[摘]View的基础知识

Android  2020年10月10日 am10:04发布4年前 (2020)更新 城堡大人
119 0 0

前言

这边文章总结得不错,对View的总结很到位。

因此摘抄于此,方便自己学习。

View的基础知识

了解View,可以有效的使用View

mTop mLeft mRight mBottom

View的位置主要通过它的四个顶点来决定,对应View的四个属性。

  1. mTop 左上角纵坐标
  2. mLeft 左上角横坐标
  3. mRight 右下角横坐标
  4. mBottom 右下角纵坐标
getTanslationX() getTranslationY()

Android3.0之后提供的两个方法,getTranslationX()和getTranslationY(),它们不同于上面的四个参数,这两个参数会由于 View的平移而变化,表示View左上角坐标相对于left、top(原始左上角坐标)的偏移量

getX() getY()

Android3.0之后提供了getX()和getY()两个方法。

@ViewDebug.ExportedProperty(category = "drawing")
public float getX() {
    return mLeft + getTranslationX();
}

代码是将mLeft加上translationX得到x的,可以看出来,x和y代表的就是当前View左上角相对于父布局的偏移量。

MotionEvent

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

  1. ACTION_DOWN——手指刚接触屏幕。
  2. ACTION_MOVE——在屏幕上移动。
  3. ACTION_DOWN——从屏幕上松开。

这些事件对应MotionEvent类中的几个静态常量。

public static final int ACTION_DOWN = 0;
public static final int ACTION_UP   = 1;
public static final int ACTION_MOVE = 2;

正常情况下的一些列点击事件:

  1. 点击屏幕后立即松开,ACTION_DOWN->ACTION_UP
  2. 点击屏幕滑动后再松开,ACTION_DOWN->ACTION_MOVE->......->ACTION_MOVE->ACTION_UP
  3. 可以通过MotionEvent对象调用getX()、getY()、getRawX()、getRawY()获取触碰点的位置参数。
  4. getX()、getY() 相对于当前View左上角的x、y值。
  5. getRawX()、getRawY() 相对于手机屏幕左上角的x、y值。
TouchSlop

TouchSlop是系统能识别的最小滑动距离,如果小于这个值,则不认为是滑动。这是一个常量和设备有关,可以通过以下方式获得。

ViewConfiguration.get(getContext()).getScaledTouchSlop();

public int getScaledTouchSlop() {
    return mTouchSlop;
}

这个mTouchSlop在ViewConfiguration的无参构造器中用一个常量赋了初始值为8。

private static final int TOUCH_SLOP = 8;
@Deprecated
public ViewConfiguration() {
    //...
    mTouchSlop = TOUCH_SLOP;
    //...
}

有参构造器中初始化为资源文件的一个值,这个值也是8。

<!-- Base "touch slop" value used by ViewConfiguration as a
     movement threshold where scrolling should begin. -->
<dimen name="config_viewConfigurationTouchSlop">8dp</dimen>

private ViewConfiguration(Context context) {
    //...
    mTouchSlop = res.getDimensionPixelSize(com.android.internal.R.dimen.config_viewConfigurationTouchSlop);
    //...
}

在处理滑动的时候可以使用这个值来做一些过滤,过滤掉滑动距离小于这个值,会有更好的用户体验。

Velocity Tracker

用来获取手指滑动过程中的速度,包括水平速度和垂直速度。

onTouchEvent()中追踪当前单击事件的速度。

  1. 首先获得一个VelocityTracker对象,再将当前时间加入进去。
VelocityTracker velocityTracker = VelocityTracker.obtain();
velocityTracker.addMovement(event);
  1. 计算自定义时间内的速度,再调用get获得定义时间内划过的像素点。
velocityTracker.computeCurrentVelocity(1000);
int xVelocity = (int) velocityTracker.getXVelocity();
int yVelocity = (int) velocityTracker.getYVelocity();
  1. 计算真正的速度。
int xV = xVelocity / 1;//这里的1是上面计算时间时定义的时间间隔1000ms
int yV = yVelocity / 1;
  1. 回收资源。
velocityTracker.clear();
velocityTracker.recycle();

PS:

  1. 获取速度之前必须要调用computeCurrentVelocity()计算速度。
  2. getXVelocity()\getYVelocity()获取到的是计算单位时间内滑过的像素值,并不是速度。
GestureDetector

GestureDetector用于检测用户的单击、滑动、长按、双击等行为。

GestureDetector内部有两个监听接口,OnGestureListener和OnDoubleTapListener,里面的方法可以根据需求去实现。

public interface OnGestureListener {
    boolean onDown(MotionEvent e);//手指轻轻触摸屏幕的一瞬间,一个ACTION_DOWN触发
    void onShowPress(MotionEvent e);//手指轻触屏幕,没有松开或挪动
    boolean onSingleTapUp(MotionEvent e);//轻触后松开,单击行为,伴随一个ACTION_UP触发
    boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY);//拖动行为,由一个ACTION_DOWN和一系列ACTION_MOVE触发
    void onLongPress(MotionEvent e);//长按
    boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY);//按下快速滑动后松开,一个ACTION_DOWN、多个ACTION_MOVE和一个ACTION_UP触发
}
public interface OnDoubleTapListener {
    boolean onSingleTapConfirmed(MotionEvent e);//严格的单击行为,不能是双击中的其中一次单击,onSingleTapUp可以是双击中的其中一次。
    boolean onDoubleTap(MotionEvent e);//双击,两次单击,不可能和onSingleTapConfirmed共存
    boolean onDoubleTapEvent(MotionEvent e);//双击行为,双击期间ACTION_DOWN ACTION_MOVE ACTION_UP都会触发此回调。
}

创建一个GestureDetector,根据需要实现接口并传入GestureDetector。

gestureDetector = new GestureDetector(context, gestureListener);
gestureDetector.setOnDoubleTapListener(doubleTapListener);
gestureDetector.setIsLongpressEnabled(false);//解决长按屏幕后无法拖动的现象

接管View的onTouchEvent(),GestureDetector的onTouchEvent()中会根据event来回调上面说的两个接口方法。

@Override
public boolean onTouchEvent(MotionEvent event) {
    boolean consume = gestureDetector.onTouchEvent(event);
    return consume;
}

PS:

并不是必须要用GestureDetector来实现所需的监听,完全也可以直接在View的onTouchEvent()中做判断并实现需求。所以,如果只需要监听简单的单击事件就可以直接使用View的onTouchEvent(),如果需要监听复杂一点的一系列事件,就可以使用GestureDetector。

摘抄来源

  1. Android View相关(一)View的参数与滑动实现

 历史上的今天

  1. 2024: ATC平台去掉U盘的fsck功能(0条评论)
  2. 2019: 许知远:优雅的爱情到哪里去了(0条评论)
版权声明 1、 本站名称: 笔友城堡
2、 本站网址: https://www.biumall.com/
3、 本站部分文章来源于网络,仅供学习与参考,如有侵权,请留言

暂无评论

暂无评论...

随机推荐

Android Studio删除引用的资源

前言之前说过,Android Studio有个功能(Android Studio Refactor/Remove Unused Resources【重构,移除没有引用的资源】),非常好用,但到了Android Studio高版本时好像失效了。最近看到其他的功能替代。因此记录于此,方便自己查阅...

林清玄:把时间花在心灵上

朋友带我去看一位收藏家的收藏,据说他收藏的都是顶级的东西,随便拿一件来都是价逾千万。我们穿过一条条的巷子,来到一家不起眼的公寓前面,我心中正自纳闷,顶级的古董怎么会收藏在这种地方呢?收藏家来开门了,连续打开三扇不锈钢门,才走进屋内。室内的灯光非常幽暗,等了几秒钟,我才适应了室内的光线,这时,才赫...

[摘]各种基本数据类型转byte数组并反转

int 转 byte[]   低字节在前(低字节序)public static byte[] toLH(int n) { byte[] b = new byte[4]; b[0] = (byte) (n & 0xff); b[1] = (byte) (n >&g...

Activity的Context介绍

前言对于Application,Activity和Service这几个类,我们是很[熟悉]的。确实[熟悉],作为App开发这基本都要面对这几个类。比较好奇的朋友会发现,他们都拥有Context,但他们的Context有似乎有一点点的不同。今天有空,根据网上大佬的步伐,在这里简单记录一下。正文...

[摘]音视频学习系列第(一)篇---基础概念

shui知道最在学习这个,这个博主总结得不错,因此摘抄于此,以方便自己查阅。可访问改博主sofarsogoo_932d的一系列文章《音视频学习系列》,感谢他的分享。什么是音/视频音频声音的集合视频图片的集合,当一段连续的图片不断的出现在人眼前(至少要求1秒24帧,即一秒内连续出...

Android6.0Settings分析

源码:Android 6.0应用:Settings目录:android-6.0.0_r1\packages\apps\Settings Android 中Settings的代码很多,我这里只是简单分析一下,仅供参考。如果要深入了解设置,自己要多看看源码。一般分析应用的话...