Android View事件传面试相关

    技术2022-07-11  87

    View 事件分发(csdn)

    传递图示

    事件拦截的应用场景 https://www.jianshu.com/p/d82f426ba8f7https://www.jianshu.com/p/b21a2d91a704面试题 为什么要有事件传递机制 因为android的view 是树形结构,当点击事件发生的时候 要经过好几层的View ,若是没有事件传递机制 ,就没办法确定这个事件给谁处理了,所以事件传递机制就是为了处理这个问题而出现的android布局加载的过程 用户执行Activity的setContentView方法,内部是PhoneWindow的setContentView方法,在PhoneWindow中完成DecorView的创建,PhoneWindow是window的实现类.DecorView是Activity的根View,也是PhotoWindow的内部类,并且继承了Framlayout.DecorView将屏幕分为2个部分:titleView和contentView,我们平常加载的布局就是ContentView.android 事件传递的三个重要方法

    viewgroup 拥有这三个方法 acitivity和view没有拦截方法,

    事件分发的流程 Activity——>PhoneWindow——>DecorView——>ViewGroup——>...——>View

    onTouchListener,onTouchEvent和onClick的优先级别 onTouchListener—–>onTouchEvent—>onclickonTouchListener >>> onTouchEvent >>> setOnLongClickListener >>> OnClickListerner总结 onTouch的优先级高于onClick控件被点击时,onTouch返回false—>dispatchTouchEvent方法返回false—>执行onTouchEvent—>在performClick方法里回调onClickonTouch返回true—>dispatchTouchEvent方法返回true—>不执行onTouchEvent,显然onClick方法也不会被调用参考https://juejin.im/entry/58df5b33570c35005798493c面试口述 onTouchListener 的优先级要高于onTouchEvent ,若onTouchListener返回的是true onTouchEvent 就不执行了View中为什么没有onInterceptTouchEvent事件拦截方法? View最为事件传递的最末端,要么消费掉事件,要么不处理进行回传,根本没必要进行事件拦截用伪代码表示ViewGroup的事件分发过程并解释?

    对于一个ViewGroup来说,点击事件产生后,首先会传递给它,这时她的dispatchTouchEvent会被调用,如果这个ViewGroup的onInterceptTouchEvent,方法返回true表示它要拦截当前事件,接着事件就会交给这个ViewGroup处理,即它的onTouchEvent就会被调用;如果这个这个ViewGroup的onInterceptTouchEvent,方法返回false就表示它不拦截当前事件,这时事件就会传递给子元素,接着子元素的dispatchTouchEvent方法就会被调用,如此反复直到事件最终被处理。常见的注意问题 如果事件一直没有被消费,最后会传给Activity,如果Activity也不需要就被抛弃。view事件执行顺序dispatchTouchEvent-> setOnTouchListener的onTouch->onTouchEvent,如果setOnTouchListener返回ture,后续事件onTouchEvent不在执行onClick是在onTouchEvent(event)方法中的,所以onTouch优先于onClick执行如果重写dispatchTouchEvent方法,dispatchTouchEvent无论返回true还是false,事件都不再进行分发, 只有当其返回super.dispatchTouchEvent(ev),才表明其具有向下层分发的愿望。setOnLongClickListener的onLongClick的返回值表示什么? 返回false,长按的话会同时执行onLongClick和onClick;如果setOnLongClickListener返回true,表示事件被消耗,不会继续传递,只执行longClick;requestDisallowInterceptTouchEvent 可以在子元素中干扰父元素的事件分发吗?如果可以,是全部都可以干扰吗? 答:肯定可以,但是down事件干扰不了。简述事件传递的流程 事件都是从Activity.dispatchTouchEvent()开始传递一个事件发生后,首先传递给Activity,然后一层一层往下传,从上往下调用dispatchTouchEvent方法传递事件:activity --> ~~ --> ViewGroup --> View如果事件传递给最下层的View还没有被消费,就会按照反方向回传给Activity,从下往上调用onTouchEvent方法,最后会到Activity的onTouchEvent()函数,如果Activity也没有消费处理事件,这个事件就会被抛弃:dispatchTouchEvent方法用于事件的分发,Android中所有的事件都必须经过这个方法的分发,然后决定是自身消费当前事件还是继续往下分发给子控件处理。返回true表示不继续分发,事件没有被消费。返回false则继续往下分发,如果是ViewGroup则分发给onInterceptTouchEvent进行判断是否拦截该事件。onTouchEvent方法用于事件的处理,返回true表示消费处理当前事件,返回false则不处理,交给子控件进行继续分发。onInterceptTouchEvent是ViewGroup中才有的方法,View中没有,它的作用是负责事件的拦截,返回true的时候表示拦截当前事件,不继续往下分发,交给自身的onTouchEvent进行处理。返回false则不拦截,继续往下传。这是ViewGroup特有的方法,因为ViewGroup中可能还有子View,而在Android中View中是不能再包含子View的上层View既可以直接拦截该事件,自己处理,也可以先询问(分发给)子View,如果子View需要就交给子View处理,如果子View不需要还能继续交给上层View处理。既保证了事件的有序性,又非常的灵活。事件由父View传递给子View,ViewGroup可以通过onInterceptTouchEvent()方法对事件拦截,停止其向子view传递如果View没有对ACTION_DOWN进行消费,之后的其他事件不会传递过来,也就是说ACTION_DOWN必须返回true,之后的事件才会传递进来应用场景 常见的滑动冲突 外部滑动方向和内部滑动方向不一致的场景 ViewPager和Fragment配合使用组成的页面滑动效果。这种冲突的解决方式,一般都是根据水平滑动还是竖直滑动(滑动的距离差)来判断到底是由谁来拦截事件外部滑动方向和内部滑动方向一致的场景 内外两层同时能上下滑动或者能同时左右滑动。这种一般都是根据业务来进行区分。例如 ScrollView 和ListView 滑动的场景滑动事件冲突解决方案 内部拦截法外部拦截法基于上述总结写了一个事件传递的例子 githua地址 https://github.com/yxwandroid/view_analysis.git面试视角 https://www.jianshu.com/p/dc6fabc32996参考 https://www.jianshu.com/p/7cf6eb4ce7a9
    Processed: 0.010, SQL: 9