kotlin 如何使用回调函数从Fragment打开DialogFragment?

tjvv9vkg  于 6个月前  发布在  Kotlin
关注(0)|答案(2)|浏览(82)

我想从一个片段打开我的dialogfragment类,并想从dialog片段返回数据。我是一个大学生,有一个示例应用程序,它是从主Activity通过回调实现完成的,但当我尝试从一个片段打开dialog时,它仍然将其定向到主Activity,而不是我打开它的片段。我可以使用回调实现来完成这一点吗?还是必须这样做?还有别的吗
我有一个例子项目的代码,当它从主活动启动时,它就可以工作了。我在网上搜索了一下,发现它也可以用导航参数来完成,但如果可能的话,我想这样做。如果不行,我会很感激我必须改变什么来处理导航参数,因为我不太理解它。

class MenuFragment : Fragment(), PlanAdapter.PlanItemClickListener, PlanItemDialogFragment.NewPlanItemDialogListener {
    private lateinit var binding : FragmentMenuBinding

    private lateinit var database: PlanListDatabase
    private lateinit var adapter: PlanAdapter

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = FragmentMenuBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        database = PlanListDatabase.getDatabase(requireActivity().applicationContext)

        binding.fab.setOnClickListener{
            PlanItemDialogFragment().show(
                childFragmentManager,
                PlanItemDialogFragment.TAG
            )
        }
    }

class PlanItemDialogFragment : DialogFragment() {
    interface NewPlanItemDialogListener {
        fun onPlanItemCreated(newItem: PlanItem)
    }

    private lateinit var listener: NewPlanItemDialogListener

    private lateinit var binding: DialogNewItemBinding

    override fun onAttach(context: Context) {
        super.onAttach(context)
        listener = context as? NewPlanItemDialogListener
            ?: throw RuntimeException("Activity must implement the NewPlanItemDialogListener interface!")
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        binding = DialogNewItemBinding.inflate(LayoutInflater.from(context))

        return AlertDialog.Builder(requireContext())
            .setTitle(hu.bme.aut.android.mobil_hf.R.string.new_plan_item)
            .setView(binding.root)
            .setPositiveButton(hu.bme.aut.android.mobil_hf.R.string.button_ok) { dialogInterface, i ->
                if (isValid()) {
                    listener.onPlanItemCreated(getPlanItem())
                }
            }
            .setNegativeButton(hu.bme.aut.android.mobil_hf.R.string.button_cancel, null)
            .create()
    }

字符串

a2mppw5e

a2mppw5e1#

你可以先检查parentFragment是否是onAttach方法中的侦听器类型

listener = parentFragment as? NewPlanItemDialogListener 
        ?: context as? NewPlanItemDialogListener
        ?: throw RuntimeException("Activity or parrent fragment must implement the NewPlanItemDialogListener interface!")

字符串

jq6vz3qz

jq6vz3qz2#

结果将被定向到主Activity,而不是从其打开的片段,因为此场景中使用的上下文是Activity的上下文。
您可以使用lamda函数而不是回调函数从Dialog中检索数据,

class PlanItemDialogFragment(private val onPlantCreated:(PlanItem)-> Unit):DialogFragment(){

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        return AlertDialog.Builder(requireContext())
            .setTitle("Title")
            .setMessage("Message...")
            .setPositiveButton("Ok"){ dialogInterface, i ->

                onPlantCreated(getPlantItem()) 

            }
            .setNegativeButton("Cancel"){ dialogInterface, i ->

            }
            .create()
    }

字符串
}
然后在片段中调用对话框。

fab.setOnClickListener {
        PlanItemDialogFragment(
            onPlantCreated = { planItem ->
                // Use the 'planItem' data here
            }
        ).show(childFragmentManager,PlanItemDialogFragment.TAG)
    }

相关问题