MTK SystemUI/系统深度定制修改与编辑------细数那些你所不知道的事件分发处理机制 dispatchTouchEvent

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jspping/article/details/50234691

中午休息的时间,腾出一点时间来写写自己最爱之一的一件事情,就是写博客,不要小看写博客这样的不起眼的小事,多写博客

及总结开发中遇到的问题和解决问题的心得,更有助于你加深对这个问题的印象解决方法和认知,下一次遇到这种问题,那就

不再是问题了!个人感觉,从我毕业到参加工作到现在,感觉技术提升了很大一个层次无论是上层还是底层都或多或少能轻松的

进行开发和新知识的学习,而写博客就是我提升的方法之一,欢迎广大开发者也加入这个行列,一起成长!


前不久我老大叫我看下SystemUI,以后可能用户什么的需要定制这些东西或者推翻改掉,我就花时间看了几天,然后给了一些个

务,把 MTK 原生的SystemUI下拉菜单给去掉,加上自己的导航栏,在修改一些定制的东西,然后我就开始着手修改这些东

西,在处理一个 onTouchEvent 的时候,我发现我把事件屏蔽掉,但是下来栏目依旧还是被执行了事件,我就顺着源码往上找,

理清他们的事件机制和处理,下面看看对应关系


class:FrameWorks/base/packages/SystemUI/com.android.systemui.statusbar.phone.StatusBarWindowView

extends:StatusBarWindowView extends FrameLayout

method: dispatchTouchEvent(MotionEvent ev)


其中 dispatchTouchEvent(MotionEvent ev) 就是我们需要注意的函数,我找到StatusBarWindowView 的 父类FrameLayout,

现 FrameLayout 根本没有这个方法,于是继续究其根源,找到了ViewGroup,ViewGroup extends View ,这个View就是所

有Widget 的父类包括被拓展的 ViewGroup 所有 Android 的 View 拓展性是超强的!


子控件需要注册Touch事件,在其父类首先被 dispatchTouchEvent(MotionEvent ev)  注册提交并且在里面做相应处理和判断,

不过这些都是系统源码处理好了的 return false 表示事件没有被消费,继续下发到子控件,true 则表示已被消费,不会被下发,

就比如:我在Activity 里面写了一个触摸事件,它会在 Activity 的 dispatchTouchEvent(MotionEvent ev) 注册和下发给子控

制,在 ViewGroup 里面有这样一个函数可以拦截事件的下发 ,即 onInterceptTouchEvent(ev) 该函数返回

super.onInterceptTouchEvent(ev); 即 false ,表示不拦截,一般默认不拦截,那么,现在我就有两种最好的方案来解决这个下来问题了,从

源头来解决这个问题,简单粗暴

方案一:取消 ViewGroup 子 View 的事件注册,从根本上截断 StatusBar 的 Touch 事件

方案二:在 onInterceptTouchEvent(ev) 拦截,即 return true ,自己做响应事件,即返回true,不做任何处理即可

我选择了方案一,因为在诸多客户的定制中,可能涉及的有些大相径庭,那么我们就可以做兼容模式,于是乎我在事件注册的地方启用了标志位,

来区分是否定制下拉的菜单栏显示或不现实,也不影响后续的改动


下面贴出这些 method:

    /**
     * FrameWorks/base/packages/SystemUI/com.android.systemui.statusbar.phone.StatusBarWindowView
     * method dispatchTouchEvent(MotionEvent ev)
     * @param ev Touch MotionEvent
     * super.dispatchTouchEvent(ev) return true can commit listener 
     * @author Engineer.Jsp
     * */
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (mBrightnessMirror != null && mBrightnessMirror.getVisibility() == VISIBLE) {
            // Disallow new pointers while the brightness mirror is visible. This is so that you
            // can't touch anything other than the brightness slider while the mirror is showing
            // and the rest of the panel is transparent.
            if (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) {
                return false;
            }
        }
      return isOnTouchScrollShow?super.dispatchTouchEvent(ev):isOnTouchScrollShow;
    }

isOnTouchScrollShow flags 我默认 false 即取消事件的注册

拦截函数的复写:

    /**
     * FrameWorks/base/packages/SystemUI/com.android.systemui.statusbar.phone.StatusBarWindowView
     * method onInterceptTouchEvent(MotionEvent ev)
     * @param ev Touch MotionEvent
     * super.onInterceptTouchEvent(ev) default return false ,if return true can unregister listener 
     * @author Engineer.Jsp
     * */
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
    	return super.onInterceptTouchEvent(ev);
//    	return true; 
    }

处理完之后,linux 下编译之后,达到了我想要的效果,下拉菜单执行下拉没有再显示出来



有需要软件定制的订单软件的可以私信我,我们都可以做,粉丝们也可以宣传和学习,谢谢观博~!再次感谢!

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页