关闭
Hit
enter
to search or
ESC
to close
May I Suggest ?
#leanote #leanote blog #code #hello world
Leo's Blog
Home
Archives
Tags
Search
RxJava
About Me
View的事件基础知识
UI
View
505
0
0
leoray
UI
View
本文是《Android开发艺术探索》中第三章Android的事件体系中的笔记。 # View 基础知识 View 的位置参数 MotionEvent TouchSlop VelocityTracker GestureDetector Scroller 等 ## 1. View 的坐标体系 ### left,top,right,bottom  其中, ``` width=right-left height=bottom-top ``` ### x,y,translationX,translationY Android 3.0开始,增加了其他的一些位置参数(都是相对于父容器的偏移量): x,y : View 左上角的坐标 translationX, translationY:View左上角相对于父容器的偏移量 其中, ``` x=left+translationX y=top+translationY ``` 在 View 平移过程中,left 和 top 是原始的左上角位置信息是不变的,发生改变的是上面这四个数值 ## 2. MotionEvent 有 - ACTION_DOWN:按下一瞬间 - ACTION_MOVE:在屏幕上移动 - ACTION_UP:从屏幕上松开的一瞬间 一般情况下,一个触摸事件会触发一系列MotionEvent,如: - 点击事件:DOWN->UP - 滑动:DOWN->MOVE->MOVE->..->UP 点击事件发生的 x,y 坐标的获取: getX,getY:相对于当前 View 左上角的坐标 getRawX,getRawY:相对于手机屏幕左上角的坐标 ## 3. TouchSlop 代表系统所能识别的被认为是滑动的最小距离,这是一个常亮和设备相关,获取方法: ViewConfiguration.get(getContext()).getScaledTouchSlop()。具体在源码中的位置:frameworks/base/core/res/res/values/config.xml 中的 config_viewConfigurationTouchSlop,比如某个设备是8dp ## 4. VelocityTracker 用于追踪滑动速度,包括水平和垂直速度,使用: 一定时间内像素滑动距离,公式: ``` 速度=(终点位置-起点位置)/ 时间段 ``` 所以,速度有可能为负数,从右向左滑动的时候速度就是负数。 方法: 1. 在 onTouchEvent 中追踪当前速度: ``` VelocityTracker vt=VelocityTracker.obtain(); vt.addMovement(event); ``` 2. 计算速度: ``` vt.computeCurrentVelocity(1000) ; //1000表示计算当前1s 内的速度,必须先调用 int xv=(int)vt.getXVelocity(); int yv=(int)vt.getYVelocity(); ``` 3. 不需要的时候: ``` vt.clear(); vt.recycle(); ``` ## 5. GestureDetector 手势检测,用于辅助检测用户的单击、滑动、长按、双击等行为。 1. 创建一个 GestureDetector 对象并实现 OnGestureListener 接口 ``` GestureDetector gestureDetector = new GestureDetector(getContext(), new SimpleOnGestureListener() { @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { return super.onScroll(e1, e2, distanceX, distanceY); } }); ``` 2. 接管目标 View 的 onTouchEvent 方法 ``` @Override public boolean onTouchEvent(MotionEvent event) { return gestureDetector.onTouchEvent(event); } ``` 3. 在 OnGestureListener 中实现我们需要的方法,如 onDown:手指轻触屏幕的一瞬间,一个 ACTION_DOWN onShowPress:手指触摸屏幕未松开或拖动,一个 ACTION_DOWN,强调没有松开或拖动的状态 onSingleTapUp:ACTION_UP ,没有 DOWN onScroll:DOWN->MOVE->MOVE... onLongPress:长按屏幕(未松开) onFling:**快速**滑动后松开,DOWN->MOVE->MOVE->..->UP onDoubleTap:两次连续单击 onSingleTapConfirmed:严格的单击行为,已确认是单击而不是 onDoubleTap onDoubleTapEvent:发生了双击行为`???` ## 6. Scroller 弹性滑动对象。因为 scrollTo,scrollBy 是瞬间完成的,没有过渡效果。 Scroller和View#computeScroll 共同完成弹性滑动 1. 定义 Scroller 对象 ``` Scroller sr=new Scroller(context); ``` 2. 定义执行方法 ``` private void smoothScrollTo(int destX, int destY) { int scrollX = getScrollX(); int scrollY = getScrollY(); //在1000ms 内滑动到目标位置 scroller.startScroll(scrollX, scrollY, destX - scrollX, destY - scrollY, 1000); invalidate(); } ``` 3. 重写computeScroll方法 ``` @Override public void computeScroll() { if (scroller.computeScrollOffset()) { scrollTo(scroller.getCurrX(), scroller.getCurrY()); postInvalidate(); } } ``` # View 的滑动 三中方法:(1)scrollTo,scrollBy;(2)平移动画;(3)改变 View 的 LayoutParams 使得 View 重新布局来实现滑动 ## 1. scrollTo,scrollBy 只改变 View 内容的位置而没有改变 View的位置,即改变的是 scrollX 和 scrollerY 两个参数  ## 2. 使用动画 1. 改变的是 translationX,translationY 两个属性值; 2. View 动画是对 View 的影像做操作,就算你设置 fillAfter=true 让 View 在动画完成后留在最终位置,但是如果这个View 是可点击的,点击区域仍旧在旧的位置,所以会发生很大的问题;所以不能简单的给一个 View 做平移动画还希望他能在新位置触发一些点击事件。属性动画没有这个问题。 3. View 属性动画可以直接操控 View 的属性进行平移以完成滑动等 ## 3. 改变 LayoutParams 比如,通过增大一个 Button 的 marginLeft 让该 Button 向右移动;通过在 Button 左侧放一个初始宽度为0的空 View,然后增加该 View 的宽度讲该 Button 向右移动等方法,比较灵活。 ## 4. 三种方式比较 scrollTo,scrollBy:操作简单,适合对 View 内容的滑动; 动画:操作简单,适用于不影响交互的 View 且实现复杂动画效果; 改变 LayoutParams:操作稍微复杂,适用于有交互的 View。 #View 的弹性滑动 ##1. Scroller :前面介绍了 ##2. 动画 通过动画当然能实现,另外,也可通过动画的 AnimatorUpdateListener 监听器来然后通过 scrollTo 来进行弹性动画: ``` final int startX=0; final int deltaX=100; ValueAnimator animator=ValueAnimator.ofInt(0,1).setDuration(1000); animator.addUpdateListener(new AnimatorUpdateListener(){ @Override public void onAnimationUpdate(ValueAnimator animator){ float fraction=animator.getAnimatedFraction(); //拿到已经完成的百分比 mButton.scrollTo(startX+(int)(deltaX*fraction),0); //按钮应该滚动的百分比也是对应的 } } ``` ## 3. 延时策略 通过 Handler#postDelayed(..)结合 scrollTo()来实现;
觉得不错,点个赞?
提交评论
Sign in
to leave a comment.
No Leanote account ?
Sign up now
.
0
条评论
More...
文章目录
No Leanote account ? Sign up now.