DialogFragment 监听器
Posted
技术标签:
【中文标题】DialogFragment 监听器【英文标题】:DialogFragment Listener 【发布时间】: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)
【问题讨论】:
【参考方案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 监听器是否真的被初始化了。
【讨论】:
以上是关于DialogFragment 监听器的主要内容,如果未能解决你的问题,请参考以下文章
DialogFragment是从Activity还是Fragment打开的?