【问题标题】:DialogFragment ListenerDialogFragment 监听器
【发布时间】:2020-11-10 01:25:53
【问题描述】:

我有一个带有监听器的 DialogFragment,当单击按钮以调用片段中的函数时。

当我点击肯定按钮时,我收到lateinit property listener has not been initialized

对话框片段

class CreateCollectionDialog: DialogFragment() {
    lateinit var listener: CreateCollectionDialogListener

    interface CreateCollectionDialogListener {
        fun onDialogPositiveClick(dialog: DialogFragment, collectionName: String)
        // fun onDialogNegativeClick(dialog: DialogFragment)
    }

    override fun onAttachFragment(childFragment: Fragment) {
        println("onAttachFragment")
        super.onAttachFragment(childFragment)
        listener = context as CreateCollectionDialogListener
        println(listener)
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        return activity?.let {
            val builder = AlertDialog.Builder(it)
            val inflater = requireActivity().layoutInflater
            builder.setView(inflater.inflate(R.layout.dialog_collection, null))
                .setPositiveButton("Create", DialogInterface.OnClickListener { dialog, id ->
                    // Create new collection
                    var newCollectionName = view?.findViewById<EditText>(R.id.newCollectionName)?.text.toString()
                    if (!newCollectionName.equals("") && newCollectionName != null) {
                        listener.onDialogPositiveClick(this, newCollectionName)
                    }
                })
                .setNegativeButton("Cancel", DialogInterface.OnClickListener { dialog, id ->
                    // User canceled dialog
                    // listener.onDialogNegativeClick(this)
                })
            builder.create()
        }?: throw IllegalStateException("Activity cannot be null")
    }

    override fun onStart() {
        super.onStart()
        val positive: Button = (dialog as AlertDialog?)!!.getButton(AlertDialog.BUTTON_POSITIVE)
        positive.setTextColor(resources.getColor(R.color.topColor))

        val negative: Button = (dialog as AlertDialog?)!!.getButton(AlertDialog.BUTTON_NEGATIVE)
        negative.setTextColor(Color.RED)
    }
}

片段

class CollectionsFragment: Fragment(), CreateCollectionDialog.CreateCollectionDialogListener {
     override fun onOptionsItemSelected(item: MenuItem): Boolean {

        when (item.itemId) {
            R.id.add -> {
                val createDialog = CreateCollectionDialog()
                createDialog.show(fragmentManager!!, "")
                return true
            }
        }
        return false
    }

    override fun onDialogPositiveClick(dialog: DialogFragment, collectionName: String) {
        addNewCollection(collectionName)
    }
}

【问题讨论】:

    标签: android kotlin dialogfragment


    【解决方案1】:

    onAttachFragment 在附加片段作为该片段的子片段时调用,在这种情况下,从不也不需要这样做。

    在当前场景中使用onAttach(Context context)。对话框片段没有子级,因此永远不会调用 onAttachFragment

    要从父片段初始化监听器,使用:

    // inside fragment lifecycle methods like onviewcreated etc
    listener = getParentFragment() as CreateCollectionDialogListener
    

    【讨论】:

    • 但我正试图通过我的片段而不是我的主要活动来做到这一点。
    • @raginggoat 那么你应该使用onAttach(Context context)?
    • 我试过了,但它给出了一个错误,说我的主要活动不能转换为 CreateCollectionDialog$CreateCollectionDialogListener。
    • 这是有道理的,因为我使用的是我的片段而不是我的主要活动。
    • 是的,我正要这么说,试试listener = getParentFragment() as CreateCollectionDialogListener 或在MainActivity 上实现lister
    【解决方案2】:

    解决此问题的最简单方法是在创建对话框时分配侦听器:

    when (item.itemId) {
        R.id.add -> {
            val createDialog = CreateCollectionDialog()
            createDialog.listener = this
            createDialog.show(fragmentManager!!, "")
            return true
        }
    }
    

    但是,请注意,如果活动因配置更改而被销毁并重新创建,则会出现问题。

    为了解决这个问题,我会利用“目标片段”的概念:

    when (item.itemId) {
        R.id.add -> {
            val createDialog = CreateCollectionDialog()
            createDialog.setTargetFragment(this, 0)
            createDialog.show(fragmentManager!!, "")
            return true
        }
    }
    

    现在,在您的另一个片段中,您可以只转换 targetFragment 属性,而不是 listener 字段:

    if (!newCollectionName.equals("") && newCollectionName != null) {
        val listener = targetFragment as CreateCollectionDialogListener
        listener.onDialogPositiveClick(this, newCollectionName)
    }
    

    【讨论】:

      【解决方案3】:

      问题似乎出在您的 fragmentManager 上!! 尝试使用 childFragmentManager 打开 DialogFragment。

      另外,检查 lateinit 监听器是否真的被初始化了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-14
        • 2013-12-24
        • 2014-12-13
        • 2014-02-21
        相关资源
        最近更新 更多