Home > Enterprise >  how to navigate to fragment inside recycler view?
how to navigate to fragment inside recycler view?

Time:10-20

I have an activity that is controlled with a navigation component, it has few fragments, inside one of these fragments there is a recyclerView that has some items, when I click on an Item I want it to navigate me to another fragment that has additional information about the item, I don't know how to use navigation component inside a recycelerView, when I type findNavController it has some parameters that am not sure what to put in or if its even the right function, I also tried to do it by code like this:

val fm = (context as AppCompatActivity).supportFragmentManager
            fm.beginTransaction()
                .replace(R.id.fragmentContainer, fragment)
                .addToBackStack(null)
                .commit()

by the way this is the code that asks for other parameters:

// it asks for a (fragment) or (activity, Int)
findNavController().navigate(R.id.action_settingsFragment_to_groupUnits)

the problem is when I navigate out of this fragment or use the drawer navigation (nav component for the other fragments), this fragment that I navigated to stays displayed in the screen, I see both fragments at the same time, I assume its a fragment backStack issue but I don't know how to solve it, thanks for the help and your time in advance

CodePudding user response:

You do not need to navigate from RecyclerView item click to AdditionalDetails fragment directly. You can do this same thing by help of interface. Steps:

  1. Create an interface with a method declaration.
  2. Extend Interface from the fragment where you are using your RecyclerView and Implement interface method.
  3. Pass this interface with the adapter.
  4. Using the interface from adapter you just pass object when click on item.
  5. Finally from your fragment you just navigate to AdditionalDetails fragment with argument.

Lets see sample code from my current project:

  1. Interface
interface ChatListClickListener {
    fun onChatListItemClick(view:View, user: User)
}
  1. Adapter Class

class UserAdapter(val Users: List<User>, val chatListClickListener: ChatListClickListener) : RecyclerView.Adapter<UserAdapter.UserViewHolder>()  {

    inner class UserViewHolder(
        val recyclerviewUsersBinding: RecyclerviewChatlistBinding
    ) : RecyclerView.ViewHolder(recyclerviewUsersBinding.root)

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
        val  vh = UserViewHolder(
            DataBindingUtil.inflate(
                LayoutInflater.from(parent.context),
                R.layout.recyclerview_chatlist,
                parent,
                false
            )
        )
        return vh
    }

    override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
        holder.recyclerviewUsersBinding.user = Users[position]
        holder.recyclerviewUsersBinding.root.setOnClickListener{
            chatListClickListener.onChatListItemClick(it,Users[position])
        }
    }

    override fun getItemCount(): Int {
        return Users.size
    }
}
  1. My fragment

class FragmentChatList : Fragment(), ChatListClickListener {

    lateinit var binding: FragmentChatListBinding
    lateinit var viewModel: ChatListViewModel
    lateinit var listener: ChatListClickListener

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val args: FragmentChatListArgs by navArgs()
        binding = FragmentChatListBinding.inflate(layoutInflater, container, false)
        val factory = ChatListFactory(args.user)
        viewModel = ViewModelProvider(this, factory).get(ChatListViewModel::class.java)
        binding.viewModel = viewModel
        listener = this

        lifecycleScope.launch {
            viewModel.addUserWhenUserConnect()
        }
        viewModel.userList.observe(viewLifecycleOwner, Observer { data ->
            binding.rvChatList.apply {
                layoutManager = LinearLayoutManager(requireContext())
                setHasFixedSize(true)
                adapter = UserAdapter(data, listener)
            }
        })
        return binding.root
    }

    override fun onChatListItemClick(view: View, user: User) {

        Toast.makeText(requireContext(), user.name   "", Toast.LENGTH_SHORT).show()
// here you navigate to your fragment....
    }

}

I guess this will be helpful.

  • Related