Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Navigation.createNavigateOnClickListener from onBindViewHolder?

I want to set an onclicklistener in the onBindViewHolder in order to navigate to a different fragment and send along some data to that fragment.

For the life of me, I can't seem to find a way to make it work. Any and all help is greatly appreciated!

The adapter class:

class ListAdapter(private val list: List<Workout>): RecyclerView.Adapter<WorkoutViewHolder>() {

    override fun getItemCount(): Int{
        return list.size
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WorkoutViewHolder {
        val layoutInflater = LayoutInflater.from(parent.context)
        return WorkoutViewHolder(layoutInflater, parent)
    }

    override fun onBindViewHolder(holder: WorkoutViewHolder, position: Int) {
        val workout: Workout = list[position]
        holder.itemView.setOnClickListener{
            Toast.makeText(holder.itemView.context, "TEST", Toast.LENGTH_LONG).show()
            val id = workout.workoutId
            val bundle = Bundle()
            bundle.putInt("workoutId", id)
            Navigation.createNavigateOnClickListener(R.id.workoutDetailsFragment)
        }
        holder.bind(workout)
    }
}

I can get the toast to pop up, so the onclicklistener seems to be working. However, the navigation part does not work. If I just set a button inside the fragment that is hosting the recyclerview and add button.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.workoutDetailsFragment)) it can navigate just fine. So the problem seems to be calling the navigate function from inside the onclicklistener inside the onbindviewholder

like image 712
Gurkmeja101 Avatar asked Jan 22 '26 10:01

Gurkmeja101


2 Answers

Navigation.createNavigateOnClickListener() creates an OnClickListener. Creating an OnClickListener just to never set it on anything doesn't do anything.

Instead, you'll want to just trigger your navigate() call directly, doing the same one line of code that createNavigateOnClickListener does internally:

override fun onBindViewHolder(holder: WorkoutViewHolder, position: Int) {
    val workout: Workout = list[position]
    holder.itemView.setOnClickListener{
        Toast.makeText(holder.itemView.context, "TEST", Toast.LENGTH_LONG).show()
        val id = workout.workoutId
        val bundle = Bundle()
        bundle.putInt("workoutId", id)

        // Using the Kotlin extension in the -ktx artifacts
        // Alternatively, use Navigation.findNavController(holder.itemView)
        holder.itemView.findNavController().navigate(
            R.id.workoutDetailsFragment, bundle)
    }
    holder.bind(workout)
}
like image 164
ianhanniballake Avatar answered Jan 24 '26 03:01

ianhanniballake


You need to assign your created listener rather than using it inside of a lambda. When you use a lambda with setOnClickListener(), the lambda literally is your listener. So in your example, you're creating a listener, but it's never assigned anywhere.

So to instead assign the created listener from Navigation.createNavigateOnClickListener(), your code should look like holder.itemView.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.workoutDetailsFragment))

like image 40
Bryan Dormaier Avatar answered Jan 24 '26 02:01

Bryan Dormaier