Android View 事件基础

Android View 事件基础

View 基础知识

本节主要介绍:View的位置参数、MotionEvent和TouchSlop、VelocityTracker,GestureDetector和Scroller对象

什么是View

View是Android中所有控件的基类,是界面层的一种抽象,代表了一个控件。除了View还有ViewGroup,ViewGroup继承于View,内部是可以有子View的,这个子View同样还可以是ViewGroup,因此View本身可以是单个控件也可以是由多个控件组成的一组控件,通过这种关系形成了View树结构。根据这个概念,我们知道Button显然是个View,LinearLayout不但是一个View而且还是一个ViewGroup。

View的位置参数

View的位置主要由它的四个属性来决定:top、left、right,bottom,其中top是左上角纵坐标,left是左上角横坐标,right是右下角横坐标,bottom是右下角纵坐标。需要注意的是,这些坐标都是相对于View的父容器的相对坐标,在Android和大部分显示系统中都是按照x轴和y轴的正方向分别为右和下来定义坐标系的。

在这里插入图片描述

从图中可以得到宽高和坐标的关系:

width = right - left
height = bottom - top

从Android3.0开始,View增加了额外的几个参数,x,y,translationX,translationY,其中x,y是View左上角的坐标,而translationX,translationY是左上角相对父容器的偏移量,这几个参数也是相对于父容器的坐标,并且translationX,translationY的默认值是0,换算关系如下:

x = left + translationX
y = top + translationY

需要注意的是,View在平移的过程中,top和left表示在原始左上角的位置信息,其值并不会发生什么,此时发生改变的是x,y,translationX,translationY,这四个参数。

MotionEvent和TouchSlop

MotionEvent

MotionEvent的典型事件有如下几种:

  • ACTION_DOWN——手指刚接触屏幕
  • ACTION_MOVE——手指在屏幕上移动
  • ACTION_UP——手机从屏幕上松开的一瞬间

一次手指触摸屏幕行为会触发一系列点击事件:

  • DOWN->UP——点击屏幕后离开松开
  • DOWN->MOVE->…->MOVE->UP——点击屏幕滑动一会再松开

通过MotionEvent对象可以得到点击事件发生的x和y坐标:getX/getY和getRawX/getRawY,区别是getX/getY返回的是相对于当前View左上角的x和y坐标,而geiRawX/getRawY返回的是相对于手机屏幕左上角的x和y坐标

TouchSlop

TouchSlop是系统所能识别出的被认为是滑动的最小距离,它是一个常量,在不同的设备下这个值可能不同,当处理滑动时利用它来做一些过滤,两次滑动之间的距离小于这个值,就可以不认为在做滑动操作

TouchSlop获取方式:

ViewConfigurtion.get(getContext()).getScaledTouchSlop

TouchSlop在源码中的位置:

fraweworks/base/core/res/values/config.xml中的config_viewConfigurationTouchSlop

VelocityTracker、GestureDetector和Scroller

VelocityTracker

速度追踪,用于追踪手指在屏幕上滑动的速度,包括水平和竖直方向上的速度

使用方式:

首先在View的onTouchEvent方法里追踪当前点击事件的速度

VelocityTracker velocityTracker = VelocityTracker.obtain();
velocityTracker.addMovement(event);

接着,当我们先知道当前的滑动速度时,这个时候可以采用如下的方式得到当前的速度

velocityTracker.computeCurrentVelocity(1000);
int xVelocity = (int) velocityTracker.getXVelocity();
int yVelocity = (int) velocityTracker.getYVelocity();

有两点需要注意:

  1. 获取速度的之前必须先计算速度,即getXVelocity和getYVelocity这两个方法前面一定要调用computeCurrentVelocity方法。
  2. 这里的速度是指一段时间内手指滑动的屏幕像素数,比如将时间设置为1000ms时,在1s内,手指在水平方向手指滑动100像素,那么水平速度就是100,当手指从右向左滑动的时候,速度即为负

速度的计算公式如下表示:

速度 = (终点位置 - 起点位置)/ 时间段

最后,当不需要使用它的时候,需要调用clear方法来重置并回收内存:

velocityTracker.clear();
velocityTracker.recycle();

GestureDetector

手势检测,用于辅助检测用户的单击、滑动、长按、双击等行为

使用方式:

首先创建对象

GestureDetector mGestureDetector = new GestureDetector(this);
//解决长按屏幕后无法拖动的现象
mGestureDetector.setIsLongPressEnabled(false);

接着,接管目标View的onTouchEvent方法

boolean consume = mGestureDetector.onTouchEvent(event);
return consume;

然后就能有选择性的实现OnGestureListener和OnDoubleTapListener中的方法了,这两个接口中的方法介绍如下图:

方法名 描述 所属接口
onDown 手指轻触屏幕一瞬间,由1个ACTION_DOWN触发 OnGestureListener
onShowPress 手指轻触屏幕,尚未松开或拖动,由1个ACTION_DOWN触发
*注意和onDown()区别,它强调的是没有松开或者拖动的状态
OnGestureListener
onSingleTapUp 单击,伴随着1个ACTION_UP触发 OnGestureListener
onScroll 拖动,由1个ACTION_DOWN,多个ACTION_MOVE触发 OnGestureListener
onLongPass 长按 OnGestureListener
onFling 快速滑动,由1个ACTION_DOWN,多个ACTION_MOVE触发和1个ACTION_UP触发 OnGestureListener
onDoubleTap 双击,由2次连续的单击组成,不可能和onSingleTapConfirmed共存 OnDoubleTapListener
onSingleTapConfirmed 严格的单击行为
*注意和onSingleTapUp的区别,如果触发了onSingleTapConfirmed,那后面不可能再紧跟着另一个单击行为,即这是可能是单击,不可能是双击中的一次单击
OnDoubleTapListener
onDoubleTapEvent 表示发生了双击行为,在双击期间,ACTION_DOWN、ACTION_MOVE和ACTION_UP都会触发此回调 OnDoubleTapListener

Scroller

用于实现View的弹性滑动,当使用View的scrollTo/scrollBy方法来进行滑动时,会瞬间完成这个动作,没有过渡效果的滑动用户体验不好,这个时候就可以用Scroller来实现过度效果的滑动

Scroller需要和view的computScrioll方法配合才能完成弹性滑动,使用方式如下:

Scroller mScroller = new Scroller(mContext);

// 缓慢滚动到指定位置
private void smoothScrollTo(int destX,int destY){
    int scrollX = getScrollX();
    int delta = destX - scrollX;
    //1000ms内滑向destX,效果就是慢慢滑动
    mScroller.startScroll(scrollX,0,delta,0,1000);
    invalidate();
}

@Override
public void computeScroll() {
    if (mScroller.computeScrollOffset()){
        scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
        postInvalidate();
    }
}
发布了174 篇原创文章 · 获赞 119 · 访问量 55万+

猜你喜欢

转载自blog.csdn.net/lj402159806/article/details/96463587
今日推荐