查找了很多关于android触屏的长按方法。都没有得到满意的结果。只好自己想办法。根据已经知道的条件,自己写逻辑。希望看官和老手点评!平台 android studio2.2 系统android4.0。上码前先看设计图。屏幕分成4个按钮块。分别是A B C D。长和宽用屏幕的1/3估计能适应所有屏幕。并记录坐标点。及逻辑判断。 字有点难看见谅!上码
package com.longbow_a.testall; import android.app.Activity; import android.content.pm.ActivityInfo; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.Window; import android.view.WindowManager;
public class TastAll extends Activity {
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //设置全屏,横向 this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); requestWindowFeature(Window.FEATURE_NO_TITLE); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); // setContentView(R.layout.activity_main); //显示自定义的SurfaceView视图 setContentView(new Test_1(this)); }//方法结尾。}//类结尾。
下面是一个view类。上面图片的逻辑就在这里实现。重点在于触碰方法中的 event.getActionIndex(),这个方法得到的返回值是当前动作的点 的event.getX(index)和event.getY(index)的index值。这个index值没有规律!本程序还可以测得手机支持多少个触点。显示了前四个触点的XY坐标值。各位运行本程序也可以研究index值保存的问题。但event.getActionIndex()不能返回移动的点的index值!只能写一个方法zuobfx(event, true) 解决长按(移动的点还在按钮块内)这个问题。 package com.longbow_a.testall;
import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.support.v4.view.MotionEventCompat; import android.view.MotionEvent; import android.view.View;
/** * Created by longbow_a on 2017/1/13. * */ public class Test_1 extends View {
Paint p1 = new Paint();//画笔一号 Paint p2 = new Paint();//画笔二号 Paint p3 = new Paint();//画笔3号 Paint p4 = new Paint();//画笔4号 Paint p5 = new Paint();//画笔5号 int pmW,pmH;//保存屏幕大小,w是x轴长度,h是y轴长度 int an_w,an_h;//按钮块的高和宽。 int bdx,cdy;//按钮块的坐标。 boolean a_long,b_long,c_long,d_long;//判断各个按钮块的按下值。false没有按下,true按下。 String zonggs ="",yi="",er="",san="",si="";//显示坐标的总个数 和 坐标值,这里只能显示是个触点。 /** * 构造方法 * @param context 上下文 *问题?能在这个方法中获得canvas吗? */ public Test_1(Context context) { super(context); //设置为焦点 setFocusable(true); //激活屏幕监听 setFocusableInTouchMode(true); //设置背景常亮 this.setKeepScreenOn(true);//这个设置没有反应? //?奇怪在这个方法中得不到高宽值!!? //只能在触碰后取得! pmW = this.getWidth();//取得屏幕高和宽。 pmH = this.getHeight(); paint_S();//设置画笔 zuob();//计数坐标值。?屏幕高宽没有!在触碰方法中再算。 }//构造方法结尾。 /** * 按钮块的坐标计数 */ public void zuob() { an_w = pmW / 3;//设置按钮块的高和宽 an_h = pmH / 3; bdx = an_w * 2; cdy =an_h * 2; } /** * 画笔设置方法 */ public void paint_S() { p1.setTextSize(30); p1.setColor(Color.GREEN);//绿色 p2.setTextSize(30); p2.setColor(Color.BLUE);//蓝色 p3.setTextSize(30); p3.setColor(Color.BLACK);//黑色 p4.setTextSize(30); p4.setColor(Color.YELLOW);//黄色 p5.setTextSize(30); p5.setColor(Color.RED);//红色 }//方法结尾 @Override public boolean onTouchEvent(MotionEvent event) { //重新得到屏幕高宽值。 if(pmH == 0) { pmW = this.getWidth(); pmH = this.getHeight(); zuob();//计数坐标。 } switch (MotionEventCompat.getActionMasked(event) ) { case MotionEvent.ACTION_DOWN://按下 cpkz((int) event.getX(event.getActionIndex()), (int) event.getY(event.getActionIndex()), true); break; case MotionEvent.ACTION_POINTER_DOWN://新的点按下 cpkz((int) event.getX(event.getActionIndex()), (int) event.getY(event.getActionIndex()), true); break; case MotionEvent.ACTION_POINTER_UP://抬起了一个点,还有触点。 cpkz((int) event.getX(event.getActionIndex()), (int) event.getY(event.getActionIndex()), false); break; case MotionEvent.ACTION_UP://抬起全部触点。 cpkz((int) event.getX(event.getActionIndex()), (int) event.getY(event.getActionIndex()), false); break; case MotionEvent.ACTION_MOVE://移动 zuobfx(event, true);//获取不了触动事件的index值只能用分析所有坐标!。 break; }//switch结尾 //下面记录触点坐标并在drow方法显示在屏幕。研究index的变化。 zonggs = "触点总数:"+event.getPointerCount(); for(int i =0 ;i<event.getPointerCount();i++) { switch (i) { case 0: yi ="index0:X=="+(int)event.getX(0)+";Y=="+(int)event.getY(0); break; case 1: er ="index1:X=="+(int)event.getX(1)+";Y=="+(int)event.getY(1); break; case 2: san ="index2:X=="+(int)event.getX(2)+";Y=="+(int)event.getY(2); break; case 3: si ="index3:X=="+(int)event.getX(3)+";Y=="+(int)event.getY(3); break; } }//循环结尾 invalidate();//刷屏,重新设置画布。 return true; }//监听结尾 @Override public void draw(Canvas canvas) { //四个按钮块 //左上角,A块按钮 if (a_long){canvas.drawRect(0,0,an_w,an_h,p2);}else{canvas.drawRect(0,0,an_w,an_h,p1);} //右上角 B块按钮 if (b_long){canvas.drawRect(bdx,0,pmW,an_h,p2);}else{ canvas.drawRect(bdx,0,pmW,an_h,p1);} //左下角 C块按钮 if (c_long){canvas.drawRect(0,cdy,an_w,pmH,p2);}else{canvas.drawRect(0,cdy,an_w,pmH,p1);} //右下角 D 块按钮 if (d_long){canvas.drawRect(bdx,cdy,pmW,pmH,p2);}else{canvas.drawRect(bdx,cdy,pmW,pmH,p1);} //显示触点坐标 canvas.drawText(zonggs,an_w+10,30,p3); canvas.drawText(yi,an_w+10,60,p5); canvas.drawText(er,an_w+10,90,p3); canvas.drawText(san,an_w+10,120,p5); canvas.drawText(si,an_w+10,150,p3); canvas.drawText("屏幕高宽:W = "+pmW+";H = "+pmH,200,180,p3); }//画图方法结尾 /** *按钮块坐标判断 * @param on_x x * @param on_y y * @param onLong 长按判断 */public void cpkz(int on_x, int on_y,boolean onLong ) { if(on_x < an_w)// A 和C按钮块 { if(on_y < an_h )// A块 { a_long = onLong; } else if(on_y > cdy)//C块 { c_long= onLong; } } else if(on_x > bdx)//B和D 按钮块 { if(on_y < an_h)//B块 { b_long= onLong; } else if(on_y > cdy)//D块 { d_long= onLong; } }//判断结尾
}//方法结尾
/** *专门为移动事件写的 判断移动坐标和按钮块关系的方法。 * * @param event 事件 * @param onxia 长按值 一定是true */ public void zuobfx(MotionEvent event,boolean onxia) { //假定按钮块没有被按下 a_long =false; b_long =false; c_long=false; d_long=false; //判断所有触点的坐标。 for ( int i =0 ; i < event.getPointerCount();i++) { //调用判断坐标方法,改变 每块 按钮的状态。 cpkz((int)event.getX(i),(int)event.getY(i),onxia);//调用每个按钮块的判断方法。 } }//方法结尾}//类结尾
运行程序后要点一下屏幕才能出现按钮图形块和屏幕高宽。本人是刚接触android的菜鸟,请问高手大神们问题出在那里?Canvas canvas能不能程序一运行就得到?不用在public void draw(Canvas canvas)方法运行后得到?谢谢阅读!
