Home > front end >  How to solve "does not have a NavController set"
How to solve "does not have a NavController set"

Time:06-24

I want to reach Detail Fragment from Main Fragment.

ERROR W/System.err: java.lang.IllegalStateException: View androidx.cardview.widget.CardView{7fe29a5 VFE...C.. ...P.... 0,0-381,319 #7f080085 app:id/container} does not have a NavController set W/System.err: at androidx.navigation.Navigation.findNavController(Navigation.kt:71) W/System.err: at com.isilon.beinconnect.ui.main.adapter.MainAdapter.onBindViewHolder$lambda-0(MainAdapter.kt:68) W/System.err: at com.isilon.beinconnect.ui.main.adapter.MainAdapter.$r8$lambda$J_WJtHWaCOLmqLIL361QlbA-I6M(Unknown Source:0) W/System.err: at com.isilon.beinconnect.ui.main.adapter.MainAdapter$$ExternalSyntheticLambda0.onClick(Unknown Source:6) Adapter

 override fun onBindViewHolder(holder: DataViewHolder, position:   Int) {
              holder.bind(data[position])
    
            holder.itemView.setOnClickListener{
    
                val resultData = data[position]
    
    
                val action =          MainFragmentDirections.actionMainFragmentToDetailFragment()
                action.releaseDate = resultData.release_date
                val navController = Navigation.findNavController(holder.itemView)
                navController.navigate(action)
            }
        }

XML

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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/scrollView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <androidx.fragment.app.FragmentContainerView
        android:id="@ id/fragmentContainerView"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/navigation" />
</LinearLayout>

DETAIL XML

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    tools:context=".ui.main.view.DetailFragment">

    <ImageView
        android:id="@ id/iv_detail_avatar"
        android:layout_width="wrap_content"
        android:layout_height="150dp"
        android:layout_margin="15dp"/>
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <TextView
            android:id="@ id/tv_adult"
            android:layout_width="wrap_content"
            android:textSize="20sp"
            android:textColor="@android:color/background_dark"
            android:layout_height="wrap_content"
            android:layout_margin="15dp"/>

        <TextView
            android:id="@ id/tv_release_date"
            android:layout_width="wrap_content"
            android:textSize="20sp"
            android:textColor="@android:color/background_dark"
            android:layout_height="wrap_content"
            android:layout_margin="15dp"/>
    </LinearLayout>

</LinearLayout>

NAVIGATION

<?xml version="1.0" encoding="utf-8"?>
<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/navigation"
    app:startDestination="@id/mainFragment">

    <fragment
        android:id="@ id/mainFragment"
        android:name="com.isilon.beinconnect.ui.main.view.MainFragment"
        android:label="fragment_main"
        tools:layout="@layout/fragment_main" >
        <action
            android:id="@ id/action_mainFragment_to_detailFragment"
            app:destination="@id/detailFragment" />
    </fragment>
    <fragment
        android:id="@ id/detailFragment"
        android:name="com.isilon.beinconnect.ui.main.view.DetailFragment"
        android:label="fragment_detail"
        tools:layout="@layout/fragment_detail" >
        <argument
            android:name="releaseDate"
            app:argType="string"
            app:nullable="true"
            android:defaultValue="No Release Date" />
        <argument
            android:name="avatar"
            app:argType="string"
            app:nullable="true"
            android:defaultValue="No Avatar Img" />
        <argument
            android:name="adult"
            app:argType="boolean"
            android:defaultValue="false" />
    </fragment>
</navigation>

CodePudding user response:

I'd do it like that

(itemView.context as AppCompatActivity).findNavController(R.id.fragmentContainerView).navigate(action)

CodePudding user response:

findNavController won't work for views added programmatically and not attached to parent view like viweholders so you need to find nav controller for recyclerview instead of viewholder itmeview

private var mRecyclerView : RecyclerView? = null
override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
    super.onAttachedToRecyclerView(recyclerView)
    mRecyclerView = recyclerView
}

override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
    super.onDetachedFromRecyclerView(recyclerView)
    mRecyclerView = null// to avoid memory leak
}
override fun onBindViewHolder(holder: DataViewHolder, position:   Int) {
    holder.bind(data[position])
    holder.itemView.setOnClickListener{
        val resultData = data[position]
        val action =          MainFragmentDirections.actionMainFragmentToDetailFragment()
        action.releaseDate = resultData.release_date
        val navController = Navigation.findNavController(mRecyclerView!!)
        navController.navigate(action)
    }
}

Q: why findNavController won't work for views added programmatically? A: Because nav controller add tags to all views when created with weak reference to itself, so when you add view programmatically and not attached to parent, findNavController won't be able to get your root view and thus won't be able to find its weak reference.

  • Related