android view的事件体系(二)

一。弹性滑动

View的滑动是比较生硬的滑动过去,在瞬间完成,用户体验太差,所以我们要实现弹性滑动。

思想: 将一次大的滑动分成若干次小的滑动,并在一个时间段完成,

实现方式: Scroller ,Handler & postDelayed ,thread & sleep

1.使用Scoller

使用方式已经在上一篇博客中提供代码。View的体系(一)中进行查看:

Scoller的工作原理:

构建一个scoller对象调用startScoll时,Scoller内部什么也没做,只是保存我们传递的参数,代码如下:

通过代码我们可以看出,startX startY表示的滑动的起点,dx,dy表示滑动的距离,

Duration表示滑动的时间。这里的滑动表示的是内容非view的本身,

Scroller通过startScoll方法的invalidate方法进行view的重新绘制,

在view的draw方法中会去调用computeScroll方法,computeScoll向scroller获取当前的ScrollX和ScrollY;

总结:

Scroller本身并不能实现view的滑动,需要配合viewcomputeScoll方法完成弹性滑动效果。通过不断的让view重新绘制,每次滑动都会有一个时间间隔,通过这个时间间隔得出view的滑动位置,再通过ScrollTo方法完成滑动,就这样每一次绘制都会导致ciew进行小幅度的滑动,多次组合成弹性滑动;

 

2.通过动画

动画本身就是一种渐进的过程,因此他本身就具备弹性效果,

例如:让view的内容在100ms向左移动100像素

  1. 使用动画模仿Scoller来实现view的滑动

通过上诉代码发现,思想和Scoller比较类似,通过一个百分比分配scollTo方法完成view的滑动。

3.使用延迟策略

延迟策略的核心:

通过发送一系列延时消息从而达到一种渐进式的效果,使用handler。View的postDelayed方法;

,也可以使用线程的方法;

  1. 举例(使用handler)

 

二。View的事件分发机制

1.什么是事件分发过程

当一个点击事件产生以后,系统需要把这个事件传递给一个具体的view,这个传递过程就是分发过程。分发过程有三个重要方法来共同完成;

2.dispachTouchEvent

用来进行事件分发,如果事件能够传递给view,那么此方法一定会被调用,返回结果和当前view的onTouchEvent和下级view的dispatchTouchEvent方法影响,表示是否消耗当前事件

3.onInterceptTonchEvent

用于判断是否拦截某个事件,如果当前view拦截某个事件,那么在同一个事件序列中,此方法不会被调用,表示是否拦截当前事件

4.onTouchEvent

在dispatchTouchEvent方法中调用,用来处理点击事件,返回结果表示是否消耗当前事件,

如果不消耗则在同一个事件序列中,当前view无法再次接收到事件

  1. 三者的关系

通过上诉代码可以直观的发现三者关系:

对于一个根viewGroup来说,点击事件产生,dispatchTouchEvent方法就会被调用;如果viewGrouponInterceptTouchEvent方法返回true,表示拦截当前事件,事件交给这个viewGroup进行处理,如果返回false,表示不拦截当前事件,事件会传递给它的子元素,子元素的dispatchTouchEvent方法就会被调用,直到事件被最终处理;

2)优先级问题

当一个view需要处理事件时,设置了onTouchListener,onTouch方法就会被回调,事件的处理需要看onTouch返回值,返回true,onTouchEvent方法不会被调用,返回false,onTouchEvent方法会被调用;

可见,View设置的onTouchListener优先级比onTOuchEvent高;在onTOuchEvent方法中,如果当前设置有onClickListener,那么onClick会被调用,所以onClickListener优先级最低

 

3)事件传递的机制

一个事件产生后,传递过程:activity----window ----- view 即事件总是最先传递给acitivty ----àwindow --------àview,当view接收到事件后,就会按照事件分发机制去分发事件;如果一个view的onTOuchEvent返回false,他的父容器onTOuchEvent方法就会被调用,依次类推,最终事件将会传递给activity进行处理;

 

  1. 关于事件传递机制,总结:
  1. 同一事件的序列指:用户手指触摸到屏幕,到离开屏幕那一刻结束,(down -àmove ---àup)
  2. 一个事件序列只能被一个view拦截消耗,
  3. 某个view一旦决定拦截,那么一个事件序列只能由他来处理,并且onInterceptTouchEvent方法不会再被调用,
  4. 某一个view一旦开始处理事件,如果它不消耗ACTION_DOWN事件(onTOuchEvent返回false),那么同一事件序列其他事件都不会再交给它处理。并且事件将重新交给父元素去处理;
  5. 如果view不消耗除ACRTION_DOWN以外的其他事件,那么这个点击事件就会消失,此时父元素的onTOuchEvent不会被调用,并当前view可以持续收到后续的事件,最终消失的事件会传递给activity进行处理
  6. ViewGroup默认不拦截任何事件,相当于viewGroup的onInterCeptTouchEvent方法返回false
  7. View 没有onInterceptTOuchEvent方法,一旦点击事件传递给它,他的onTouchEvent方法就会被调用;

android view事件体系(一)

https://blog.csdn.net/wk_beicai/article/details/89515914

发布了96 篇原创文章 · 获赞 370 · 访问量 42万+

猜你喜欢

转载自blog.csdn.net/wk_beicai/article/details/89532160