0

I'm new to the Kotlin programing language and Dealing with the recyclerView is kinda hard to understand so I have used Groupie Library, But there is no enough documentation or tutorials on how to deal with this library.

coming straight to the point I have a recycler view contains data that I added to the adapter, and I want to filter that data using the searchView, I don't know how to get the list or the Text out of that groupAdapter or the items that inside of them to perform filter.

here is the XML Layout of my Fragment

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".fragment.SearchFragment"
    android:background="@color/backgroundGray">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <include
            android:id="@+id/include4"
            layout="@layout/fragment_search_toolbar"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recycleview_search"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:divider="@null"
            android:background="@color/backgroundGray"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/include4"
            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
            tools:listitem="@layout/search_row"/>

    </androidx.constraintlayout.widget.ConstraintLayout>



</FrameLayout>

seachView XML Layout

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.SearchView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/searchView"
    android:layout_marginRight="10dp"
    android:layout_marginLeft="10dp"
    android:layout_marginBottom="10dp"
    app:queryHint="Looking For Stores.."
    app:iconifiedByDefault="false"
    android:layoutDirection="rtl"
    android:clickable="true"
    android:elevation="4dp"
    android:gravity="end"
    app:queryBackground="@null"
    android:textAlignment="textEnd"
    tools:ignore="KeyboardInaccessibleWidget,UnusedAttribute"
    android:background="@drawable/searchview_background">

</androidx.appcompat.widget.SearchView>

and this is my Fragment Class

class SearchFragment : Fragment() {

    lateinit var searchView: android.widget.SearchView

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

        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment

        return inflater.inflate(R.layout.fragment_search, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        searchView = view.findViewById(R.id.searchView)
        val adapter = GroupAdapter<GroupieViewHolder>()
        recycleview_search.adapter = StoresItems()
        

        adapter.add(Stores(R.drawable.ic_kfc, "KFC", 15.581010, 32.569032))
        adapter.add(Stores(R.drawable.ic_pizzahut, "Pizza Hut", 15.581050, 32.569002))
        adapter.add(Stores(R.drawable.ic_dominos, "Dominos Pizza", 15.581560, 32.512002))

        adapter.setOnItemClickListener { item, view ->
            val storesItem = item as Stores
            val  intent = Intent(view.context, OrderActivity::class.java)

            intent.putExtra("storename", storesItem.storename)
            startActivity(intent)
        }

        searchView.setOnCloseListener(object: SearchView.OnQueryTextListener,
            SearchView.OnCloseListener {
            override fun onQueryTextSubmit(p0: String?): Boolean {
               return false
            }

            override fun onQueryTextChange(p0: String?): Boolean {
                return false
            }
       })
    }



}
 class Stores(val img: Int, val storename: String , val latitude: Double, val longitude: Double) : Item<GroupieViewHolder>() {
        override fun getLayout(): Int {
            return R.layout.search_row
        }
    
        override fun bind(viewHolder: GroupieViewHolder, position: Int) {
    
            viewHolder.itemView.storeName.text = storename
            viewHolder.itemView.storeImage.setImageResource(img)
        }
    }
Adam Millerchip
  • 20,844
  • 5
  • 51
  • 74
Swift
  • 37
  • 1
  • 9

1 Answers1

0

Let's look at it from another point of view:

The concept is, you have a List<Things> that your RecyclerView/Adapter show. You produce a keyword (search) that should reduce that list. How you filter this list, where you filter it, where you store it, etc. is (and should be) irrelevant to the RecyclerView/Adapter. Their responsibilities are different (recycle views for performance reasons, and adapt/bind them to "Views" respectively), not search/filter a list. You haven't posted your Adapter code, but in essence:

When you submit a search query, you "filter" the list in any way you see fit, producing a new list with the filtered results, and pass this onto the adapter. The adapter will then calculate what needs to be done to display the new list.

Bonus points if you use a ListAdapter<T, K> which implements a DiffUtil.ItemCallback since that means you can do adapter.submitList(newFilteredList), sit back, and relax.

In other words, separate the responsibilities, searching, filtering is not part of the adapter/recyclerview.

Martin Marconcini
  • 26,875
  • 19
  • 106
  • 144
  • Thanks for explaining that part, as you see my code how to perform the search query on this groupie adapter, first of all I don’t know how to get the list that have added to the adapter @Martin Marconcini – Swift May 17 '21 at 10:11
  • How to get the list of items, or I don’t have any yet – Swift May 17 '21 at 10:18
  • That’s all my code there’s no adapter code – Swift May 17 '21 at 10:20
  • The List of items should not be in the adapter. Meaning you will pass it onto the adapter (because it needs it..) but it should not be your source of truth about the list. The list should be in a repository (can be in memory, can be a database, can be anything you can imagine), but once you fetch this list, you pass an immutable copy to your adapter. Your code does this "wrong" since you are adding items _directly_ to your adapter. You should construct your list, *then* send a copy to your adapter. When you search, you create a new list and send that new one to your adapter. – Martin Marconcini May 17 '21 at 10:21
  • Take a look at this simple RV example I created a few months ago: https://github.com/Gryzor/TheSimplestRV (or the source code directly: [here](https://github.com/Gryzor/TheSimplestRV/tree/main/app/src/main/java/com/example/thesimplestrv)) – Martin Marconcini May 17 '21 at 10:22