处理对话框片段中的外部单击

Handling Outside Clicks in Dialog Fragment

提问人:Hasan Altay 提问时间:11/15/2023 更新时间:11/15/2023 访问量:54

问:

我希望在点击对话框片段外部时出现一个确认对话框,询问“您确定要退出而不保存吗?当用户按下“是”按钮时,我希望关闭对话框片段。否则,如果他们关闭确认对话框,我希望它关闭,使原始对话框片段保持打开状态。棘手的部分是,在对话框片段外部点击不应关闭片段本身,而应触发确认对话框。我怎样才能做到这一点?这是我的对话片段:

@AndroidEntryPoint
class ConfessAnswerFragment(
    private val onUpdateItem: (position: Int, updatedConfession: Confession) -> Unit,
    private val findItemById: (confessionId: String) -> Int
) : DialogFragment() {

    private lateinit var binding: FragmentConfessAnswerBinding
    private lateinit var navRegister: FragmentNavigation
    private val viewModel: ConfessViewModel by viewModels()
    private var isAnswerButtonEnabled = false
    private var isEditAnswer: Boolean = false
    private var isAnswerFavorited: Boolean = false
    private lateinit var currentUserUid: String
    private lateinit var confessionId: String
    private lateinit var answerDate: String
    private lateinit var dialogHelper: DialogTemplate

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {

        binding = FragmentConfessAnswerBinding.inflate(inflater, container, false)
        navRegister = activity as FragmentNavigation
        setHasOptionsMenu(true)
        confessionId = arguments?.getString("confessionId", "") ?: ""
        currentUserUid = arguments?.getString("currentUserUid", "") ?: ""
        answerDate = arguments?.getString("answerDate", "") ?: ""
        dialogHelper = DialogTemplate(requireContext())

        getConfession(confessionId)

        return binding.root
    }
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        observeGetConfession()
        observeAddAnswer()
        observeFavorite()
        observeDeleteAnswer()
    }
...
android kotlin android-fragments

评论

0赞 ltp 11/15/2023
这不是一个好的做法,在另一个对话上显示一个对话。为什么不直接设置 Dialog.setCancelable(false) 和/或 Dialog.setCanceledOnTouchOutside(false) 呢?

答:

0赞 Faruk Karaca 11/15/2023 #1

将此代码添加到onCreateView

setOutsideTouchListener()
return binding.root

警报对话框和句柄消除的简单示例

private fun showConfirmationDialog() {
    // It will listen for all touches.
    // We do not want it to be triggered when clicking the yes or no buttons in the AlertDialog.
    clearOutSideTouchListener()

    val builder = AlertDialog.Builder(requireContext())
    builder.setMessage("Are you sure you want to exit without saving?")
        .setPositiveButton("Yes") { _, _ ->
            dismiss()
        }
        .setNegativeButton("No") { dialog, _ ->
            dialog.dismiss()

            //We have to activate it again.
            setOutsideTouchListener()
        }

    val dialog = builder.create()
    dialog.setCanceledOnTouchOutside(false)

    dialog.show()
}

外部触摸侦听器

private fun setOutsideTouchListener() {
    val outsideTouchListener = View.OnTouchListener { _, _ ->
        showConfirmationDialog()
        true
    }
    dialog?.window?.decorView?.setOnTouchListener(outsideTouchListener)
}

清晰触摸侦听器

private fun clearOutSideTouchListener() {
    dialog?.window?.decorView?.setOnTouchListener(null)
}

评论

0赞 Hasan Altay 11/15/2023
我把你写的东西应用到我的代码中。在这里,当我在对话框片段内单击时,它会转到“else”部分,但当我单击外部时,它不会转到“if”部分。我无法捕捉到外部点击。
0赞 Faruk Karaca 11/15/2023
实际上,我等待通过覆盖 onCancel 来解决它。但是,即使我删除了 onCancel super,当我按下 no 按钮时,我发现它还是被关闭了。.因此,我添加了一个新的解决方案。你能试试吗?
0赞 Hasan Altay 11/15/2023
我还激活了“dialog.setOnCancelListener”中的“setOutsideTouchListener”,删除了“dialog.setCanceledOnTouchOutside(false)”,现在它完全按照我的意愿工作。谢谢你的帮助。