Android进阶知识(八):View基础知识

Android进阶知识(八):View基础知识

  View是Android中所有控件的基类,是一种界面层的控件的一种抽象,它代表了一个控件。除了View,还有ViewGroup,其内部可以包含多个控件,即一组View。在Android的设计中,ViewGroup也继承了View,这就意味着View本身就可以是单个控件也可以是由多个控件组成的一组控件,通过这种关系形成了View树的结构

一、View的位置参数

  View的位置参数主要由它的四个顶点来决定,分别对应View的四个属性:top、left、right、bottom,其中top是左上角的纵坐标,left是左上角的横坐标,right是右下角的横坐标,bottom是右下角的纵坐标。需要注意的是,这些坐标都是相对View的父容器来说的,因此它是一种相对坐标。另外在Android中,x轴和y轴的正方向分别是右和下
在这里插入图片描述
  根据View的位置参数可以得到View的宽高和坐标的关系如下:

width = right - left;
height = bottom - top;

  在View的源码中View的四个位置参数对应了mLeft、mRight、mTop和mBottom这四个成员变量,View中提供了对应的getXX()方法来获取对应的位置参数。
  在Android3.0开始,View增加了额外的几个参数:x、y、translationX和translationY,其中x和y是View左上角的坐标,而translationX和translationY是View左上角相对于父容器的偏移量。这几个参数也是相对于父容器的坐标,并且translationX和translationY的默认值为0,View同样提供了get/set方法。
  几个参数之间的关系如下:

x = left + translationX;
y = top + translationY;

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

二、MotionEvent和TouchSlop

  1. MotionEvent

  在手指接触屏幕后所产生的一系列事件中,典型的事件有如下几种:

  • ACTION_DOWN——手指刚接触屏幕;
  • ACTION_MOVE——手指在屏幕上滑动;
  • ACTION_UP——手指从屏幕上松开的瞬间。

  正常情况下,一次手指触摸屏幕的行为会触发一系列点击事件,例如点击屏幕滑动一会再松开,事件序列为DWON->MOVE->…->MOVE->UP。
  上述的三种情况是典型的事件序列,同时通过MotionEvent对象可以得到点击事件发生的x和y坐标。系统提供了两组方法:getX/getY和getRawX/getRawY。getX/getY返回的是相对于当前View左上角的x和y坐标,而getRawX/getRawY返回的是相对于手机屏幕左上角的x和y坐标
在这里插入图片描述

  1. TouchSlop

  TouchSlop是系统所能识别出的被认为是滑动的最小距离,换句话说,当手指在屏幕上滑动时,当两次滑动之间的距离小于该值,则认为不是在进行滑动。这是一个常量,和设备有关,在不同设备上这个值可能是不同的,通过以下方式获取得到这个常量:ViewConfiguration.get(context).getScaledTouchSlop()。
  通常可以利用该值对用户的滑动进行过滤。

三、VelocityTracker、GestureDetector和Scroller

  1. VelocityTracker

  VelocityTracker用于追踪手指在滑动过程中的速度,包括水平和竖直方向的速度。使用的一个例子如下所示,在View的onTouchEvent方法中使用速度追踪。

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (velocityTracker == null) {
        velocityTracker = VelocityTracker.obtain();
    }
    velocityTracker.addMovement(event);
    switch(event.getAction()) {
        case MotionEvent.ACTION_DOWN:
        case MotionEvent.ACTION_MOVE:
            break;
        case MotionEvent.ACTION_UP:
            // 速度追踪
            velocityTracker.computeCurrentVelocity(1000);
            int xVelocity = (int) velocityTracker.getXVelocity();
            int yVelocity = (int) velocityTracker.getYVelocity();
            Toast.makeText(mContext, "移动速度X方向:" + xVelocity + 
            "\nY方向:" + yVelocity, Toast.LENGTH_SHORT).show();
            break;            
    }
    return true;
}

  需要注意的两点:第一,获取速度之前必须先计算速度,即getXVelocity和getYVelocity这两个方法的前面必须调用computeCurrentVelocity方法;第二,这里的速度是指一段时间内手指所滑过的像素数。注意,速度可以为负数,当手指从右向左滑动时,水平方向速度即为负值
在这里插入图片描述
  这里的终点位置是根据addMovement中添加进入的event来进行判断的,每个event都有一个对应的坐标,当调用computeCurrentVelocity方法进行计算速度时将在添加进去的event中获取最后一个evnet的坐标作为终点位置
  另外,当不需要使用速度跟踪器时,需要调用clear方法来重置并回收内存。

// 回收
velocityTracker.clear();
velocityTracker.recycle();
  1. GestureDetector

  手势检测,用于辅助检测用户的单击、滑动、长按、双击等行为。手势检测的使用并不复杂,首先创建一个GestureDetetor对象并实现OnGestureListener接口,根据需要可以实现OnDoubleTapListener接口从而监听双击行为。

// 创建并传入OnGestureListener接口的实现
GestureDetector gestureDetector = new GestureDetector(context, this);
// 解决长按屏幕后无法拖动的现象
gestureDetector.setIsLongpressEnabled(false);
// 设置双击行为监听接口
gestureDetector.setOnDoubleTapListener(this);

  接着接管目标View的onTouchEvent方法,在待监听View的onTouchEvent方法中,添加如下实现。

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

  事实上就是将View的事件处理从onTouchEvent委托到GestureDetector中,将待监听的View的事件处理委托到GestureDetector中进行处理。OnGestureListener接口和OnDoubleTabListener接口中的方法介绍如下所示。

方法名 描述 所属接口
onDown 手指轻轻触摸屏幕的一瞬间,由1个ACTION_DOWN触发 onGestureListener
onShowPress 手指轻轻触摸屏幕,尚未松开或拖动,由1个ACTION_DOWN触发 onGestureListener
onSingleTapUp 手指**(轻轻触摸屏幕)松开**,伴随着1个ACTION_UP而触发,这是单击行为 onGestureListener
onScroll 手指按下屏幕并拖动,由1个ACTION_DOWN,多个ACTION_MOVE触发,这是拖动行为 onGestureListener
onLongPress 用户长久按着屏幕不放,即长按 onGestureListener
onFling 用户按下触摸屏、快速滑动后松开,由1个ACTION_DOWN,多个ACTION_MOVE和1个ACTION_UP触发,这是快速滑动行为 onGestureListener
onDoubleTap 双击,由2次连续的单击组成,它不可能和onSingleTapConfirmed共存 onDoubleTabListener
onSingleTabConfirmed 严格的单击行为。如果触发了该行为,后面紧跟的另一个单击行为只可能是单击,而不可能是双击中的一次单击。 onDoubleTabListener
onDoubleTabEvent 表示发生了双击行为,在双击期间,ACTION_DOWN、ACTION_MOVE和ACTION_UP都会触发此回调。 onDoubleTabListener

  在实际开发中,可以不使用GestureDetector,完全可以在View的onTouchEvent方法中实现所需的监听。一个建议是:如果只是监听滑动相关的,建议在onTouchEvent中实现,如果要监听双击行为,那么就使用GestureDetector
在这里插入图片描述

  1. Scroller

  弹性滑动对象,用于实现View的弹性滑动。当使用View的scrollTo/scrollBy方法进行滑动时,其过程是瞬间完成的,没有过渡效果。而Scroller能够实现过渡效果的滑动,其过程是在一定的时间间隔内完成的。具体的使用方法见后续笔记:Android进阶知识(九):View的滑动和弹性滑动

参考资料:《Android开发艺术探索》

原创文章 78 获赞 25 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_38196407/article/details/90056491