[学习笔记]Android系统功能之多点触摸交互处理

以下内容纯粹为本人学习笔记【记录】之用,所听课程(Q群群友百度网盘提供)为极客学院一位老师所讲(老师大名我尚未知晓),如有侵权请告知。在此特别感谢这位老师录制的视频资料。

1、触摸事件监听
MainActivity.java

package com.keen.multouch;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        root = (FrameLayout) findViewById(R.id.activity_main);

        //触摸监听事件
        root.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                switch (motionEvent.getAction()) {
                    case MotionEvent.ACTION_DOWN://触摸按下
                        System.out.println("触摸按下");
                        break;
                    case MotionEvent.ACTION_MOVE://触摸移动
                        System.out.println("触摸移动");
                        break;
                    case MotionEvent.ACTION_UP://触摸弹起
                        System.out.println("触摸弹起");
                        break;
                }
                //                return false;//后续事件不会被触发。false代表告诉系统这个事件没有被触发,因此后续事件也不会触发了
                return true;//后续事件可触发
            }
        });
    }
    private FrameLayout root;
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.keen.multouch.MainActivity">

</FrameLayout>

这里写图片描述
2、触摸事件传递
若返回值为false,意味着告诉系统当前事件未被触发,因此后续事件不会被触发。所以上述日志里只看到唯一的打印“触摸按下”日志。改为true即可看到打印出监听“按下”、“移动”、“弹起/松开”事件,也就是【触摸事件传递】。
这里写图片描述
3、获取1个触摸点坐标
activity_main.xml添加一个张图片,用于演示

    <ImageView
        android:id="@+id/iv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/img_1"/>

修改后的MainActivity.java为

package com.keen.multouch;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        root = (FrameLayout) findViewById(R.id.activity_main);
        iv = (ImageView) findViewById(R.id.iv);

        //触摸监听事件
        root.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                switch (motionEvent.getAction()) {
                    case MotionEvent.ACTION_DOWN://触摸按下
                        System.out.println("触摸按下");
                        break;
                    case MotionEvent.ACTION_MOVE://触摸移动
                        System.out.println("触摸移动");

                        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) iv.getLayoutParams();
                        lp.leftMargin = (int) motionEvent.getX();
                        lp.topMargin = (int) motionEvent.getY();
                        iv.setLayoutParams(lp);

                        System.out.println(String.format("x:%f,y:%f", motionEvent.getX(), motionEvent.getY()));//获取当前触摸点(坐标)
                        break;
                    case MotionEvent.ACTION_UP://触摸弹起
                        System.out.println("触摸弹起");
                        break;
                }
//                return false;//后续事件不会被触发。false代表告诉系统这个事件没有被触发,因此后续事件也不会触发了
                return true;//后续事件可触发
            }
        });
    }
    private FrameLayout root;
    private ImageView iv;
}

这里写图片描述
4、获取多个触摸点坐标

 //获取多个触摸点
                        System.out.println("point count:" +motionEvent.getPointerCount());
                        //获取多个触摸点的位置(坐标),用索引
                        System.out.println(String.format("x1:%f y1:%f x2:%f y2:%f", motionEvent.getX(0),motionEvent.getY(0), motionEvent.getX(1),motionEvent.getY(1)));

这里写图片描述
5、示例:缩放图片
首先得判断缩放的手势,当两个手指放置在屏幕时,如何判断是放大还是缩小的动作?获取到两个点的坐标后,使用数学上的勾股定理,取得两个点之间的距离,判断两个点之间的距离增大,则当作放大的手势;反之,则是缩小的手势。
其次,代码实现:
1)计算两点之间距离:x轴的差的平方,再与y轴的差的平方 相加得和,求这和的平方根,即勾股定理。
这里写图片描述
这里写图片描述

                        if(motionEvent.getPointerCount() >=2) {
                            float offsetX = motionEvent.getX(0) -motionEvent.getX(1);
                            float offsetY = motionEvent.getY(0) -motionEvent.getY(1);
                            currentDistance = (float) Math.sqrt(offsetX *offsetX +offsetY*offsetY);

                            if(lastDistance<=0) {
                                lastDistance = currentDistance;
                            } else {
                                if (currentDistance -lastDistance >5) {//一般情况设置为5时,容错能力较大
                                    System.out.println("这是放大的操作");
                                    lastDistance = currentDistance;
                                } else if(lastDistance -currentDistance >5){
                                    System.out.println("这是缩小的操作");
                                    lastDistance = currentDistance;
                                }
                            }
                        }

这里写图片描述
2)对图片进行放大与缩小的操作
MainActivity.java

package com.keen.multouch;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        root = (FrameLayout) findViewById(R.id.activity_main);
        iv = (ImageView) findViewById(R.id.iv);

        //触摸监听事件
        root.setOnTouchListener(new View.OnTouchListener() {
            float currentDistance;//当前两点之间距离
            float lastDistance = -1;//记录最后一次时的距离,-1作为初始值,但值是不可能为负,在此只为了说明是初始值

            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                switch (motionEvent.getAction()) {
                    case MotionEvent.ACTION_DOWN://触摸按下
                        System.out.println("触摸按下");
                        break;
                    case MotionEvent.ACTION_MOVE://触摸移动
                        System.out.println("触摸移动");

                        if(motionEvent.getPointerCount() >=2) {
                            float offsetX = motionEvent.getX(0) -motionEvent.getX(1);
                            float offsetY = motionEvent.getY(0) -motionEvent.getY(1);
                            currentDistance = (float) Math.sqrt(offsetX *offsetX +offsetY*offsetY);

                            if(lastDistance<=0) {
                                lastDistance = currentDistance;
                            } else {
                                if (currentDistance -lastDistance >5) {//一般情况设置为5时,容错能力较大
                                    System.out.println("这是放大的操作");

                                    //对图片进行放大操作
                                    FrameLayout.LayoutParams lp = (FrameLayout.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 = (FrameLayout.LayoutParams) iv.getLayoutParams();
                                    lp.width = (int) (0.9f *iv.getWidth());
                                    lp.height = (int) (0.9f *iv.getHeight());
                                    iv.setLayoutParams(lp);

                                    lastDistance = currentDistance;
                                }
                            }
                        }

                        //获取多个触摸点
//                        System.out.println("point count:" +motionEvent.getPointerCount());
                        //获取多个触摸点的位置(坐标),用索引
//                        System.out.println(String.format("x1:%f y1:%f x2:%f y2:%f", motionEvent.getX(0),motionEvent.getY(0), motionEvent.getX(1),motionEvent.getY(1)));

//                        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) iv.getLayoutParams();
//                        lp.leftMargin = (int) motionEvent.getX();
//                        lp.topMargin = (int) motionEvent.getY();
//                        iv.setLayoutParams(lp);
//
//                        System.out.println(String.format("x:%f,y:%f", motionEvent.getX(), motionEvent.getY()));//获取当前触摸点(坐标)
                        break;
                    case MotionEvent.ACTION_UP://触摸弹起
                        System.out.println("触摸弹起");
                        break;
                }
//                return false;//后续事件不会被触发。false代表告诉系统这个事件没有被触发,因此后续事件也不会触发了
                return true;//后续事件可触发
            }
        });
    }
    private FrameLayout root;
    private ImageView iv;
}

猜你喜欢

转载自blog.csdn.net/weixin_38256474/article/details/72858207