Android事件分发机制
来源:互联网 发布:无法优化游戏的问题 编辑:程序博客网 时间:2024/06/05 08:27
一、View位置参数
1.top、bottom、left、right:分别表示四个顶点的原始坐标,通过getTop()、getBottom()、getLeft()、getRight()方法获取,这些坐标都是相对于父控件的相对坐标,如果要获取相对于屏幕的绝对坐标可以通过View.getLoactionOnScreen(int[])获得
2.x、y是View左上角相对于父容器的坐标,translationX、translationY是View左上角相对于父容器的偏移量,View也为它们提供了get/set方法
x = left + translationX
y = top + translationY
二、MotionEvent
点击事件发生的x、y:
event.getX()、event.getY():获取相对于当前View左上角的坐标
event.getRawX()、event.getRawY():获取相对于屏幕左上角的坐标
三、ScrollTo/ScrollBy滑动
getScrollX()、getScrollY()分别获取View左边缘和View内容左边缘在水平方向的距离和View上边缘和View内容上边缘在竖直方向的距离,即View左边缘或上边缘的内容的原始坐标,从左向右和从上向下滑动为负值,从右向左和从下向上滑动为正值。
四、
1.TouchSlop:系统所能识别的被认为是滑动的最小距离
ViewConfiguration.get(getContext()).getScaledTouchSlop();
2.VelocityTracker:速度追踪
在onTouchEvent方法中追踪当前点击事件的速度:
VelocityTracker velocityTracker = VelocityTracker.obtain(); velocityTracker.addMovement(event); velocityTracker.computeCurrentVelocity(1000);//计算速度 int xVelocity = (int) velocityTracker.getXVelocity(); int yVelocity = (int) velocityTracker.getYVelocity(); velocityTracker.clear();//重置回收内存 velocityTracker.recycle();
3.GestureDetector:手势检测
创建一个GestureDetector对象并实现OnGestureListener接口
在待监听View的onTouchEvent方法中
GestureDetector gestureDetector = new GestureDetector(this, new GestureDetector.OnGestureListener(){ @Override public boolean onDown(MotionEvent e) { return false; } @Override public void onShowPress(MotionEvent e) { } @Override public boolean onSingleTapUp(MotionEvent e) { return false; } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { return false; } @Override public void onLongPress(MotionEvent e) { } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { return false; } }); //解决长按屏幕后无法拖动的现象 gestureDetector.setIsLongpressEnabled(false); return gestureDetector.onTouchEvent(event);
五、View的滑动
1.使用ScrollTo/ScrollBy
2.使用动画,主要是操作View的translationX和translationY属性
3.改变布局参数getLayoutParams()和setLayoutParams()
六、弹性滑动
1.使用Scoller
invalidate()方法会导致View重绘,在View的draw方法中又会调用computeScroll方法,computeScroll方法在View中是一个空实现,需要自己实现,完成控件的滑动
Scroller scroller = new Scroller(this); scroller.startScroll(fromX,fromY,deltaX,deltaY,duration); invalidate();
@Override public void computeScroll(){ if(scroller.computeScrollOffset()){ scrollTo(scroller.getCurrX(),scroller.getCurrY()); postInvalidate(); } }
2.使用值动画
ValueAnimator valueAnimator = ValueAnimator.ofInt(0,100).setDuration(1000); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { int value = (int) animation.getAnimatedValue(); view.scrollBy(value); } });
3.使用延时策略
使用Handler或View的postDelayed方法发送一个延时消息,在消息中进行View的滑动,接连不断地发送这种这种延时消息;
或者使用线程的sleep方法,在while循环中不断地滑动View和sleep;
六、View事件分发机制
事件传递给某View,调用该View的dispatchTouchEvent方法,在该方法内部调用onInterceptTouchEvent方法,返回true,表示拦截,调用onTouchEvent方法,返回true,表示消耗该事件,返回false表示不处理该事件,交给父View的onTouchEvent方法处理;返回false,表示不拦截,将事件继续向下传递给子View,调用子View的dispatchTouchEvent方法。
通过requestDisallowInterceptTouchEvent()方法可以在子元素中干预父元素的事件分发过程,ACTION_DOWN事件除外。
七、滑动冲突
1.外部拦截法
重写父元素的onInterceptTouchEvent()方法,父容器需要此事件则拦截,不需要则不拦截,ACTION_DOWN必须返回false,ACTION_MOVE根据需求来决定是否拦截,ACTION_UP事件也要返回false,否则处理事件的子元素无法接收到ACTION_UP事件。
2.内部拦截法
重写子元素的dispatchTouchEvent()方法,调用parent.requestDisallowInterceptTouchEvent();
如果子元素需要此事件就直接消耗掉,否则就交由父容器处理
- android事件分发机制
- Android事件分发机制
- Android 事件分发机制
- Android事件分发机制
- Android 事件分发机制
- Android 事件分发机制
- android 事件分发机制
- Android事件分发机制
- android 事件分发机制
- android事件分发机制
- Android 事件分发机制
- android事件分发机制
- android 事件分发机制
- android 事件分发机制
- Android 事件分发机制
- Android事件分发机制
- Android事件分发机制
- Android 事件分发机制
- 进程监控程序-java
- Maven学习 (一) 搭建Maven环境
- opencv读取并显示两个摄像头
- 2-3-4 Tree
- qwerq
- Android事件分发机制
- PHP干货
- do...while(0)的妙用
- zabbix安装
- 【杂碎笔记】【计算机与机器视觉 by E.R.Davies】Chapter4
- Maven profile整合Spring profile
- Python案例-开发之路-进度条实现
- Valid Parentheses
- Android动画学习Demo(3) 沿着贝塞尔曲线移动的Property Animation