Android 快速学习onTouch,并完成实验单点滑动,双点触控,多点触控。

(一)单点触控,拖动目标滑动

话不多说先来看看onTouchEvent方法。

/** * 屏幕触控事件 * @param event * @return */@Overridepublic boolean onTouchEvent(MotionEvent event) {    return super.onTouchEvent(event);    }

参数传入一个MotionEvent类

我们看看MotionEvent类几个比较重要的属性和方法。

常量:

  • MotionEvent.ACTION_DOWN:当屏幕检测到第一个触点按下之后就会触发到这个事件。
  • MotionEvent.ACTION_MOVE:当触点在屏幕上移动时触发,触点在屏幕上停留也是会触发的,主要是由于它的灵敏度很高,而我们的手指又不可能完全静止(即使我们感觉不到移动,但其实我们的手指也在不停地抖动)。
  • MotionEvent.ACTION_UP:当触点松开时被触发。
  • MotionEvent.ACTION_POINTER_DOWN:当屏幕上已经有触点处于按下的状态的时候,再有新的触点被按下时触发。
  • MotionEvent.ACTION_POINTER_UP:当屏幕上有多个点被按住,松开其中一个点时触发(即非最后一个点被放开时)触发。
  • MotionEvent.ACTION_OUTSIDE: 表示用户触碰超出了正常的UI边界.

方法:

  • getAction():返回动作类型,如上常量。
  • getX()/getY():获得事件发生时,触摸的中间区域的X/Y坐标,由这两个函数获得的X/Y值是相对坐标,相对于消费这个事件的视图的左上角的坐标。 
  • getDownTime() :按下开始时间 
  • getEventTime() : 事件结束时间 
  • getPointerCount():获取触控点的数量,比如2则可能是两个手指同时按压屏幕 
  • getX(nID):获取第nID个触控点的x位置 
  • getY(nID):获取第nID个触控点的y位置 

实验1:单击控件,控件跟随手指移动。

先上效果图:

Android 快速学习onTouch,并完成实验单点滑动,双点触控,多点触控。(一)单点触控,拖动目标滑动_第1张图片

布局代码:

shape_tv_cir.xml

<?xml version="1.0" encoding="utf-8"?>xmlns:android="http://schemas.android.com/apk/res/android">    android:radius="360dp"/>    android:color="#ff0000"/>

其他几个shape一样只改个色码值。

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>xmlns:android="http://schemas.android.com/apk/res/android"                android:layout_width="match_parent"                android:layout_height="match_parent">            android:id="@+id/tv_cir1"        android:layout_width="10dp"        android:layout_height="10dp"        android:layout_centerVertical="true"        android:layout_marginLeft="100dp"        android:background="@drawable/shape_tv_cir"/>            android:id="@+id/tv_cir2"        android:layout_width="10dp"        android:layout_height="10dp"        android:layout_alignParentTop="true"        android:layout_centerHorizontal="true"        android:layout_marginTop="100dp"        android:background="@drawable/shape_tv_cir2"/>                android:id="@+id/tv_cir3"        android:layout_width="10dp"        android:layout_height="10dp"        android:layout_alignParentRight="true"        android:layout_centerVertical="true"        android:layout_marginRight="100dp"        android:background="@drawable/shape_tv_cir3"/>

界面代码:

看注释即可↓

public class SingleTouchActivity extends AppCompatActivity {    /**     * UI     */    private TextView tvCir1, tvCir2, tvCir3;    /**     * Data & other     */    private static final String TAG = "onTouch";    //点击位置的范围,越大范围越容易触控到。    private static final int TOUCHRANGE = 30;    //用于记录各个点的位置    private float Cir1X = 0;    private float Cir1Y = 0;    private float Cir2X = 0;    private float Cir2Y = 0;    private float Cir3X = 0;    private float Cir3Y = 0;    //各个点的状态-是否被触控到 true按下 false反之    private boolean Cir1State = false;    private boolean Cir2State = false;    private boolean Cir3State = false;    //状态栏高度    private int statusBarHeight = 0;    //标题栏高度    private int contentViewTop = 0;    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_singletouch);        initView();    }    private void initView() {        tvCir1 = (TextView) findViewById(R.id.single_tv_cir1);        tvCir2 = (TextView) findViewById(R.id.single_tv_cir2);        tvCir3 = (TextView) findViewById(R.id.single_tv_cir3);    }    @Override    public void onWindowFocusChanged(boolean hasFocus) {        super.onWindowFocusChanged(hasFocus);        if (hasFocus) {            //状态栏高度            Rect frame = new Rect();            getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);            statusBarHeight = frame.top;            //标题栏高度            Window window = getWindow();            contentViewTop = window.findViewById(Window.ID_ANDROID_CONTENT).getTop();            //这里注意不能放在onCreate方法里面....那会儿控件还没加载完成呢            //通过获取Top Left 来获取View的位置            Cir1X = tvCir1.getLeft();            //onTouch事件里的x,y是相对于整个屏幕而言的  activity里的控件的位置是其父布局为参照物            //所以需要加一个状态栏+标题栏的高度            Cir1Y = tvCir1.getTop() + contentViewTop + statusBarHeight;            Cir2X = tvCir2.getLeft();            Cir2Y = tvCir2.getTop() + contentViewTop + statusBarHeight;            Cir3X = tvCir3.getLeft();            Cir3Y = tvCir3.getTop() + contentViewTop + statusBarHeight;        }    }    /**     * 屏幕触控事件     *     * @param event     * @return     */    @Override    public boolean onTouchEvent(MotionEvent event) {        switch (event.getAction()) {            //判断手指按下的位置 是否在目标周围  是的话在滑动时控件跟随滑动 反之...            case MotionEvent.ACTION_DOWN:                Log.i(TAG, "手指按下了 X:" + event.getX() + " Y:" + event.getY());                if (onTouchRange(Cir1X, Cir1Y, event)) {                    Cir1State = true;                } else if (onTouchRange(Cir2X, Cir2Y, event)) {                    Cir2State = true;                } else if (onTouchRange(Cir3X, Cir3Y, event)) {                    Cir3State = true;                }                break;            case MotionEvent.ACTION_MOVE:                Log.i(TAG, "手指在滑动 X:" + event.getX() + " Y:" + event.getY());                if (Cir1State) {                    tvCir1.setX(event.getX());                    //onTouch事件里的x,y是相对于整个屏幕而言的  activity里的控件的位置是其父布局为参照物                    //所以移动时的y轴要扣除一个状态栏+标题栏的高度                    tvCir1.setY(event.getY() - statusBarHeight - contentViewTop);                } else if (Cir2State) {                    tvCir2.setX(event.getX());                    tvCir2.setY(event.getY() - statusBarHeight - contentViewTop);                } else if (Cir3State) {                    tvCir3.setX(event.getX());                    tvCir3.setY(event.getY() - statusBarHeight - contentViewTop);                }                break;            case MotionEvent.ACTION_UP:                if (Cir1State) {                    Cir1X = event.getX();                    Cir1Y = event.getY();                } else if (Cir2State) {                    Cir2X = event.getX();                    Cir2Y = event.getY();                } else if (Cir3State) {                    Cir3X = event.getX();                    Cir3Y = event.getY();                }                Cir1State = false;                Cir2State = false;                Cir3State = false;                break;            default:                break;        }        return true;    }    /**     * @param x     目标x     * @param y     目标y     * @param event     * @return true 在范围内 反之...     */    private boolean onTouchRange(float x, float y, MotionEvent event) {        //判断x轴范围        if ((event.getX() - TOUCHRANGE) < x && (event.getX() + TOUCHRANGE) > x) {            //判断y轴范围            if ((event.getY() - TOUCHRANGE) < y && (event.getY() + TOUCHRANGE) > y) {                return true;            }        }        return false;    }}

思路点拨:先判断是否按下,并且位置在目标上或者目标范围使其按住滑动有效(因为有的东西可能非常小,用户很难点击到,我们给这个加大范围,便于用户操作)。按住时目标跟随手指滑动移动(获取xy位置,赋值给目标就好)--目标可能是控件。松开清除状态,并更新位置。


好了今天先到这里---2018/05/07 23:34

更多相关文章

  1. Android 位置服务——BaiduLocation的使用
  2. 自定义RadioButton样式并去除默认样式位置【Android】
  3. android取得所在位置的经纬度
  4. 自制Android下的播放器(音频来源SD卡上的固定位置)
  5. Android通过基站获取地理位置
  6. Android 铃声设置界面,起始位置为当前已选项
  7. MTK平台修改音量默认值需要改动的位置
  8. 如何在Android 11 中正确请求位置权限?以及Android 8 - 11位置权

随机推荐

  1. Android(安卓)判断软键盘的状态(显示,隐藏)
  2. ListView 实现像Android(安卓)Market那样
  3. Android(安卓)各种Span示例
  4. Android(安卓)Monkey
  5. Android:开发环境搭建
  6. Android调用系统 Set As Intent
  7. Unity同步加载Android里的StreamingAsset
  8. Android(安卓)Activity 生命周期 跟踪完
  9. android6.0 netd设置dns
  10. Android(安卓)开发常用代码片段