Android解决OnClick和OnTouch冲突

        在商显悬浮按钮开发过程中遇到的问题,悬浮按钮即要实现随手指移动而移动(onTouch),也要实现点击事件(onClick事件),这里会遇到一个问题,在onTouch方法return false的时候,在滑动过程中抬起的时候会触发 MotionEvent.ACTION_UP 事件,同时也会触发onClick事件,如果onTouch方法return true,则view的onClick事件不会执行。
        通过查看View的源码,View的listener都存在一个静态内部类里面,

 static class ListenerInfo {
        /**
         * Listener used to dispatch focus change events.
         * This field should be made private, so it is hidden from the SDK.
         * {@hide}
         */
        protected OnFocusChangeListener mOnFocusChangeListener;

        /**
         * Listeners for layout change events.
         */
        private ArrayList<OnLayoutChangeListener> mOnLayoutChangeListeners;

        protected OnScrollChangeListener mOnScrollChangeListener;

        /**
         * Listeners for attach events.
         */
        private CopyOnWriteArrayList<OnAttachStateChangeListener> mOnAttachStateChangeListeners;

        /**
         * Listener used to dispatch click events.
         * This field should be made private, so it is hidden from the SDK.
         * {@hide}
         */
        public OnClickListener mOnClickListener;

        /**
         * Listener used to dispatch long click events.
         * This field should be made private, so it is hidden from the SDK.
         * {@hide}
         */
        protected OnLongClickListener mOnLongClickListener;

        /**
         * Listener used to dispatch context click events. This field should be made private, so it
         * is hidden from the SDK.
         * {@hide}
         */
        protected OnContextClickListener mOnContextClickListener;

        /**
         * Listener used to build the context menu.
         * This field should be made private, so it is hidden from the SDK.
         * {@hide}
         */
        protected OnCreateContextMenuListener mOnCreateContextMenuListener;

        private OnKeyListener mOnKeyListener;

        private OnTouchListener mOnTouchListener;

        private OnHoverListener mOnHoverListener;

        private OnGenericMotionListener mOnGenericMotionListener;

        private OnDragListener mOnDragListener;

        private OnSystemUiVisibilityChangeListener mOnSystemUiVisibilityChangeListener;

        OnApplyWindowInsetsListener mOnApplyWindowInsetsListener;
    }

    ListenerInfo mListenerInfo;

通过反射获取mListenerInfo实例,再获取mListenerInfo里面的mOnClickListener,最后调用mOnClickListener.onClick()方法即可,修改后的onTouch代码如下
 

 button.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                switch (motionEvent.getAction()) {
                    case MotionEvent.ACTION_DOWN: {
                        Log.i("mandroid.cn", "button按下");
                        //记录按下时的位置
                        x = motionEvent.getRawX();
                        y = motionEvent.getRawY();
                        break;
                    }
                    case MotionEvent.ACTION_MOVE: {
                        Log.i("mandroid.cn", "button移动");
                        break;
                    }
                    case MotionEvent.ACTION_UP: {
                        //检测移动的距离,如果很微小可以认为是点击事件
                        if (Math.abs(motionEvent.getRawX() - x) < 10 && Math.abs(motionEvent.getRawY() - y) < 10) {
                            try {
                                Field field = View.class.getDeclaredField("mListenerInfo");
                                field.setAccessible(true);
                                Object object = field.get(view);
                                field = object.getClass().getDeclaredField("mOnClickListener");
                                field.setAccessible(true);
                                object = field.get(object);
                                if (object != null && object instanceof View.OnClickListener) {
                                    ((View.OnClickListener) object).onClick(view);
                                }
                            } catch (Exception e) {

                            }
                        } else {
                            Log.i("mandroid.cn", "button已移动");
                        }
                        break;
                    }
                }
                return true;
            }
        });
发布了14 篇原创文章 · 获赞 16 · 访问量 3423

猜你喜欢

转载自blog.csdn.net/weixin_35649059/article/details/103259822