androidreturn-valueandroid-dialogfragmentdialogfragment

Return value from a dialogfragment with a listener


I've just saw a comment to use a listener to know when a DialogFragment is dismissed

https://stackoverflow.com/a/72059505/2129561

The guy proposed the next:

In your DialogFragment you can use this:

lateinit var onDismissListener : () -> Any

override fun onDismiss(dialog: DialogInterface) {
    if (this::onDismissListener.isInitialized) {
        onDismissListener()
    }

    super.onDismiss(dialog)
}

then in your fragment which creates the dialog:

val dialog = DialogFragment()
dialog.onDismissListener = {
      Toast.makeText(context, "Dismissed", Toast.LENGTH_SHORT).show()
}

dialog.show(context.supportFragmentManager, "tag")

I, I'm trying to use this idea to return a value from the dialogfragment but I don't know how at this moment. My try is:

lateinit var onDismissListener : () -> Any
    lateinit var onAcceptListener : () -> Any

    override fun onDismiss(dialog: DialogInterface) {
        if (this::onDismissListener.isInitialized) {
            onDismissListener()
        }

        super.onDismiss(dialog)
    }

    fun onAccept(passwordInput: String){
        if(this::onAcceptListener.isInitialized){
            onAcceptListener()
        }
    }

and inside the button, do the next:

btnAccept.setOnClickListener {
onAccept(password.text.toString())
dismiss()
}

Obviously, this is not working... :)


Solution

  • in order to pass data from DialogFragment to your Fragment/Activity you need to implement an Interface in the DialogFragment and let your Fragment/Activity implement it.

    as an example :

    in DialogFragment class:

    you will add this

    interface dialogListener{
        fun passData(data: Any)
    }
    

    in your Activity or Fragment class you will need to

    : dialogListener {...
    

    now after this, your fragment/activity will show red bulb, which means you need to implement the interface methods, so you will need to override the functions you have in your interface, which will look like this:

    override fun passData(data: Any) {
       print(data)
    }
    

    like this you will be printing the data in the fragment/activity

    but now, you need to know how to trigger it, first you will need to pass the interface you implemented in act/frag to your dialog fragment and that can be through maybe a set function you add or pass it by constructor, and later on you call it

    as summary your DialogFragment would look something like this:

    class dialogFragment(private val listener: Listener): DialogFragment() {
    .
    .
    .
    .
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
    
        button.setOnClickListener {
            listener.passData(data)
        }
    
    }
    
    interface Listener{
        fun passData(data: Any)
    }
    

    }

    while your fragment or activity would be looking something like this:

    class fragment : Fragment() , Listener {
    
    
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        .
        .
        .
        var dialog = dialogFragment(this)
        dialog.show...
        .
        .
        .
    }
    
    override fun passData(data: Any) {
        print(data)
    }
    
    }