如何检测用户触摸对话框片段之外的区域?

3

当用户触摸对话框片段外部时,我希望执行一些任务。我该如何做?

  • 在我的自定义对话框片段中,有一段代码可以防止在触摸外部时关闭对话框:

    getDialog().setCanceledOnTouchOutside(false);


@PierGiorgioMisley:我想要一个机制来处理用户触摸对话框外部的任何自定义操作,而不仅仅是为了解除。 - huu duy
2个回答

2

那么您需要移除getDialog().setCanceledOnTouchOutside(false);并使用一些反射来利用Window的隐藏方法来决定何时关闭对话框:

最初的回答。

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    return object : Dialog(activity as Context, theme) {
        override fun onTouchEvent(event: MotionEvent): Boolean {
            if (dialogShouldCloseOnTouch(window, context, event)) {
                // do custom logic
                return true
            } else {
                return super.onTouchEvent(event)
            }
        }
    }
}

private fun dialogShouldCloseOnTouch(
    window: Window, 
    context: Context, 
    event: MotionEvent): Boolean {
    val method = window.javaClass.getMethod("shouldCloseOnTouch", Context::class.java, MotionEvent::class.java)
    return method.invoke(window, context, event) as Boolean
}

@DYS,在一些设备上无法正常工作。错误信息:“Caused by: java.lang.NoSuchMethodException: com.android.internal.policy.PhoneWindow.shouldCloseOnTouch”。 - Gary Chen
@XueQing,你能告诉我这些设备的Android版本吗? - DYS
@DYS,你的代码在模拟器上运行良好。但是由于这个错误,我无法使用这个逻辑。我的手机安装的是Android 10版本。 - Gary Chen
1
@XueQing 可能是这样。 在这种情况下,您可以尝试将“Window.shouldCloseOnTouch”复制粘贴到您的“Fragment”中。 - DYS

0
public class MyActivity extends Activity {

 @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Make us non-modal, so that others can receive touch events.
    getWindow().setFlags(LayoutParams.FLAG_NOT_TOUCH_MODAL, LayoutParams.FLAG_NOT_TOUCH_MODAL);

    // ...but notify us that it happened.
    getWindow().setFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);

    // Note that flag changes must happen *before* the content view is set.
    setContentView(R.layout.my_dialog_view);
  }

  @Override
  public boolean onTouchEvent(MotionEvent event) {
    // If we've received a touch notification that the user has touched
    // outside the app, finish the activity.
    if (MotionEvent.ACTION_OUTSIDE == event.getAction()) {
      //outside touch event
      return true;
    }

    // Delegate everything else to Activity.
    return super.onTouchEvent(event);
  }
}

参考:在这里看第二个答案。

P.S. 在问题中,他说他有一个带有对话框主题的活动


1
问题是针对对话框片段而不是活动。 - Ravjit Singh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接