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.