Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/183.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 在对话框外单击时如何触发事件_Android_Android Dialog - Fatal编程技术网

Android 在对话框外单击时如何触发事件

Android 在对话框外单击时如何触发事件,android,android-dialog,Android,Android Dialog,我想知道如何解决我遇到的问题 我有一个在活动中弹出的对话框。对话框没有覆盖整个屏幕,因此活动中的按钮仍然显示。当使用dialog.setCanceledOnTouchOut(true)在对话框边界之外有一个触摸时,我可以轻松地关闭对话框 但是,我想做的是,如果单击超出对话框的范围,则触发一个事件(例如,如果有人触摸主活动上的按钮,则应关闭对话框并同时触发该事件)。它对我有效 Window window = dialog.getWindow(); window.se

我想知道如何解决我遇到的问题

我有一个在活动中弹出的对话框。对话框没有覆盖整个屏幕,因此活动中的按钮仍然显示。当使用
dialog.setCanceledOnTouchOut(true)在对话框边界之外有一个触摸时,我可以轻松地关闭对话框

但是,我想做的是,如果单击超出对话框的范围,则触发一个事件(例如,如果有人触摸主活动上的按钮,则应关闭对话框并同时触发该事件)。

它对我有效

        Window window = dialog.getWindow();
        window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
                WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
        window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);

        dialog.show();

对话框时,查看此

。将取消设置为外部(true)然后您只需像这样重写
onCancel()

dialog.setOnCancelListener(
        new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                //When you touch outside of dialog bounds, 
                //the dialog gets canceled and this method executes.
            }
        }
);
onCancel()
方法中键入代码,以便在取消对话框时运行。

当在对话框外单击时,可以使用触发事件:

dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
    @Override
    public void onCancel(DialogInterface dialog) {
        yourFunction();
    }
});

如果您在自定义对话框类中,并且希望捕获“单击外部”事件-覆盖取消()。如果希望捕获“对话框已关闭”事件,请覆盖Disclose()。 我建议在super.disclose()之前插入逻辑。科特林示例:

override fun dismiss() {
    Utils.hideKeyboard(mContext, window)
    super.dismiss()
}

DialogFragment
中,您可以使用
AlertDialog
和以下答案:


使用“后退”按钮命令返回上一屏幕

在扩展DialogFragment的类中使用重写方法onCancel

@Override
    public void onCancel(@NonNull DialogInterface dialog)
    {
        super.onCancel(dialog);
        getParentFragment().getActivity().onBackPressed();
    }

其网址为
com.google.android.material.bottomsheet.BottomSheetDialog

> // We treat the CoordinatorLayout as outside the dialog though it is technically inside
>     coordinator
>         .findViewById(R.id.touch_outside)
>         .setOnClickListener(
>             new View.OnClickListener() {
>               @Override
>               public void onClick(View view) {
>                 if (cancelable && isShowing() && shouldWindowCloseOnTouchOutside()) {
>                   cancel();
>                 }
>               }
>             });
因此,您可以在您的对话框中覆盖ClickListener

class MyBottomDialogFragment : BottomSheetDialogFragment(){
 override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val dialog = object : BottomSheetDialog(activity as Context, theme) {
            private var isDialogCancelable: Boolean = false
            private var isDialogCancelableOnTouchOutside: Boolean = false

            override fun onBackPressed() {
                handleBackPressed(this)
            }

            override fun setContentView(layoutResId: Int) {
                super.setContentView(layoutResId)
                setupTouchOutside()
            }

            override fun setContentView(view: View?) {
                super.setContentView(view)
                setupTouchOutside()
            }

            override fun setContentView(view: View?, params: ViewGroup.LayoutParams?) {
                super.setContentView(view, params)
                setupTouchOutside()
            }

            private fun setupTouchOutside() {
                val coordinator = findViewById<View>(com.google.android.material.R.id.coordinator) as CoordinatorLayout
                // We treat the CoordinatorLayout as outside the dialog though it is technically inside
                coordinator
                    .findViewById<View>(com.google.android.material.R.id.touch_outside)
                    .setOnClickListener {
                        if (isDialogCancelable && isShowing && isDialogCancelableOnTouchOutside) {
                            handleTouchOutside(this)
                        }
                    }
            }


            override fun setCancelable(cancelable: Boolean) {
                super.setCancelable(cancelable)
                isDialogCancelable = cancelable
            }

            override fun setCanceledOnTouchOutside(cancel: Boolean) {
                super.setCanceledOnTouchOutside(cancel)
                isDialogCancelableOnTouchOutside = cancel
            }
        }
        dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
        dialog.setCanceledOnTouchOutside(true)
        return dialog
    }

  protected open fun handleBackPressed(dialog: BottomSheetDialog) {
        /* do what you want but after that call dialog.cancel() or dialog.dismiss() */
    }

    protected open fun handleTouchOutside(dialog: BottomSheetDialog) {
        /* do what you want but after that call dialog.cancel() or dialog.dismiss() */        
    }
}
类MyBottomDialogFragment:BottomSheetDialogFragment(){
重写FunonCreateDialog(savedInstanceState:Bundle?:对话框){
val dialog=object:BottomSheetDialog(活动作为上下文、主题){
私有变量isDialogCancelable:Boolean=false
私有变量isDialogCancelableOnTouchOutside:Boolean=false
重写函数onBackPressed(){
把手压住了(这个)
}
覆盖有趣的setContentView(layoutResId:Int){
super.setContentView(layoutResId)
setupTouchOutside()
}
覆盖内容视图(视图:视图?){
super.setContentView(视图)
setupTouchOutside()
}
覆盖有趣的setContentView(视图:view?,参数:ViewGroup.LayoutParams?){
super.setContentView(视图,参数)
setupTouchOutside()
}
私人娱乐场所(户外){
val coordinator=findViewById(com.google.android.material.R.id.coordinator)作为协调人布局
//我们将CoordinatorLayout视为对话框外部,尽管它在技术上是内部的
协调员
.findviewbyd(com.google.android.material.R.id.touch\u外部)
.setOnClickListener{
如果(isDialogCancelable&&isShowing&&IsDialogCancelableOnTouchOut){
手槽外侧(此)
}
}
}
覆盖乐趣可设置可取消(可取消:布尔值){
super.setCancelable(可取消)
isDialogCancelable=可取消
}
覆盖fun setCanceledOnTouchOutside(取消:布尔值){
super.setCanceledOnTouchOut(取消)
isDialogCancelableOnTouchOutside=取消
}
}
dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT\u INPUT\u ADJUST\u RESIZE)
对话框。setCanceledOnTouchOutside(真)
返回对话框
}
受保护的开放式趣味把手已按下(对话框:底部挡板对话框){
/*在调用dialog.cancel()或dialog.discouse()之后,执行您想要的操作*/
}
受保护的开放式趣味手柄(对话框:底部挡板对话框){
/*在调用dialog.cancel()或dialog.discouse()之后,执行您想要的操作*/
}
}

我发现所有其他答案都相当冗长和复杂,因此我采用了这种方法:

第1步: 为要为其生成单击外部事件的元素的外部容器创建ID

在我的例子中,它是一个线性布局,我将其id指定为“outsideContainer”

第二步: 为外部容器设置一个onTouchListener,它将作为内部元素的外部点击事件

outsideContainer.setOnTouchListener(new View.OnTouchListener() {
                                            @Override
                                            public boolean onTouch(View v, MotionEvent event) {
                                                // perform your intended action for click outside here
                                                Toast.makeText(YourActivity.this, "Clicked outside!", Toast.LENGTH_SHORT).show();
                                                return false;
                                            }
                                        }
    );

通常的解决方案是使对话框成为模态。你为什么不想那样做?谢谢。我试图在我的主要活动中显示一个webview(在对话框中),以便它保持应用程序的外观。最佳答案。。两年后,我也引用了同样的答案…无法再次投票:)覆盖Dialog.onCancel(…)有效,但Dialog.setOnCancelListener(…)对我无效。你说什么时候?-<代码>当dialog.setCanceledOnTouchOutside(真)时这是默认行为…这应该是公认的答案!!多好的回答啊,这很有效。只是我可以滚动列表视图,但不能点击它。这不是一个很好的答案。也就是说,它不是泛型的。我必须写新的行为,而不是注意旧的行为。在我制作通用对话框实用程序的情况下,我无法知道对话框背后是什么。@JaveneCPPMcGowan您可以使用从自定义对话框到视图的回调。正如我所说的,这是一种新的行为。@SilverTech为什么建议在super.disclose()之前插入逻辑?另一种情况是,hideKeyboard函数有时只能按预期工作。它与@WillNeithan answer()有什么区别?为什么建议在super.onDismiss()之前插入逻辑?那么为什么super.onCancel()之后是逻辑呢?@AJW,我打开了
对话框片段
onCancel
为空,而
onDismiss
包含一些关于dismissing(clo)的逻辑
class MyBottomDialogFragment : BottomSheetDialogFragment(){
 override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val dialog = object : BottomSheetDialog(activity as Context, theme) {
            private var isDialogCancelable: Boolean = false
            private var isDialogCancelableOnTouchOutside: Boolean = false

            override fun onBackPressed() {
                handleBackPressed(this)
            }

            override fun setContentView(layoutResId: Int) {
                super.setContentView(layoutResId)
                setupTouchOutside()
            }

            override fun setContentView(view: View?) {
                super.setContentView(view)
                setupTouchOutside()
            }

            override fun setContentView(view: View?, params: ViewGroup.LayoutParams?) {
                super.setContentView(view, params)
                setupTouchOutside()
            }

            private fun setupTouchOutside() {
                val coordinator = findViewById<View>(com.google.android.material.R.id.coordinator) as CoordinatorLayout
                // We treat the CoordinatorLayout as outside the dialog though it is technically inside
                coordinator
                    .findViewById<View>(com.google.android.material.R.id.touch_outside)
                    .setOnClickListener {
                        if (isDialogCancelable && isShowing && isDialogCancelableOnTouchOutside) {
                            handleTouchOutside(this)
                        }
                    }
            }


            override fun setCancelable(cancelable: Boolean) {
                super.setCancelable(cancelable)
                isDialogCancelable = cancelable
            }

            override fun setCanceledOnTouchOutside(cancel: Boolean) {
                super.setCanceledOnTouchOutside(cancel)
                isDialogCancelableOnTouchOutside = cancel
            }
        }
        dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
        dialog.setCanceledOnTouchOutside(true)
        return dialog
    }

  protected open fun handleBackPressed(dialog: BottomSheetDialog) {
        /* do what you want but after that call dialog.cancel() or dialog.dismiss() */
    }

    protected open fun handleTouchOutside(dialog: BottomSheetDialog) {
        /* do what you want but after that call dialog.cancel() or dialog.dismiss() */        
    }
}
outsideContainer.setOnTouchListener(new View.OnTouchListener() {
                                            @Override
                                            public boolean onTouch(View v, MotionEvent event) {
                                                // perform your intended action for click outside here
                                                Toast.makeText(YourActivity.this, "Clicked outside!", Toast.LENGTH_SHORT).show();
                                                return false;
                                            }
                                        }
    );