11

I have a feed fragment that its main element is a RecyclerView of posts.

I am managing the recycler with Lisa Wray's Groupie library https://github.com/lisawray/groupie

Now in my navigation graph I have an action connecting the feed fragment to the another fragment, and I try to call this action with an on click listener I create in the bind function of the adapter.

val action=FeedFragmentDirections.actionDestinationFeedToDestinationAddToBucket(image.id)
findNavController().navigate(action)

I keep getting an error saying navigation destination XXXXX is unknown to this NavController

I've tried adding a few things before the findNavController(), like viewHolder.itemView or viewHolder.root but nothing works.

When I use viewHolder.itemView.rootView I get this error instead View DecorView@a190adf[MainActivity] does not have a NavController set I don't know what DecorView is.

Any ideas how I can implement my oncick listeners properly?

Tsabary
  • 3,119
  • 2
  • 24
  • 66
  • can you tell in which file you wrote `findNavController().navigate(action)` – Moinkhan Mar 28 '19 at 09:39
  • @Moinkhan what do you mean in which file? I've been using this command in all the fragments I navigate from using the Navigation component. I've try to work it out but couldn't find any answer to this problem so kinda gave up at this point, but would love to figure it out as it would allow me more functionality – Tsabary Mar 29 '19 at 02:21
  • make sure you are finding nav controller on view which is inside your nav host fragment ... – Moinkhan Mar 29 '19 at 03:22
  • I am trying to find nav controller from one item in a recyclerview, that is inside my nav host fragment – Tsabary Mar 29 '19 at 05:55
  • Try to find NavController from parent views not from item .. – Moinkhan Mar 29 '19 at 06:38
  • @Tsabary Got any solution for this? – pavi2410 Jun 10 '19 at 18:44
  • I think I have to go with this: https://github.com/lisawray/groupie/issues/253#issuecomment-489363028 – pavi2410 Jun 10 '19 at 18:47
  • @Pavitra I've ditched the navigation component, it caused me to many issues. I am using a simple fragment manager now. Each item in my recyclerView has a reference to the main activity, and with that reference I get a hold to the fragment manager and do what I need – Tsabary Jun 10 '19 at 22:56
  • Checkout this https://stackoverflow.com/a/59740737/6770917 – ovicko Jan 14 '20 at 23:30

7 Answers7

9

Using itemView seems to work too as that's what I have on my code:

class RecyclerSettingsItem(
private val activity: MainActivity,
private val settingItem: String
) : Item<GroupieViewHolder>() {

override fun bind(viewHolder: GroupieViewHolder, position: Int) {

    var navController: NavController? = null

    viewHolder.apply {

        with(viewHolder.itemView) {

            tvTitle.text = settingItem

            itemView.setOnClickListener {

                navController = Navigation.findNavController(itemView)
                navController!!.navigate(R.id.action_settingsFragment_to_contactTracingFragment)

            }

        }

    }
}


override fun getLayout() = R.layout.rv_settings_item_row

}
Francislainy Campos
  • 3,462
  • 4
  • 33
  • 81
4

you could pass the parent fragment or activity in the recylerview adapter constructor.

class MyRecylerViewAdapter(...your other args.., val parentFragment: Fragment)

then find the navController from your parentFragment object

parentFragment.findNavController()

Edit: You could also pass the navController directly, but why pass the parentFragment? if you use different themes in your app, the construction of Views and ViewHolder should be done with the Context of parentFragment.requireActivity, otherwise your theme would not be applied to the RecyclerView items.

ilaimihar
  • 141
  • 5
4

just pass the navigation controller in the contractor of recyclerview adaptor class. java example

public RecyclerAdaptorMasseges(Context context, List<ConfirmationMessagesModuel> data, NavController navController) {
    inflate = LayoutInflater.from(context);
    this.data = data;
    this.navController = navController;
    Log.d("hex", " MsgRecyclerAdaptor");

}
2
 itemBinding.tvProfileBooked.setOnClickListener {

            val bundle = bundleOf("BookingId" to item.id)
            Navigation.findNavController(it).navigate(R.id.profileBookedFragment,bundle)

        }

Now Profile Fragment

    val bookingId = arguments?.getString("BookingId")
    
1

It worked for me

class MyRecylerViewAdapter(...your other args.., val findNavController: NavController)
MyRecylerViewAdapter(..., findNavController())
1

you could use 'requireView()'

     requireView().findNavController().navigate(R.id.your_action)
Jogy Felix
  • 11
  • 1
-1

i had the same problem, solved it by adding a click listener interface and calling the navController inside my fragment(or your activity).

Use this example : https://www.codexpedia.com/android/defining-item-click-listener-for-recyclerview-in-android/

and i add this:

@Override
public void onClick(View view, int position) {
    Globals.eventList = developersLists.get(position);
    navController.navigate(R.id.eventoFragment);
}
KevinZR
  • 11
  • 1