首页 > 解决方案 > Android:无法实例化对话框侦听器

问题描述

我按照官方文档在我的应用程序上创建了一个对话框提示。它正在工作,但是当我添加侦听器来处理来自调用片段的数据时,我遇到了崩溃。它不能将上下文实例化为侦听器。这是我的一些代码:

调用片段:

class ConfigWifiFragment : Fragment(), BleManagerListener, WifiPasswordDialogFragment.NoticeDialogListener {

    companion object {
        fun newInstance() = ConfigWifiFragment()
    }

    private var _binding: FragmentConfigWifiBinding? = null
    // This property is only valid between onCreateView and
    // onDestroyView.
    private val binding get() = _binding!!

    private var dialogPassword = WifiPasswordDialogFragment()

    //... some code

    private fun connectToWifiNetwork(ssid: String)
    {
        Log.i("Connection", ssid)
        Log.i("Context", context.toString())
        getFragmentManager()?.let { dialogPassword.show(it, "passwordWifi") }
    }

    override fun onDialogPositiveClick(dialog: DialogFragment) {
        TODO("Not yet implemented")
        Log.i("ConfigWifi", dialog.config_wifi_password.text.toString())
    }

    override fun onDialogNegativeClick(dialog: DialogFragment) {
        TODO("Not yet implemented")
        Log.i("ConfigWifi", "not ok")
    }
}

对话框:

import android.app.AlertDialog
import android.app.Dialog
import android.content.Context
import android.content.DialogInterface
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.DialogFragment

class WifiPasswordDialogFragment : DialogFragment() {
    internal lateinit var listener: NoticeDialogListener

    interface NoticeDialogListener {
        fun onDialogPositiveClick(dialog: DialogFragment)
        fun onDialogNegativeClick(dialog: DialogFragment)
    }

    override fun onAttach(context: Context) {
        super.onAttach(context)
        // Verify that the host activity implements the callback interface

        try {
            // Instantiate the NoticeDialogListener so we can send events to the host
            listener = context as NoticeDialogListener // CRASH
        } catch (e: ClassCastException) {
            // The activity doesn't implement the interface, throw exception
            throw ClassCastException((context.toString() +
                    " must implement NoticeDialogListener"))
        }
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        return activity?.let {
            val builder = AlertDialog.Builder(it)
            // Get the layout inflater
            val inflater = requireActivity().layoutInflater;

            // Inflate and set the layout for the dialog
            // Pass null as the parent view because its going in the dialog layout
            builder.setView(inflater.inflate(R.layout.dialog_wifi_password, null))
                // Add action buttons
                .setPositiveButton(R.string.validation,
                    DialogInterface.OnClickListener { dialog, id ->
                        // sign in the user ...
                        Log.i("dialog", "ok")
                        listener.onDialogPositiveClick(this)
                    })
                .setNegativeButton(R.string.cancel,
                    DialogInterface.OnClickListener { dialog, id ->
                        //getDialog().cancel()
                        Log.i("dialog", "Cancel")
                        listener.onDialogNegativeClick(this)
                    })
            builder.create()
        } ?: throw IllegalStateException("Activity cannot be null")
    }
}

该行中的代码崩溃: ,即使它在调用片段中实现(然后抛出异常)listener = context as NoticeDialogListener,它也无法获取上下文。NoticeDialogListener在显示对话提示之前,我检查了上下文的 ID,以及里面的 ID;一样的。

我的代码和示例之间的唯一区别是我使用的是 aFragment而不是FragmentActivity. 在我的情况下,我怎样才能使我的代码工作?

标签: androidkotlinandroid-fragmentslistener

解决方案


我找到了一个解决方案,我不知道这是否是更优雅的方式,但就是这样:

第一:我删除了onAttachDialogFragment 中的函数

第二:我创建了一个设置监听器的方法:

fun setListener(_listener : WifiPasswordDialogListener)
    {
        listener = _listener
    }

第三:我在方法之前调用了该show方法:

private fun connectToWifiNetwork(ssid: String)
    {
        Log.i("Connection", ssid)
        Log.i("Context", context.toString())
        dialogPassword.setListener(this)
        getFragmentManager()?.let { dialogPassword.show(it, "passwordWifi") }
    }

我现在可以像这样从调用片段访问 DialogBox 的数据:

override fun onDialogPositiveClick(dialog: DialogFragment) {
        Log.i("ConfigWifi", dialog.dialog?.config_wifi_password?.text.toString())
    }

推荐阅读