电容屏战胜电阻屏的一大胜点就是多点触控。随便智能手机的发展,多点触控在各种模块和控件中运用很多。如地图app,或是大图浏览时,两个指头可以控制图片的大小。这方面,相关的第三方控件很多,今天简略记录一下它们的实现原理。
单点触控的方法,相信都已经很熟悉了。
view.setOnTouchListener(touchListener); View.OnTouchListener touchListener = new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction() & MotionEvent.ACTION_MASK){ case MotionEvent.ACTION_DOWN: break; case MotionEvent.ACTION_UP: break; case MotionEvent.ACTION_MOVE: break; case MotionEvent.ACTION_POINTER_DOWN:break; case MotionEvent.ACTION_POINTER_UP:break; } return true; } };
多点触控的方法,与单点触控很类似,有所不同的是
event.getAction() & MotionEvent.ACTION_MASK
我们需要这样,才能获得屏幕上的第二点的触摸事件:
case MotionEvent.ACTION_POINTER_DOWN: break; case MotionEvent.ACTION_POINTER_UP: break;
他们分别表示了第二根手指的按下和离开屏幕。这样我们就可以这个来确定进入和退出多点触控模式。
在多点触控模式下,我们获取坐标点依旧是在MotionEvent.ACTION_MOVE中:
float width = calculateWidth(v ,event.getX() , event.getY() , event.getX(1) , event.getY(1));
我们通过getX(1)和getY(1)来获取第二点的坐标。
这样,我们就能够获取4个点的坐标。附上一个两个手指拉直线的demo。直线宽度会随手指间距离变化。
public class MainActivity extends AppCompatActivity { TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = (TextView) findViewById(R.id.text_view_id); initView(textView); } private void initView(View view){ view.setOnTouchListener(touchListener); } Canvas canvas ; Paint paint; Bitmap bitmap; Drawable drawable; private void drawLine(View view , float x1 , float y1 , float x2 , float y2){ if (canvas != null && paint != null && view != null && bitmap != null){ canvas.drawColor(Color.parseColor("#ffffff")); canvas.drawLine(x1, y1, x2, y2, paint); view.invalidate(); }else { bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888); canvas = new Canvas(bitmap); paint = new Paint(); paint.setStrokeWidth(10); paint.setColor(Color.parseColor("#44ff0000")); drawable = new BitmapDrawable(getResources() , bitmap); view.setBackgroundDrawable(drawable); } } boolean isMulMove = false; View.OnTouchListener touchListener = new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction() & MotionEvent.ACTION_MASK){ case MotionEvent.ACTION_DOWN: break; case MotionEvent.ACTION_UP: break; case MotionEvent.ACTION_MOVE: if (isMulMove){ float width = calculateWidth(v ,event.getX() , event.getY() , event.getX(1) , event.getY(1)); if (paint != null){ paint.setStrokeWidth(width); } drawLine(v ,event.getX() , event.getY() , event.getX(1) , event.getY(1)); } break; case MotionEvent.ACTION_POINTER_DOWN: isMulMove = true; break; case MotionEvent.ACTION_POINTER_UP: isMulMove = false; break; } return true; } }; private float calculateWidth(View view , float x1 , float y1 , float x2 , float y2){ float result ; float distance = (float) Math.sqrt( (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2) ); float maxDistance = (float) Math.sqrt( view.getWidth()*view.getWidth() + view.getHeight()*view.getHeight() ); result = 100-distance * 90.0f/maxDistance; return result; } }
Done~