I want to open my dialogfragment class from a fragment and want to return the data from the dialog fragment. I am a uni student and had an example app where it was done from the main activity with a callback implementation but when I try to open the dialog from a fragment it still directs it to the main activity not the fragment I opened it from. Can I do this with the callback implementation or do I have to do something else?
I have code from the example project which works when it is launched from the main activity. I searched for it online and found that it can be done with navigation arguments too but wanted to do this way if possible. If not I would appreciate what do I have to change to do with the navigation arguments because I didn't quite understand it.
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()
}
The result is being directed to the main activity instead of the fragment it was opened from because the context used in this scenario is the activity's context.
You can use lamda function instead of callback to retrive the data from 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()
}
}
Then call dialog in fragment.
fab.setOnClickListener {
PlanItemDialogFragment(
onPlantCreated = { planItem ->
// Use the 'planItem' data here
}
).show(childFragmentManager,PlanItemDialogFragment.TAG)
}