Kotlin Android RecyclerView ItemClickListener with SearchView

22 Views Asked by At

I'm trying to perform a RecyclerView ItemClickListener with a SearchView box in order to list data from Firestore and click on a specific item to show the details. I'm able to get data and detail when the search aren't used. When an item is identified in the search function the position are updated as listed in the RecyclerView and then the detail is related at an incorrect item.

This is my adapter:

class MyAdapter (private var placeList: List<Place>, private var listener: RecyclerViewEvent):
RecyclerView.Adapter<MyAdapter.MyViewHolder>(){

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyAdapter.MyViewHolder {

    val itemView = LayoutInflater.from(parent.context).inflate(R.layout.item_place,
        parent,false)
    return MyViewHolder(itemView)
}

override fun onBindViewHolder(holder: MyAdapter.MyViewHolder, position: Int) {

    val place : Place = placeList[position]
    holder.town.text = place.name
    holder.regione.text = place.regione

    if (place.cude == true){
        holder.cude.visibility = View.VISIBLE
    }else if( place.cude == false){
        holder.cude.visibility = View.INVISIBLE
    }else{
        holder.cude.visibility = View.INVISIBLE
    }

}

fun setFilteredList(placeList: List<Place>){
    this.placeList = placeList
    notifyDataSetChanged()
}

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

inner class MyViewHolder(itemView: View): RecyclerView.ViewHolder(itemView), View.OnClickListener {
    val town: TextView = itemView.findViewById(R.id.tvTown)
    val regione: TextView = itemView.findViewById(R.id.tvRegion)
    val cude: ImageView = itemView.findViewById(R.id.ledCude)

    init {
        itemView.setOnClickListener(this)
    }

    override fun onClick(v: View?) {
        val position = adapterPosition
        if (position != RecyclerView.NO_POSITION) {
            listener.onItemClick(position)
        }
    }
}

interface RecyclerViewEvent {
    fun onItemClick(position: Int)
}

}

and this my activity:

class MainActivity : AppCompatActivity(), MyAdapter.RecyclerViewEvent {

private lateinit var recyclerView: RecyclerView
private lateinit var searchView: SearchView
private var placeList = ArrayList<Place>()
private lateinit var myadapter: MyAdapter

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    recyclerView = findViewById(R.id.recyclerView)
    searchView = findViewById(R.id.searchView)

    recyclerView.setHasFixedSize(true)
    recyclerView.adapter = MyAdapter(placeList, this)
    recyclerView.layoutManager = LinearLayoutManager(this)
    addDataToList()

    searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
        override fun onQueryTextSubmit(query: String?): Boolean {
            return false
        }

        override fun onQueryTextChange(newText: String?): Boolean {
            filterList(newText)
            return true
        }
    })

}

override fun onItemClick(position: Int) {
    val detailPlace = placeList[position]
    val intent = Intent(this, PlaceDetails::class.java)
    intent.putExtra("android", detailPlace)
    startActivity(intent)
}

private fun addDataToList() {
    placeList.clear()

    val db = Firebase.firestore
    db.collection("places")
        .get()
        .addOnSuccessListener { result ->
            for (document in result) {
                placeList.add(document.toObject(Place::class.java))

                Log.d("OGGETTO", placeList.toString())
                myadapter = MyAdapter(placeList, this)
                recyclerView.adapter = myadapter
            }
            myadapter.notifyDataSetChanged()
        }
        .addOnFailureListener { e ->
            // Handle any errors
        }

}

private fun filterList(query: String?) {

    if (query != null) {
        val filteredList = ArrayList<Place>()
        for (i in placeList) {
            if (i.name.lowercase(Locale.ROOT).contains(query)) {
                filteredList.add(i)
            }
        }

        if (filteredList.isEmpty()) {
            Toast.makeText(this, "No Data found", Toast.LENGTH_SHORT).show()
        } else {
            myadapter.setFilteredList(filteredList)
        }
    }
}

}

How to fix the correct position when I use the filter?

0

There are 0 best solutions below