android开发之多点触摸交互处理

来源:互联网 发布:如何保持精力充沛 知乎 编辑:程序博客网 时间:2024/06/04 18:55

接下来,我将用代码一步一步来解剖多点触控,嘎嘎!!

触摸事件的侦听

布局文件:<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/container"    android:layout_width="match_parent"    android:layout_height="match_parent"/>
MainActivity:package com.zanelove.touch;import android.app.Activity;import android.os.Bundle;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.widget.FrameLayout;public class MainActivity extends Activity {    private static final String TAG = "MainActivity";    private FrameLayout root;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        root = (FrameLayout) findViewById(R.id.container);        //设置触摸事件        root.setOnTouchListener(new View.OnTouchListener() {            @Override            public boolean onTouch(View v, MotionEvent event) {                switch (event.getAction()) {                    case MotionEvent.ACTION_DOWN:                        Log.e(TAG,"ACTION_DOWN");                        break;                    case MotionEvent.ACTION_MOVE:                        Log.e(TAG,"ACTION_MOVE");                        break;                    case MotionEvent.ACTION_UP:                        Log.e(TAG,"ACTION_UP");                        break;                }                /**                 * 事件是分阶段性的:                 *  第一阶段:Action_DOWN                 *  第二阶段:Action_MOVE                 *  第三阶段:Action_UP                 *  既然分阶段性,那么如果当Action_DOWN事件没有触发成功,也就是返回false的情况下,那么Action_MOVE以及Action_UP就都接收不到事件了。                 *  因此要想MOVE和UP都想触发成功,必须返回true                 */                return true;            }        });    }}

获取一个触摸点坐标

布局文件:<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/container"    android:layout_width="match_parent"    android:layout_height="match_parent">    <ImageView            android:id="@+id/iv"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:src="@drawable/ic_launcher"            /></FrameLayout>
MainActivity:package com.zanelove.touch;import android.app.Activity;import android.os.Bundle;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.widget.FrameLayout;import android.widget.ImageView;public class MainActivity extends Activity {    private static final String TAG = "MainActivity";    private FrameLayout root;    private ImageView iv;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        root = (FrameLayout) findViewById(R.id.container);        iv = (ImageView) findViewById(R.id.iv);        //设置触摸事件        root.setOnTouchListener(new View.OnTouchListener() {            @Override            public boolean onTouch(View v, MotionEvent event) {                switch (event.getAction()) {                    case MotionEvent.ACTION_DOWN:                        Log.e(TAG,"ACTION_DOWN");                        break;                    case MotionEvent.ACTION_MOVE:                        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) iv.getLayoutParams();                        lp.leftMargin = (int) event.getX();                        lp.topMargin = (int) event.getY();                        iv.setLayoutParams(lp);                        Log.e(TAG,"x:"+event.getX()+"y:"+event.getY());                        break;                    case MotionEvent.ACTION_UP:                        Log.e(TAG,"ACTION_UP");                        break;                }                /**                 * 事件是分阶段性的:                 *  第一阶段:Action_DOWN                 *  第二阶段:Action_MOVE                 *  第三阶段:Action_UP                 *  既然分阶段性,那么如果当Action_DOWN事件没有触发成功,也就是返回false的情况下,那么Action_MOVE以及Action_UP就都接收不到事件了。                 *  因此要想MOVE和UP都想触发成功,必须返回true                 */                return true;            }        });    }}

获取多个触摸点坐标

package com.zanelove.touch;import android.app.Activity;import android.os.Bundle;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.widget.FrameLayout;import android.widget.ImageView;public class MainActivity extends Activity {    private static final String TAG = "MainActivity";    private FrameLayout root;    private ImageView iv;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        root = (FrameLayout) findViewById(R.id.container);        iv = (ImageView) findViewById(R.id.iv);        //设置触摸事件        root.setOnTouchListener(new View.OnTouchListener() {            @Override            public boolean onTouch(View v, MotionEvent event) {                switch (event.getAction()) {                    case MotionEvent.ACTION_DOWN:                        Log.e(TAG,"ACTION_DOWN");                        break;                    case MotionEvent.ACTION_MOVE:                        //获取多个触摸点//                        Log.e(TAG,"pointer count: "+event.getPointerCount());                        //获取多个触摸点坐标                        Log.e(TAG,"x1: "+event.getX(0)+", y1: "+event.getY(0)+", x2: "+event.getX(1)+", y2: "+event.getY(1));                        /*FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) iv.getLayoutParams();                        lp.leftMargin = (int) event.getX();                        lp.topMargin = (int) event.getY();                        iv.setLayoutParams(lp);                        Log.e(TAG,"x:"+event.getX()+"y:"+event.getY());*/                        break;                    case MotionEvent.ACTION_UP:                        Log.e(TAG,"ACTION_UP");                        break;                }                /**                 * 事件是分阶段性的:                 *  第一阶段:Action_DOWN                 *  第二阶段:Action_MOVE                 *  第三阶段:Action_UP                 *  既然分阶段性,那么如果当Action_DOWN事件没有触发成功,也就是返回false的情况下,那么Action_MOVE以及Action_UP就都接收不到事件了。                 *  因此要想MOVE和UP都想触发成功,必须返回true                 */                return true;            }        });    }}

缩放图片示例

原理:

如何判断我的手势操作是放大或是缩小的操作呢?
答:获取两个点的坐标,使用数学上的勾股定理算出两个点之间的距离,判断这两个点的距离是增大的状态我们就当做是放大的手势,相反,就将其当做缩小的手势.

如何具体计算两个点之间的距离?
答:两点的x轴的差平方与y轴差的平方相加再将其和求平方根(三角函数的勾股定理)
float offsetX = event.getX(0)-event.getX(1);
float offsetY = event.getY(0)-event.getY(1);
float currentDistance = (float) Math.sqrt(offsetX*offsetX+offsetY*offsetY);

import android.app.Activity;import android.os.Bundle;import android.view.MotionEvent;import android.view.View;import android.widget.FrameLayout;import android.widget.FrameLayout.LayoutParams;import android.widget.ImageView;public class MainActivity extends Activity {    private ImageView iv;    private FrameLayout root;    private float currentDistance;    private float lastDistance = -1;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        root = (FrameLayout) findViewById(R.id.container);        iv = (ImageView) findViewById(R.id.iv);        root.setOnTouchListener(new View.OnTouchListener() {            @Override            public boolean onTouch(View v, MotionEvent event) {                switch (event.getAction()) {                case MotionEvent.ACTION_DOWN:                    break;                case MotionEvent.ACTION_MOVE:                    if (event.getPointerCount()>=2) {                        float offsetX = event.getX(0)-event.getX(1);                        float offsetY = event.getY(0)-event.getY(1);                        currentDistance = (float) Math.sqrt(offsetX*offsetX+offsetY*offsetY);                        if (lastDistance<0) {                            lastDistance = currentDistance;                        }else{                            if (currentDistance-lastDistance>5) {                                System.out.println("放大");                                FrameLayout.LayoutParams lp = (LayoutParams) iv.getLayoutParams();                                lp.width= (int) (1.1f*iv.getWidth());                                lp.height = (int) (1.1f * iv.getHeight());                                iv.setLayoutParams(lp);                                lastDistance = currentDistance;                            }else if (lastDistance-currentDistance>5) {                                System.out.println("缩小");                                FrameLayout.LayoutParams lp = (LayoutParams) iv.getLayoutParams();                                lp.width=(int) (0.9f*iv.getWidth());                                lp.height=(int) (0.9f*iv.getHeight());                                iv.setLayoutParams(lp);                                lastDistance = currentDistance;                            }                        }                    }else if(event.getPointerCount() == 1){                        FrameLayout.LayoutParams lp = (LayoutParams) iv.getLayoutParams();                        lp.leftMargin = (int) event.getX();                        lp.topMargin = (int) event.getY();                        iv.setLayoutParams(lp);                    }                    break;                case MotionEvent.ACTION_UP:                    break;                }                return true;            }        });    }}

示例代码戳Here

0 0
原创粉丝点击