静态网站建设课程设计wordpress添加一言

当前位置: 首页 > news >正文

静态网站建设课程设计,wordpress添加一言,大兴网站开发网站建设价格,漯河市住房和乡镇建设局官方网站文章目录Android View事件分发机制#xff1a;事件分发中的核心方法onTouchListener和onClickListener的优先级事件分发DOWN,MOVE,UP 事件分发CANCEL代码实践requestdisallowIntereptTouchEvent作用Android View事件分发机制#xff1a; 事件分发中的核心方法 Android中事件… 文章目录Android View事件分发机制事件分发中的核心方法onTouchListener和onClickListener的优先级事件分发DOWN,MOVE,UP 事件分发CANCEL代码实践requestdisallowIntereptTouchEvent作用Android View事件分发机制 事件分发中的核心方法 Android中事件分发实际上分发的是MotionEvent事件分发的过程中涉及到下面三个核心的方法 dispatchTouchEvent用来进行事件的分发只要事件传递给当前View那么这个方法一定会被调用该方法的返回值受到onTouchEvent和子View的dispatchTouchEvent的影响。onInterceptTouchEvent用来询问是否拦截某个事件如果当前View拦截了某个事件那么在同一个事件序列中这个方法不会被再次调用。onInterceptTouchEvent只存在于ViewGroup中Activity和普通的View中都没有这个方法onTouchEvent用来处理MotionEvent 上面的方法如果返回的是true就表示消耗当前的事件。 onTouchListener和onClickListener的优先级 onTouchListener 优先级高于 onClickListener onTouchListener优先级高于onClickListeneronTouchListener返回false后续的click事件才会被处理onTouchListener返回true表示消耗了事件不会再传递。 事件分发 事件传递的时候是由Activity-window-view如果view不处理的话最后事件会回到activity在事件的流程中View不会分发事件View只会处理事件ViewGroup会先分发事件如果子View没有处理事件尝试自己处理事件如果自己没有处理最后交给Activity。 DOWN,MOVE,UP 事件分发 android.view.ViewGroup#dispatchTouchEvent boolean handled false;if (onFilterTouchEventForSecurity(ev)) {final int action ev.getAction();final int actionMasked action MotionEvent.ACTION_MASK;// Handle an initial down.if (actionMasked MotionEvent.ACTION_DOWN) {// Throw away all previous state when starting a new touch gesture.// The framework may have dropped the up or cancel event for the previous gesture// due to an app switch, ANR, or some other state change.cancelAndClearTouchTargets(ev);// 一次事件开始ViewGroup会先清除之前的状态例如清楚FLAG_DISALLOW_INTERCEPT的标记resetTouchState();}// Check for interception.final boolean intercepted;// 为down事件或者mFirstTouchTarget不为空表示找到了消耗touch事件的viewif (actionMasked MotionEvent.ACTION_DOWN|| mFirstTouchTarget ! null) {final boolean disallowIntercept (mGroupFlags FLAG_DISALLOW_INTERCEPT) ! 0;if (!disallowIntercept) {intercepted onInterceptTouchEvent(ev);ev.setAction(action); // restore action in case it was changed} else {intercepted false;}} else {// There are no touch targets and this action is not an initial down// so this view group continues to intercept touches.intercepted true;}…// 会便利当前viewgroup的所有child寻找是否需要消耗事件// Find a child that can receive the event.// Scan children from front to back.final ArrayListView preorderedList buildTouchDispatchChildList();final boolean customOrder preorderedList null isChildrenDrawingOrderEnabled();final View[] children mChildren;for (int i childrenCount - 1; i 0; i–) {final int childIndex getAndVerifyPreorderedIndex(childrenCount, i, customOrder);final View child getAndVerifyPreorderedView(preorderedList, children, childIndex);// If there is a view that has accessibility focus we want it// to get the event first and if not handled we will perform a// normal dispatch. We may do a double iteration but this is// safer given the timeframe.if (childWithAccessibilityFocus ! null) {if (childWithAccessibilityFocus ! child) {continue;}childWithAccessibilityFocus null;i childrenCount - 1;}// canReceivePointerEvents判断view是否可见view没有再播放动画// isTransformedTouchPointInView判断点击区域是否在view的范围内if (!child.canReceivePointerEvents()|| !isTransformedTouchPointInView(x, y, child, null)) {ev.setTargetAccessibilityFocus(false);continue;}ViewGroup的TouchEvent中都会先去判断View是否有子view有子view的话递归调用子View的dispatchTouchEvent方法否则直接调用自己的dispatchTouchEvent方法 if (child null) {handled super.dispatchTouchEvent(event);} else {handled child.dispatchTouchEvent(event);}Down事件分发后一定会找到了消耗事件的view或者事件直接被Activity消耗如果ViewGroup没有消耗事件事件就不会再继续往当前ViewGroup分发UP和MOVE事件都会发送到DOWN事件的消耗这上mFirstTouchTarget不为null直接找到target进行分发。 // Dispatch to touch targets.if (mFirstTouchTarget null) {// No touch targets so treat this as an ordinary view.handled dispatchTransformedTouchEvent(ev, canceled, null,TouchTarget.ALL_POINTER_IDS);} else {// Dispatch to touch targets, excluding the new touch target if we already// dispatched to it. Cancel touch targets if necessary.TouchTarget predecessor null;TouchTarget target mFirstTouchTarget;while (target ! null) {final TouchTarget next target.next;if (alreadyDispatchedToNewTouchTarget target newTouchTarget) {handled true;} else {final boolean cancelChild resetCancelNextUpFlag(target.child)|| intercepted;if (dispatchTransformedTouchEvent(ev, cancelChild,target.child, target.pointerIdBits)) {handled true;}if (cancelChild) {if (predecessor null) {mFirstTouchTarget next;} else {predecessor.next next;}target.recycle();target next;continue;}}predecessor target;target next;}} View的dispatchTouchEvent android.view.View#dispatchTouchEvent if (onFilterTouchEventForSecurity(event)) {if ((mViewFlags ENABLED_MASK) ENABLED handleScrollBarDragging(event)) {result true;}//noinspection SimplifiableIfStatementListenerInfo li mListenerInfo;if (li ! null li.mOnTouchListener ! null (mViewFlags ENABLED_MASK) ENABLED li.mOnTouchListener.onTouch(this, event)) {result true;}if (!result onTouchEvent(event)) {result true;}}View的dispatchTouchEvent中会先判断view有没有设置TouchListener如果设置了TouchListener再去判断onTouch方法的返回值如果onTouch方法没有消耗事件会再调用onTouchEvent方法。如果View 的onTouchEvent方法返回了false就表示事件没有被消耗那么最终会调用到ViewGroup的onTouchEvent。 // Dispatch to touch targets.if (mFirstTouchTarget null) {// No touch targets so treat this as an ordinary view.handled dispatchTransformedTouchEvent(ev, canceled, null,TouchTarget.ALL_POINTER_IDS);// 上面的代码会调用到dispatchTransformedTouchEvent中的下面的地方进行事件分发if (child null) {handled super.dispatchTouchEvent(transformedEvent);mFirstTouchTarget为null表示子view没有消耗事件这里会再调用dispatchTransformedTouchEvent去派发。 ViewGroup事件派发结束后就会回到Activity中参考下面的代码 /*** Called to process touch screen events. You can override this to* intercept all touch screen events before they are dispatched to the* window. Be sure to call this implementation for touch screen events* that should be handled normally.** param ev The touch screen event.** return boolean Return true if this event was consumed.*/public boolean dispatchTouchEvent(MotionEvent ev) {if (ev.getAction() MotionEvent.ACTION_DOWN) {onUserInteraction();}if (getWindow().superDispatchTouchEvent(ev)) {return true;}// 执行activity的onTouchEventreturn onTouchEvent(ev);}如果ViewGroup的onTouchEvent返回false那么就会调用Activity的onTouchEvent。 CANCEL Cancel事件触发场景案例当ScrollView中添加自定义View时ScrollView在DOWN事件不会进行拦截当手指滑动到一定的距离后onInterceptTouchEvent方法返回true并触发ScrollView的滚动效果当ScrollView进行滚动的时候内部的子View会收到一个cancel事件并丢失焦点。 代码实践 代码地址https://gitee.com/lxd15130140362/lxd-android-start/tree/master/app/src/main/java/com/example/androidstart/view 界面布局样式
都不处理事件点击自定义的Textview日志顺序如下 2023-02-19 20:50:19.786 7129-7129/com.example.androidstart I/Activity: dispatchTouchEvent: ACTION_DOWN 2023-02-19 20:50:19.787 7129-7129/com.example.androidstart D/CustomizeLayout: dispatchTouchEvent: ACTION_DOWN 2023-02-19 20:50:19.787 7129-7129/com.example.androidstart D/CustomizeLayout: onInterceptTouchEvent: ACTION_DOWN 2023-02-19 20:50:19.787 7129-7129/com.example.androidstart I/CustomizeTextView: dispatchTouchEvent: ACTION_DOWN 2023-02-19 20:50:19.787 7129-7129/com.example.androidstart I/CustomizeTextView: onTouchEvent: ACTION_DOWN 2023-02-19 20:50:19.787 7129-7129/com.example.androidstart I/CustomizeLayout: onTouchEvent: ACTION_DOWN 2023-02-19 20:50:19.787 7129-7129/com.example.androidstart I/Activity: onTouchEvent: ACTION_DOWN 2023-02-19 20:50:19.829 7129-7129/com.example.androidstart I/Activity: dispatchTouchEvent: ACTION_MOVE 2023-02-19 20:50:19.829 7129-7129/com.example.androidstart I/Activity: onTouchEvent: ACTION_MOVE 2023-02-19 20:50:19.927 7129-7129/com.example.androidstart I/Activity: dispatchTouchEvent: ACTION_MOVE 2023-02-19 20:50:19.928 7129-7129/com.example.androidstart I/Activity: onTouchEvent: ACTION_MOVE 2023-02-19 20:50:20.017 7129-7129/com.example.androidstart I/Activity: dispatchTouchEvent: ACTION_MOVE 2023-02-19 20:50:20.017 7129-7129/com.example.androidstart I/Activity: onTouchEvent: ACTION_MOVE 2023-02-19 20:50:20.018 7129-7129/com.example.androidstart I/Activity: dispatchTouchEvent: ACTION_UP 2023-02-19 20:50:20.018 7129-7129/com.example.androidstart I/Activity: onTouchEvent: ACTION_UPDown事件会从activity-viewgroup-viewmove和up事件都被activity自己消费了不会进行事件分发因为之前的down事件没有人分发就表示子view不会处理点击事件。 事件传输流程
自定义的ViewGroup的onInterceptTouchEvent返回true但是并不消耗事件日志如下 2023-02-19 20:57:04.896 7618-7618/com.example.androidstart I/Activity: dispatchTouchEvent: ACTION_DOWN 2023-02-19 20:57:04.898 7618-7618/com.example.androidstart D/CustomizeLayout: dispatchTouchEvent: ACTION_DOWN 2023-02-19 20:57:04.898 7618-7618/com.example.androidstart D/CustomizeLayout: onInterceptTouchEvent: ACTION_DOWN 2023-02-19 20:57:04.898 7618-7618/com.example.androidstart I/CustomizeLayout: onTouchEvent: ACTION_DOWN 2023-02-19 20:57:04.899 7618-7618/com.example.androidstart I/Activity: onTouchEvent: ACTION_DOWN 2023-02-19 20:57:04.995 7618-7618/com.example.androidstart I/Activity: dispatchTouchEvent: ACTION_MOVE 2023-02-19 20:57:04.996 7618-7618/com.example.androidstart I/Activity: onTouchEvent: ACTION_MOVE 2023-02-19 20:57:04.998 7618-7618/com.example.androidstart I/Activity: dispatchTouchEvent: ACTION_MOVE 2023-02-19 20:57:04.998 7618-7618/com.example.androidstart I/Activity: onTouchEvent: ACTION_MOVE 2023-02-19 20:57:04.999 7618-7618/com.example.androidstart I/Activity: dispatchTouchEvent: ACTION_UP 2023-02-19 20:57:04.999 7618-7618/com.example.androidstart I/Activity: onTouchEvent: ACTION_UPDown事件会从Activity-ViewGroup因为ViewGroup进行了拦截所以这里不会分发到子ViewMOVE和UP事件也只会在activity中进行分发 viewGroup的onInterceptTouchEvent调用父类实现但是onTouchEvent返回truue即ViewGroup不拦截但是消耗事件。 2023-02-19 21:17:28.939 9448-9448/com.example.androidstart I/Activity: dispatchTouchEvent: ACTION_DOWN 2023-02-19 21:17:28.940 9448-9448/com.example.androidstart D/CustomizeLayout: dispatchTouchEvent: ACTION_DOWN 2023-02-19 21:17:28.941 9448-9448/com.example.androidstart D/CustomizeLayout: onInterceptTouchEvent: ACTION_DOWN 2023-02-19 21:17:28.941 9448-9448/com.example.androidstart I/CustomizeTextView: dispatchTouchEvent: ACTION_DOWN 2023-02-19 21:17:28.942 9448-9448/com.example.androidstart I/CustomizeTextView: onTouchEvent: ACTION_DOWN 2023-02-19 21:17:28.942 9448-9448/com.example.androidstart I/CustomizeLayout: onTouchEvent: ACTION_DOWN 2023-02-19 21:17:29.021 9448-9448/com.example.androidstart I/Activity: dispatchTouchEvent: ACTION_MOVE 2023-02-19 21:17:29.022 9448-9448/com.example.androidstart D/CustomizeLayout: dispatchTouchEvent: ACTION_MOVE 2023-02-19 21:17:29.022 9448-9448/com.example.androidstart I/CustomizeLayout: onTouchEvent: ACTION_MOVE 2023-02-19 21:17:29.023 9448-9448/com.example.androidstart I/Activity: dispatchTouchEvent: ACTION_UP 2023-02-19 21:17:29.023 9448-9448/com.example.androidstart D/CustomizeLayout: dispatchTouchEvent: ACTION_UP 2023-02-19 21:17:29.023 9448-9448/com.example.androidstart I/CustomizeLayout: onTouchEvent: ACTION_UPdown事件会activity-viewgroup-view因为viewgroup消耗了事件因此down事件不会回到activity同时由于已经有了事件消费者因此MOVE和UP事件不会再往view进行传递回直接调用到ViewGroup的onTouch中中。 requestdisallowIntereptTouchEvent作用 子view在自己的down或者move的时候调用requestdisallowIntereptTouchEvent这样父view在这次事件传递中就不会拦截当前链路的事件。 链接 requestDisallowInterceptTouchEvent失效的原因及解决