Android 动态代理禁用LongClick

78 阅读1分钟

Android 动态代理禁用LongClick

本文主要讲下项目中遇到的禁止longCLick事件需求的实现.

    public static void hookView(final View view) {
        try {
            Log.d(TAG, "forbidden long click:" + view);
            // 获取View的ListenerInfo对象
            Method getListenerInfo = View.class.getDeclaredMethod("getListenerInfo");
            getListenerInfo.setAccessible(true);
            Object liObj = getListenerInfo.invoke(view);

            // 获取原有的OnClickListener和OnLongClickListener
            Class<?> listenerInfoClz = Class.forName("android.view.View$ListenerInfo");
            Field onClickListenerField = listenerInfoClz.getDeclaredField("mOnClickListener");
            Field onLongClickListenerField = listenerInfoClz.getDeclaredField("mOnLongClickListener");
            onClickListenerField.setAccessible(true);
            onLongClickListenerField.setAccessible(true);
            final View.OnClickListener onClickListener = (View.OnClickListener) onClickListenerField.get(liObj);
            View.OnLongClickListener onLongClickListener = (View.OnLongClickListener) onLongClickListenerField.get(liObj);
            Log.d(TAG, "forbidden long click:" + (onLongClickListener == null) + (onClickListener == null));
            // hook OnLongClickListener
            View.OnLongClickListener newOnLongClickListener = new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    // 禁用长按事件
                    isLongClick = true;
                    // 恢复长按事件
                    isLongClick = false;
                    // 返回true表示已经处理了长按事件
                    Log.d(TAG, "forbidden longclick:" + view);
                    return true;
                }
            };
            onLongClickListenerField.set(liObj, newOnLongClickListener);

            // hook OnClickListener
            View.OnClickListener newOnClickListener = new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // 判断是否是长按事件
                    if (!isLongClick) {
                        // 执行原有的点击事件
                        if (onClickListener != null) {
                            onClickListener.onClick(v);
                        }
                    }
                }
            };
            onClickListenerField.set(liObj, newOnClickListener);
        } catch (Exception e) {
             Log.e(TAG, "hookView: ", e);
        }
    }