Home > Software engineering >  boilerplate / class name repeated 4x - when creating / opening dialogs
boilerplate / class name repeated 4x - when creating / opening dialogs

Time:12-10

How to reduce boilerplate when creating and then using dialogs?
Especially name of the dialog - in the SIMPLEST case it occurs 4 times!

For example:

class MyDialogFragment : DialogFragment() {
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        // unnecessary details
        ...
    }

    companion object {
        const val TAG = "MyDialogFragment"
    }
}


class MyFragment : Fragment() {
    fun doSthAndShowDialog() {
        sth()
        MyDialogFragment().show(
            childFragmentManager, MyDialogFragment.TAG
        )
    }
}

Would be great to dynamically generate TAG from dialog class name - so we don't to code it.

For example:

class MyFragment : Fragment() {
    fun doSthAndShowDialog() {
        sth()
        MagicDialogTool.show(
            MyDialogFragment::class,
            childFragmentManager
            // tag is generated and set internally by MagicDialogTool
        )
    }
}

Thanks & cheers ;]

CodePudding user response:

A couple of extension functions I think could do it.

First a base one for generating the tag. This is what you'd use instead of MyFragment.TAG in other places where you need it (example: getSimpleTag<MyFragment>().

inline fun <reified F: Fragment> getSimpleTag() = F::class.simpleName

Then:

inline fun <reified F: Fragment> FragmentManager.findFragmentBySimpleTag(): F? =
    findFragmentByTag(getSimpleTag<F>()) as? F

// and

inline fun <reified F: DialogFragment> F.show(manager: FragmentManager) =
    show(manager, getSimpleTag<F>())

Then you can simply use:

class MyFragment : Fragment() {
    fun doSthAndShowDialog() {
        sth()
        MyDialogFragment().show(childFragmentManager)
    }
}

CodePudding user response:

You could create a method in the Dialog class which only takes a FragmentManager object as argument. Like so:

class MyDialogFragment : DialogFragment() {
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        // unnecessary details
        ...
    }

    fun show(childFragmentManager: FragmentManager) {
        show(childFragmentManager, MyDialogFragment::class.simpleName)
    }
}

You can then use it like so:

class MyFragment : Fragment() {
    fun doSthAndShowDialog() {
        sth()
        MyDialogFragment().show(childFragmentManager)
    }
}

Or you could create an extension function to be used for various DialogFragment classes:

inline fun <reified T: DialogFragment> T.show(
    childFragmentManager: FragmentManager
) {
    show(childFragmentManager, T::class.simpleName)
}
  • Related