How to open a different activity on recyclerView in fragment?

921 Views Asked by At

I am using a recyclerView to show my listItems in the home fragment. But I have been stuck on how to open a different activity when items are clicked. How can I do for the next steps? Could you please help me to solve the issue? I would appreciate the help.

HomeFragment.kt

class HomeFragment : Fragment() {
private var _binding: FragmentHomeBinding? = null
private val binding get() = _binding!!

lateinit var recycle1:RecyclerView
private val list = ArrayList<Locations>()
private val adapter:Adapter = Adapter(list)

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {

    var v =inflater.inflate(R.layout.fragment_home, container, false)

    recycle1 = v.findViewById(R.id.rv_item)
    recycle1.layoutManager = LinearLayoutManager(activity)

    list.clear()
    testData()

    val adapterr = Adapter(list)
    recycle1.adapter = adapterr
    adapter.notifyDataSetChanged()
    recycle1.setHasFixedSize(true)
    return v
}

private fun testData(){
    list.add(Locations(R.drawable.book_cafe,"The Book Cafe","20 Martin Rd","Cafe"))
    list.add(Locations(R.drawable.citysprouts,"City Sprouts","102 Henderson Road","Cafe"))
    list.add(Locations(R.drawable.esplanade,"Library@esplande","8 Raffles Ave","Library"))
    list.add(Locations(R.drawable.hf,"Library@Harbourfront","1 HarbourFront Walk","Library"))
    list.add(Locations(R.drawable.mangawork,"MangaWork","291 Serangoon Rd","Cafe"))
    list.add(Locations(R.drawable.orchard,"Library@orchard","277 Orchard Road","Library"))
    list.add(Locations(R.drawable.rabbitandfox,"Rabbit&Fox","160 Orchard Rd","Cafe"))
    list.add(Locations(R.drawable.sixlettercoffee,"T6 Letter Coffee","259 Tanjong Katong Rd","Cafe"))

}

}

Adapter.kt

class Adapter (val listItem:ArrayList<Locations>) : RecyclerView.Adapter<Adapter.RecycleViewHolder>(){
inner class RecycleViewHolder(itemView: View):RecyclerView.ViewHolder(itemView){
    val itemImage: ShapeableImageView = itemView.findViewById(R.id.item_image)
    val heading: TextView = itemView.findViewById(R.id.item_title)
    val detail: TextView = itemView.findViewById(R.id.item_detail)
    val category: TextView = itemView.findViewById(R.id.item_categories)

}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecycleViewHolder {
    val view:View = LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false)
    return RecycleViewHolder(view)
}

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

override fun onBindViewHolder(holder: RecycleViewHolder, position: Int) {
    val item = listItem[position]
    holder.itemImage.setImageResource(item.itemImage)
    holder.heading.text = item.headings
    holder.detail.text = item.detail
    holder.category.text = item.category
}

Locations. kt

data class Locations(var itemImage:Int,var headings :String,var detail :String,var category :String)
2

There are 2 best solutions below

0
On

You have to take help of an interface to navigate :

First Create an interface , Suppose name it Navigate


interface Navigate {


    fun onRecyclerViewItemClicked(location : Location)

}

Then you have to make use of this interface in the adapter as well as the fragment : In your adapter , you have to do the following :

class Adapter (val listItem:ArrayList<Locations>) : RecyclerView.Adapter<Adapter.RecycleViewHolder>(){

//Declare listener object
    var listener: Navigate? = null


inner class RecycleViewHolder(itemView: View):RecyclerView.ViewHolder(itemView){
    val itemImage: ShapeableImageView = itemView.findViewById(R.id.item_image)
    val heading: TextView = itemView.findViewById(R.id.item_title)
    val detail: TextView = itemView.findViewById(R.id.item_detail)
    val category: TextView = itemView.findViewById(R.id.item_categories)

}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecycleViewHolder {
    val view:View = LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false)
    return RecycleViewHolder(view)
}

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

override fun onBindViewHolder(holder: RecycleViewHolder, position: Int) {
    val item = listItem[position]
    holder.itemImage.setImageResource(item.itemImage)
    holder.heading.text = item.headings
    holder.detail.text = item.detail
    holder.category.text = item.category

     // Now suppose you want to navigate to another fragment / Activity on click of the itemImage , then do the following 
   holder.itemImage.setOnClickListener{
            
     listener?.onRecyclerViewItemClicked(item)
    }
}

Now in your fragment extend the Navigate Class and implement the override the methods :

class HomeFragment : Fragment() , Navigate {

// Rest of your code


override fun onRecyclerViewItemClicked(location : Location){

   // The argument location here is the information of the item that is clicked of 
   // the RecyclerView
  // Here write your code to navigate to the next fragment / activity based on what 
  //you are using NavController / Fragment Manager
}


}
0
On

Set a clickListener in init {} block of your view holder For eg.

inner class RecycleViewHolder(itemView: View):RecyclerView.ViewHolder(itemView){
    val itemImage: ShapeableImageView = itemView.findViewById(R.id.item_image)
    val heading: TextView = itemView.findViewById(R.id.item_title)
    val detail: TextView = itemView.findViewById(R.id.item_detail)
    val category: TextView = itemView.findViewById(R.id.item_categories)
   
    init {
       itemView.setOnClickListener { // start your activity using view context  }
     }

}

Never set your click listener in onBindViewHolder() method as click listener will set multiple times because this method method is called every time items are bound in recycler view. Reference official doc