DialogFragment 侦听器
DialogFragment Listener
我有一个带有侦听器的 DialogFragment,用于单击按钮以调用我的片段中的函数。
当我点击肯定按钮时,我得到 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)
}
}
片段
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
当片段作为该片段的子片段附加时调用,在这种情况下,从不也不需要。
对当前场景使用onAttach(Context context)。对话框片段没有子片段,因此 onAttachFragment
永远不会被调用。
要从父片段初始化侦听器,请使用:
// inside fragment lifecycle methods like onviewcreated etc
listener = getParentFragment() as CreateCollectionDialogListener
解决此问题的最简单方法是在创建对话框时分配侦听器:
when (item.itemId) {
R.id.add -> {
val createDialog = CreateCollectionDialog()
createDialog.listener = this
createDialog.show(fragmentManager!!, "")
return true
}
}
但是请注意,如果 activity 由于配置更改而被销毁并重新创建,这将出现问题。
为了解决这个问题,我将利用“目标片段”的概念:
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)
}
问题似乎出在您的 fragmentManager 上!!
尝试使用 childFragmentManager 打开 DialogFragment。
此外,检查 lateinit 侦听器是否实际初始化。
我有一个带有侦听器的 DialogFragment,用于单击按钮以调用我的片段中的函数。
当我点击肯定按钮时,我得到 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)
}
}
片段
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
当片段作为该片段的子片段附加时调用,在这种情况下,从不也不需要。
对当前场景使用onAttach(Context context)。对话框片段没有子片段,因此 onAttachFragment
永远不会被调用。
要从父片段初始化侦听器,请使用:
// inside fragment lifecycle methods like onviewcreated etc
listener = getParentFragment() as CreateCollectionDialogListener
解决此问题的最简单方法是在创建对话框时分配侦听器:
when (item.itemId) {
R.id.add -> {
val createDialog = CreateCollectionDialog()
createDialog.listener = this
createDialog.show(fragmentManager!!, "")
return true
}
}
但是请注意,如果 activity 由于配置更改而被销毁并重新创建,这将出现问题。
为了解决这个问题,我将利用“目标片段”的概念:
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)
}
问题似乎出在您的 fragmentManager 上!! 尝试使用 childFragmentManager 打开 DialogFragment。
此外,检查 lateinit 侦听器是否实际初始化。