简体   繁体   English

DialogFragment 监听器

[英]DialogFragment Listener

I have a DialogFragment with a listener for when a button gets clicked to call a function in my fragment.我有一个带有监听器的 DialogFragment,用于单击按钮以在我的片段中调用 function。

I am getting lateinit property listener has not been initialized when I click the positive button.当我单击肯定按钮时,我得到lateinit property listener has not been initialized

DialogFragment对话片段

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)
    }
}

Fragment分段

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)
    }
}

onAttachFragment is called when a fragment is attached as a child of this fragment, which in this case, never and not required. onAttachFragment当一个片段作为这个片段的一个孩子被附加时被调用,在这种情况下,从不也不需要。

Use onAttach(Context context) for current scenario.对当前场景使用onAttach(Context context) Dialog fragment has no child so onAttachFragment will never be called.对话框片段没有子片段,因此永远不会调用onAttachFragment

To initialize the listener from the parent fragment, use:要从父片段初始化侦听器,请使用:

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

The simplest way to solve this problem would be to assign the listener at the time you create the dialog:解决此问题的最简单方法是在创建对话框时分配侦听器:

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

However, note that this will have problems if the activity is destroyed and recreated due to a configuration change.但是,请注意,如果活动因配置更改而被销毁并重新创建,则会出现问题。

To solve that, I would leverage the concept of "target fragments":为了解决这个问题,我将利用“目标片段”的概念:

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

And now, in your other fragment, instead of having a listener field, you can just cast the targetFragment property:现在,在您的其他片段中,您可以只targetFragment属性,而不是具有listener器字段:

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

Problem seems to be with your fragmentManager.!问题似乎出在您的 fragmentManager 上。! Try using childFragmentManager to open the DialogFragment.尝试使用 childFragmentManager 打开 DialogFragment。

Also, check if lateinit listener is actually initialized or not.另外,检查 lateinit 侦听器是否实际初始化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM