onUserInteraction不DialogPreference工作(onUserInterac

2019-07-19 18:06发布

预计onUserInteraction被调用任何用户交互。 它工作正常PreferenceActivity 。 然而,当DialogPreference是弹出, onUserInteraction不再被称为甚至有用户交互,如触摸事件。

看来, DialogPreference不是唯一的案例。 每当Dialog显示,它不报告的用户交互活动。

但是,我能做些什么,如果我真的需要它。 谢谢。

Answer 1:

据我所知, onUserInteraction()根本就不是在用户与对话交互调用(甚至从开始Activity中,要监控相互作用)。

有两种解决方案,我知道是:

  • 子类Dialog / DialogPreference类和重写dispatchTouchEvent()

  • 实施Window.Callback接口,并将其设置为Dialog发出小号窗口回调:

     dialog.getWindow().setCallback(callbackImplementation); 

    注:此实现应该通过调用适当的对话方式处理所有接收到的事件或处理以自己的方式发生的事件(例如,通过手动调用onUserInteraction()

编辑

你有几个方法来获得Activity从定制PreferenceDialog实例。

  1. 调用DialogPreference.getPreferenceManager()返回方法PreferenceManager 。 它有一个getActivity()方法, 但它的包私人所以你必须把你的自定义DialogPreferenceandroid.preference包进行访问。

  2. PreferenceActivity.onCreate()充气后的喜好,使用findPreference()找到您的自定义DialogPreference的关键。 然后将它转换为你的自定义类,并设置活动this通过访问。

我会去的第二个选项。



Answer 2:

下面是一个完整的解决方案DialogFragment ,这将触发活动的onUserInteraction()上的触摸,并保留默认回调的行为:

public abstract class BaseDialogFragment extends DialogFragment {

    @Override
    public void onActivityCreated(final Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        final Window window = getDialog().getWindow();
        if (window != null) {
            window.setCallback(new UserInteractionAwareCallback(window.getCallback(), getActivity()));
        }
    }
}

这里是回调本身:

public class UserInteractionAwareCallback implements Window.Callback {

    private final Window.Callback originalCallback;
    private final Activity activity;

    public UserInteractionAwareCallback(final Window.Callback originalCallback, final Activity activity) {
        this.originalCallback = originalCallback;
        this.activity = activity;
    }

    @Override
    public boolean dispatchKeyEvent(final KeyEvent event) {
        return originalCallback.dispatchKeyEvent(event);
    }

    @Override
    public boolean dispatchKeyShortcutEvent(final KeyEvent event) {
        return originalCallback.dispatchKeyShortcutEvent(event);
    }

    @Override
    public boolean dispatchTouchEvent(final MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
            case MotionEvent.ACTION_UP:
                if (activity != null) {
                    activity.onUserInteraction();
                }
                break;
            default:
        }
        return originalCallback.dispatchTouchEvent(event);
    }

    @Override
    public boolean dispatchTrackballEvent(final MotionEvent event) {
        return originalCallback.dispatchTrackballEvent(event);
    }

    @Override
    public boolean dispatchGenericMotionEvent(final MotionEvent event) {
        return originalCallback.dispatchGenericMotionEvent(event);
    }

    @Override
    public boolean dispatchPopulateAccessibilityEvent(final AccessibilityEvent event) {
        return originalCallback.dispatchPopulateAccessibilityEvent(event);
    }

    @Nullable
    @Override
    public View onCreatePanelView(final int featureId) {
        return originalCallback.onCreatePanelView(featureId);
    }

    @Override
    public boolean onCreatePanelMenu(final int featureId, final Menu menu) {
        return originalCallback.onCreatePanelMenu(featureId, menu);
    }

    @Override
    public boolean onPreparePanel(final int featureId, final View view, final Menu menu) {
        return originalCallback.onPreparePanel(featureId, view, menu);
    }

    @Override
    public boolean onMenuOpened(final int featureId, final Menu menu) {
        return originalCallback.onMenuOpened(featureId, menu);
    }

    @Override
    public boolean onMenuItemSelected(final int featureId, final MenuItem item) {
        return originalCallback.onMenuItemSelected(featureId, item);
    }

    @Override
    public void onWindowAttributesChanged(final WindowManager.LayoutParams attrs) {
        originalCallback.onWindowAttributesChanged(attrs);
    }

    @Override
    public void onContentChanged() {
        originalCallback.onContentChanged();
    }

    @Override
    public void onWindowFocusChanged(final boolean hasFocus) {
        originalCallback.onWindowFocusChanged(hasFocus);
    }

    @Override
    public void onAttachedToWindow() {
        originalCallback.onAttachedToWindow();
    }

    @Override
    public void onDetachedFromWindow() {
        originalCallback.onDetachedFromWindow();
    }

    @Override
    public void onPanelClosed(final int featureId, final Menu menu) {
        originalCallback.onPanelClosed(featureId, menu);
    }

    @Override
    public boolean onSearchRequested() {
        return originalCallback.onSearchRequested();
    }

    @TargetApi(Build.VERSION_CODES.M)
    @Override
    public boolean onSearchRequested(final SearchEvent searchEvent) {
        return originalCallback.onSearchRequested(searchEvent);
    }

    @Nullable
    @Override
    public ActionMode onWindowStartingActionMode(final ActionMode.Callback callback) {
        return originalCallback.onWindowStartingActionMode(callback);
    }

    @TargetApi(Build.VERSION_CODES.M)
    @Nullable
    @Override
    public ActionMode onWindowStartingActionMode(final ActionMode.Callback callback, final int type) {
        return originalCallback.onWindowStartingActionMode(callback, type);
    }

    @Override
    public void onActionModeStarted(final ActionMode mode) {
        originalCallback.onActionModeStarted(mode);
    }

    @Override
    public void onActionModeFinished(final ActionMode mode) {
        originalCallback.onActionModeFinished(mode);
    }
}


文章来源: onUserInteraction not working in DialogPreference