Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call navigation action after click on item with RecyclerView and DataBinding?

I have problem with call navigation action defined in nav_graph in my adpter.

I tried to call Navigation.findNavController(v).navigate(id_myaction) in the bind function of the ViewHolder but it doesnt work and I got

error : " View androidx.constraintlayout.widget.ConstraintLayout{96d8d23 V.E...C.. ...P.... 0,471-1080,628} does not have a NavController set"

It's my action:

<fragment
            android:id="@+id/eventListFragment"
            android:name="EventListFragment"
            android:label="fragment_event_list"
            tools:layout="@layout/fragment_event_list" >
        <action
                android:id="@+id/action_eventListFragment_to_startEventFragment"
                app:destination="@id/startEventFragment" />
</fragment>

It's my adapter:

class EventListAdapter(val findNavController: NavController) : RecyclerView.Adapter<EventListAdapter.ViewHolder>() {
    private lateinit var eventList:List<Event>


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EventListAdapter.ViewHolder {
        val binding: EventListItemBinding = DataBindingUtil.inflate(LayoutInflater.from(parent.context), R.layout.event_list_item, parent, false)
        return ViewHolder(binding,findNavController)
    }

    override fun onBindViewHolder(holder: EventListAdapter.ViewHolder, position: Int) {
        holder.bind(eventList[position])
    }

    override fun getItemCount(): Int {
        return if(::eventList.isInitialized) eventList.size else 0
    }

    fun updateEventList(eventList:List<Event>){
        this.eventList = eventList
        notifyDataSetChanged()
    }

    class ViewHolder(private val binding: EventListItemBinding, val findNavController: NavController):RecyclerView.ViewHolder(binding.root){
        private val viewModel = EventListItemViewModel()

        fun bind(event:Event){
            viewModel.bind(event)
            binding.root.setOnClickListener {v -> Navigation.findNavController(v).navigate(R.id.action_eventListFragment_to_startEventFragment)}
        binding.viewModel = viewModel
        }

    }
}

I would to start startEventFragment definied in my action after click on item.

like image 303
M.Devan Avatar asked Oct 15 '19 19:10

M.Devan


1 Answers

Based on the official tutorial, you may require to change your code as follows,

binding.root.setOnClickListener {v ->
    v.findNavController().navigate(R.id.action_eventListFragment_to_startEventFragment) 
}

Update

If you read the documentation, you will find the following note,

Note: The Navigation component is designed for apps that have one main activity with multiple fragment destinations. The main activity is associated with a navigation graph and contains a NavHostFragment that is responsible for swapping destinations as needed. In an app with multiple activity destinations, each activity has its own navigation graph.

So, you need to make sure that the both fragments belong to a same activity and the activity is associated with navigation graph and contains a NavHostFragment. Please check if your activity's layout contains the following fragment tag,

<fragment
    android:id="@+id/nav_host_fragment"
    android:name="androidx.navigation.fragment.NavHostFragment"
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"

    app:defaultNavHost="true"
    app:navGraph="@navigation/nav_graph_id" />
like image 150
Roaim Avatar answered Nov 01 '22 18:11

Roaim