Convert Fragment to Dialog Fragment with navArgs, How to navigate to DialogFragment from outside the Fragment class

All we need is an easy explanation of the problem, so here it is.

I want to navigate to DetailsFragment onClick of the list item (book_item.xml)

book_item.xml

<LinearLayout 
        ...
        onBooksClickListener="@{result}">
... 
</LinearLayout>

Now it works fine for Fragment (Full Screen)

I want to make it overlay fragment so want to convert it to Dialog Fragment

Working Code For Fragment

Fragment Class

class DetailsFragment : Fragment() {
 private val args by navArgs<DetailsFragmentArgs>()
 override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?): View? {
    val view = inflater.inflate(R.layout.fragment_details, container, false)
    }
 }

RowBinding Class

class BooksRowBinding  {
    companion object {

        @ExperimentalCoroutinesApi
        @BindingAdapter("onBooksClickListener")
        @JvmStatic
        fun onBooksClickListener(linearLayout: LinearLayout, result: Result){
            linearLayout.setOnClickListener{
                try {
                    val action = BooksListFragmentDirections.actionBooksListFragmentToDetailsFragment(result)
                    linearLayout.findNavController().navigate(action)

                    }catch (e: Exception){
                    Log.d("OnBooksClickListener",e.toString())
                }
            }
        }

To convert it to DailogFragment I tried using the google android docs but it didnt’t explain how to open dialogFragment from outside the Fragment class

Broken Code of DialogFragment

Fragment Class

class DetailsFragment : DailogFragment() {
 private val args by navArgs<DetailsFragmentArgs>()
 override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?): View? {
    val view = inflater.inflate(R.layout.fragment_details, container, false)
    }
 }

 

RowBinding Class

class BooksRowBinding  {
    companion object {

        @ExperimentalCoroutinesApi
        @BindingAdapter("onBooksClickListener")
        @JvmStatic
        fun onBooksClickListener(linearLayout: LinearLayout, result: Result){
            linearLayout.setOnClickListener{
                try {
                    DetailsFragment().show(childFragmentManager,DetailsFragment.TAG) 
                   /****************ERROR *******************
                    this works only if you call this from within the 
                    onCreateMethod of the Fragment
                   ******************************************/
                    }catch (e: Exception){
                    Log.d("OnBooksClickListener",e.toString())
                }
            }
        }

Now i am Getting error: Unresolved reference: childFragmentManager

my_nav.xml

<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/my_nav"
    app:startDestination="@id/booksListFragment">
    <fragment
        android:id="@+id/booksListFragment"
        android:name="we.are.suvikranth.ui.BooksListFragment"
        android:label="Suvikranth"
        tools:layout="@layout/fragment_books_list">
        
        <action
         android:id="@+id/action_booksListFragment_to_detailsFragment"
            app:destination="@id/detailsFragment" />
    </fragment>
    <fragment 
        android:id="@+id/detailsFragment"
        android:name="we.are.suvikranth.ui.DetailsFragment"
        android:label="Books Details"
        tools:layout="@layout/fragment_details" >
        <argument
            android:name="result"
            app:argType="we.are.suvikranth.models.Result" />
    </fragment>
</navigation>

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

Use the previous code to navigate to dialog Fragment

But change the fragment to dialog in my_nav.xml

Now the RowBinding Class looks like

class BooksRowBinding  {
    companion object {

        @ExperimentalCoroutinesApi
        @BindingAdapter("onBooksClickListener")
        @JvmStatic
        fun onBooksClickListener(linearLayout: LinearLayout, result: Result){
            linearLayout.setOnClickListener{
                try {
                    val action = BooksListFragmentDirections.actionBooksListFragmentToDetailsFragment(result)
                    linearLayout.findNavController().navigate(action)

                    }catch (e: Exception){
                    Log.d("OnBooksClickListener",e.toString())
                }
            }
        }

my_nav.xml looks like

<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/my_nav"
    app:startDestination="@id/booksListFragment">
    <fragment
        android:id="@+id/booksListFragment"
        android:name="we.are.suvikranth.ui.BooksListFragment"
        android:label="Suvikranth"
        tools:layout="@layout/fragment_books_list">
        
        <action
         android:id="@+id/action_booksListFragment_to_detailsFragment"
            app:destination="@id/detailsFragment" />
    </fragment>
    <dialog
        android:id="@+id/detailsFragment"
        android:name="we.are.suvikranth.ui.DetailsFragment"
        android:label="Books Details"
        tools:layout="@layout/fragment_details" >
        <argument
            android:name="result"
            app:argType="we.are.suvikranth.models.Result" />
    </dialog>
</navigation>

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

Leave a Reply