博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
View的事件体系
阅读量:6229 次
发布时间:2019-06-21

本文共 3442 字,大约阅读时间需要 11 分钟。

hot3.png

  • 3.1 View的基础知识

  • 1.View:

     View是Android中所有控件的基类(和java中的Object相似),它是一种界面层控件的抽象。ViewGroup也是继承自View的,它们相互嵌套,形成了View树结构。

  • 2.View的位置参数:

          top、left、right、bottom,分别对应View的左上角和右下角相对于父容器的横纵坐标值。 

          从Android 3.0开始,view增加了x、y、translationX、translationY四个参数,这几个参数也是相对于父容器的坐标。x和y是左上角的坐标,而translationX和translationY是view左上角相 对于父容器的偏移量,默认值都是0。
x = left + translationX
y = top + translationY
       注意:在进行平移操作的时候,top、left、right、bottom不会改变,还是原始位置的值,x、y、translationX、translationY则会跟随移动改变。
      185314_VKpt_2336969.png

  • 3.MotionEvent和TouchSlop

  • 3.1. MotionEvent

MotionEvent是指手指接触屏幕后所产生的一系列事件,主要有ACTION_UP、ACTION_DOWN、ACTION_MOVE等。正常情况下,一次手指触屏会触发一系列点击事件,主要有下面两种典型情况:

1.点击屏幕后离开,事件序列是ACTION_DOWN -> ACTION_UP;
2.点击屏幕后滑动一会再离开,事件序列是ACTION_DOWN -> ACTION_MOVE -> ACTION_MOVE -> … -> ACTION_UP;
通过MotionEvent可以得到点击事件发生的x和y坐标,其中getX和getY是相对于当前view左上角的x和y坐标,getRawX和getRawY是相对于手机屏幕左上角的x和y坐标。

  • 3.2.    TouchSlop

TouchSlope是系统所能识别出的可以被认为是滑动的最小距离,获取方式是ViewConfiguration.get(getContext()).getScaledTouchSlope()。查看源码发现这个值是8dp。实际使用的时候,可以拿到这个值来判断是否是滑动。

  • 4. VelocityTracker、GestureDetector、Scroller

  • 4.1. VelocityTracker

VelocityTracker用于追踪手指在滑动过程中的速度,包括水平和垂直方向上的速度。

    速度计算公式: 速度 = (终点位置 - 起点位置) / 时间段
使用过程:
1.在View的OnTouch方法中追踪当前单击事件的速度
 185341_TN2w_2336969.png
2.获得当前速度:获得之前必须计算,也就是调用mVelocityTracker.computeCurrentVelocity(时间ms);这里的速度是指单位时间内的速度,计算公式如上所示。
 185352_DOKd_2336969.png
3.不需要的时候重置回收

185359_ymSm_2336969.png

  • 4.2    GestureDetector

GestureDetector用于辅助检测用户的单击、滑动、长按、双击等行为。GestureDetector的使用比较简单,主要也是辅助检测常见的触屏事件。作者建议:如果只是监听滑动相关的事件在

onTouchEvent中实现;如果要监听双击这种行为的话,那么就使用GestureDetector。
使用过程:
1.创建对象实现接口
 185418_8rAp_2336969.png
2.接管View的OnTouchEvent事件

185435_ekCI_2336969.png

3.    选择性实现接口中的方法:列举使用较多的
185451_a1wR_2336969.png

185457_kxWJ_2336969.png

185502_W5tR_2336969.png

  • 4.3    Scroller

弹性滑动对象,用于实现View的弹性滑动。

在下面使用Scroller进行弹性滑动会再说。
常见实现实例:

185511_tr5M_2336969.png185521_P7C1_2336969.png

参考:View滑动效果的七种实现方式 http://blog.csdn.net/zly921112/article/details/50436538

详细内容可以参见《Android群英传》读书笔记 (2) 第五章 Scroll分析

 

  • 3.2 View的滑动

    不管多么绚丽的滑动效果,最终都是由不通过的滑动加特效组成的。掌握滑动的方法是实现绚丽的自定义控件的基础。目前有三种常见方式可以实现控件的滑动:控件本身提供的scrollTo/scrollBy、动画效果、改变View的LayoutParams使用View重新布局从而实现滑动。

  • 3.2.1控件本身提供的scrollTo/scrollBy

    源码分析:

 185537_YEz9_2336969.png

185542_nKhL_2336969.png

 
源码看出来,一个是滑动到指定位置(绝对位置),一个是做增量滑动。在滑动过程中,要十分注意,这个坐标系计算方式有点奇葩,由于我们scrollTo/scrollBy滑动的是内容,而不是View本身(如果是一个ViewGroup那么就是所有子控件移动了)。所以就导致内容区域向右上滑动是负数,另外怎么滑动也无法将View滑动到附近其它View的区域,超滑动到其它View就超出父ViewGroup了,超出部分就不会显示。
具体可以参考:
这篇博客关于这个讲的很不错,另外可以参考《android群英传》94页分析的也很好
 android 布局之滑动探究 scrollTo 和 scrollBy 方法使用说明
http://blog.csdn.net/vipzjyno1/article/details/24577023
 185549_TySH_2336969.png

  • 3.2.2使用动画

传统的动画作用的是View的影像,View本身并没有什么移动,动画完成之后FillAfter设置true停在最后一刻。而Android3.0之后出的属性动画则可以移动View本身。帧动画可以做的事情属性动画都可以做到,但是3.0以下的想用就需要动画库的支持包了。

 
传动的动画做完之后由于View没动,所以会有很大问题,常见的就是点击事件还在原来的位置上面。艺术探究上对于这个问题有个思路,在动画结束位置准备一个一样的控件,动画完了显示出来,隐藏原来的。不过有点麻烦,还是用属性动画吧,3.0以下现在用的也少。

185600_3F4f_2336969.png

补充阅读参考:

书籍::《Android群英传》第7章
博客:android 动画分类 
http://blog.csdn.net/xyz_lmn/article/details/38667899    

  • 3.2.3 改变布局参数

这里直接拿到LayoutParams做相应改变就可以了

 185617_oeXB_2336969.png

  • 3.2.4 三种方式的对比

第一种,原生方法,专门用于滑动,可以轻松滑动而且不影响布局内部元素的点击事件,但是只能滑动内容而不能滑动View本身。

第二种,动画,属性动画比较完美,View本身也可以操作。但是另外二种动画(3.0以下的),不能改变View本身的位置,不适合有交互的View。动画的优点在于,可以实现某些较为复杂的动画效果。
第三种,直接改参数,适合有交互的View。

  • 3.3弹性滑动

    实现弹性滑动有一个共同的思想:渐进式滑动,都是将一次大的滑动分成若干次小的滑动并且在一个时间段内完成。常见的有三种实现方式:Scroller、Handler#postDelayed、Thread#sleep.

  • 3.3.1 Scroller

代码清单:

 185630_keH7_2336969.png
我们构建了mScroller对象之后,调用StartScroll(),源码如下,还没有做什么操作,只是保存了一些数据。
 185636_WhOG_2336969.png
之后调用invalidate()进行刷新,动画开始了,invalidate()之后会调用onDraw()方法,onDraw()会调用到,computeScroll()方法,这个是一个空实现,上面我们实现了,拿到当前父视图中content的滑动坐标。接着继续刷新。循环知道完成动画

  • 3.3.2 通过动画

    动画本身就天然具有渐进性,使用就有弹性。书中例子:用属性动画模仿Scroller

  • 3.3.3 使用延时策略

    发送一系列延时消息,达到一种渐进式效果。可以使用Handler和View的postDelayed来实现,通过不断的循环给自己发消息,达到效果,记得要有出口,不然就是死循环了。

常见使用实例:这里在界面退出的时候,最好是把消息remove掉,不然后台还是会继续循环操作,在Android中常见的自动轮播图,就可以使用这种策略来做,这个就必须在界面退出时候移除了。
     185646_uVF9_2336969.png

 

未完待续。。。。

转载于:https://my.oschina.net/byronhs/blog/714012

你可能感兴趣的文章
Python3.4 12306 2015年3月验证码识别
查看>>
从Handler.post(Runnable r)再一次梳理Android的消息机制(以及handler的内存泄露)
查看>>
windows查看端口占用
查看>>
Yii用ajax实现无刷新检索更新CListView数据
查看>>
JDBC的事务
查看>>
Io流的概述
查看>>
App 卸载记录
查看>>
JavaScript变量和作用域
查看>>
开源SIP服务器加密软件NethidPro升级
查看>>
《别做正常的傻瓜》的一些读书心得
查看>>
作业:实现简单的shell sed替换功能和修改haproxy配置文件
查看>>
Altium 拼板方法以及 注意的 地方
查看>>
PMP考试的过与只是
查看>>
java 监控 收集资料3(收集中)
查看>>
Apache Pulsar中的地域复制,第1篇:概念和功能
查看>>
getRealPath()和getContextPath()的区别
查看>>
python pip install 出现 OSError: [Errno 1] Operation not permitted
查看>>
oracle12C 重做日志
查看>>
awk-sed
查看>>
zookeeper与kafka安装部署及java环境搭建(发布订阅模式)
查看>>