本文共 9802 字,大约阅读时间需要 32 分钟。
Multitouch
或Multi-Touch
)是采用人机交互技术与硬件设备共同实现的技术,能在没有传统输入设备(如鼠标、键盘等)。下进行计算机的人机交互操作。多点触摸技术,能构成一个触摸屏(屏幕,桌面,墙壁等)或触控板,都能够同时接受来自屏幕上多个点进行计算机的人机交互操作。动作 | 常量 |
---|---|
按下 | MotionEvent.ACTION_DOWN |
移动 | MotionEvent.ACTION_MOVE |
放开 | MotionEvent.ACTION_UP |
onTouchListener
- 接口onTouch()
抽象 方法里,我们可以根据不同动作编写不同事件处理代码MotionEvent
对象的getX()
和getY()
方法可以获得触摸点的坐标。如果是多点触摸,通过getPointerCount()
获取触点个数,然后通过getX(pointerIndex)与getY(pointerIndex)
获得某个触点的坐标。onTouchEvent()
接收处理此事件。每个部分对触摸事件的处理过程如下: Activity的处理过程: Activity.dispatchTouchEvent()
最先被调用,其作用是调用RootView
(通常是一个ViewGroup)的dispatchTouchEvent()
,即负责分发事件。ViewGroup
中的dispatch会调用其他孩子的dispatchTouchEvent()。注意:Activity中的onTouchEvent()是整个View的触摸事件传递链条的终点,不过前提是整个过程中没有view的touchEvent对此事件感兴趣。 View的处理过程: 检查是否有TouchListener()注册在这个View中,如果有则查看其是否想要消费此次事件,如果不消费事件,那么接下来该View的onTouchEvent()就要被调用了,如果未返回true,事件就会返回视图树的上一层。通过触摸移动米老鼠
将约束布局改成线性布局,再添加一个图像控件显示米老鼠
声明变量和常量
通过资源标识符获取控件实例
让根布局获取焦点
米老鼠图像控件的布局参数
给线性根布局注册触摸监听器
完整代码
package net.ls.movemickeybytouch;import androidx.appcompat.app.AppCompatActivity;import android.annotation.SuppressLint;import android.os.Bundle;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.widget.ImageView;import android.widget.LinearLayout;public class MainActivity extends AppCompatActivity { private ImageView ivMickey; //米老鼠图像控件 private LinearLayout root; //线性根布局 private LinearLayout.LayoutParams layoutParams; //布局参数 private static final String TAG = "move_mickey_by_touch"; //标记常量 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); root=findViewById(R.id.root); ivmickey = findViewById(R.id.iv_mickey); //让根布局成为焦点 root.setFocusable(true); root.requestFocus(); //获取米老鼠图像控件的布局参数 layoutParams = (LinearLayout.LayoutParams) ivmickey.getLayoutParams(); // 给线性根布局注册触摸监听器,实现监听器接口,编写触摸事件代码 root.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN://0,触点按下 Log.d(TAG,"ACTION_DOWN("+event.getX()+","+event.getY()+")"); break; case MotionEvent.ACTION_MOVE://2,触点移动 Log.d(TAG,"ACTION_MOVE("+event.getX()+","+event.getY()+")"); break; case MotionEvent.ACTION_UP://1,触点放开 Log.d(TAG,"ACTION_UP("+event.getX()+","+event.getY()+")"); break; } // 根据变化的触点坐标来更新米老鼠图像控件的布局参数 layoutParams.leftMargin = (int) event.getX(); layoutParams.topMargin = (int) event.getY(); // 重新设置米老鼠图像控件的布局参数 ivMickey.setLayoutParams(layoutParams); return true; // 设置为true,三个事件:down-->move-->up才会依次执行 } }); }}
package net.ls.movemickeybytouch;import androidx.appcompat.app.AppCompatActivity;import android.annotation.SuppressLint;import android.os.Bundle;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.widget.ImageView;import android.widget.LinearLayout;public class MainActivity extends AppCompatActivity { private ImageView ivmickey; //米老鼠图像控件 private LinearLayout root; //线性根布局 private LinearLayout.LayoutParams layoutParams; //布局参数 private static final String TAG = "move_mickey_by_touch"; //标记常量 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); root=findViewById(R.id.root); ivmickey = findViewById(R.id.iv_mickey); //让根布局成为焦点 root.setFocusable(true); root.requestFocus(); //获取米老鼠图像控件的布局参数 layoutParams = (LinearLayout.LayoutParams) ivmickey.getLayoutParams(); // 给线性根布局注册触摸监听器,实现监听器接口,编写触摸事件代码 root.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN://0,触点按下 Log.d(TAG,"ACTION_DOWN("+event.getX()+","+event.getY()+")"); break; case MotionEvent.ACTION_MOVE://2,触点移动 Log.d(TAG,"ACTION_MOVE("+event.getX()+","+event.getY()+")"); break; case MotionEvent.ACTION_UP://1,触点放开 Log.d(TAG,"ACTION_UP("+event.getX()+","+event.getY()+")"); break; } //设置米老鼠图像控件坐标 ivmickey.setX(event.getX()-ivmickey.getWidth()/2); ivmickey.setY(event.getY()-ivmickey.getHeight()/2); return true; } }); }}
将约束布局改成线性布局,再添加一个图像控件显示米老鼠
声明变量
通过资源标识符获取控件实例,让根布局获取焦点,让根布局获取焦点
给根布局注册触摸监听器
完整代码
package net.ls.zoommickeybytouch;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;import android.view.MotionEvent;import android.view.View;import android.widget.ImageView;import android.widget.LinearLayout;public class MainActivity extends AppCompatActivity { private LinearLayout root; private ImageView ivMickey; private float x1,y1;//第一个触点的坐标 private float x2,y2;//第二个触点的坐标 private float nextX1,nextY1;//第一个触点的下一次坐标 private float nextX2,nextY2;//第二个触点的下一次坐标 private float distance; //两个触点间的距离 private float nextDistance;//两个触点的下一次距离 private LinearLayout.LayoutParams layoutParams; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); root = findViewById(R.id.root); ivMickey = findViewById(R.id.iv_mickey); root.setFocusable(true); root.requestFocus(); layoutParams = (LinearLayout.LayoutParams) ivMickey.getLayoutParams(); //给根布局注册触摸监听器,实现触摸监听器接口,编写触摸事件方法 root.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { //判断触点个数 if (event.getPointerCount()==1){ //单点触摸 - 移动米老鼠 layoutParams.leftMargin = (int)(event.getX() - ivMickey.getWidth()/2); layoutParams.topMargin = (int)(event.getY() - ivMickey.getHeight()/2); }else if (event.getPointerCount()==2){ //两点触摸 - 缩放米老鼠 //判断触点动作 switch (event.getAction()){ case MotionEvent.ACTION_DOWN: //获取第一个触点的坐标 x1 = event.getX(0); y1 = event.getY(0); //获取第二个触点的坐标 x2 = event.getX(1); x2 = event.getY(1); distance =(float) Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); break; case MotionEvent.ACTION_MOVE: //获取第一个触点下一次的坐标 nextX1 = event.getX(0); nextY1 = event.getY(0); //获取第二个触点下一次的坐标 nextX2 = event.getX(1); nextY2 = event.getY(1); //计算两个触点的下一次距离 nextDistance = (float) Math.sqrt((nextX1-nextX2)*(nextX1-nextX2)+(nextY1-nextY2)*(nextY1-nextY2)); break; case MotionEvent.ACTION_UP: break; } //修改米老鼠图像控件的布局参数 if (nextDistance>distance){ if (layoutParams.width<1000){ layoutParams.width = (int) (layoutParams.width*1.05); layoutParams.height = (int) (layoutParams.height*1.05);} } else { if (layoutParams.width>10) { layoutParams.width = (int) (layoutParams.width / 1.05); layoutParams.height = (int) (layoutParams.height / 1.05); } } //第一个触点坐标进行迭代 x1 = nextX1; y1 = nextY1; x2 = nextX2; y2 = nextY2; distance=(float) Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); } ivMickey.setLayoutParams(layoutParams); return true; } }); }}
转载地址:http://ybpowy.baihongyu.com/