[Android/kotlin] 리사이클러뷰 TabLayout, Filterable 사용법

JINA·2021년 9월 2일
2

✍TabLayout, Filterable 사용법

Tablayout을 사용해서 원하는 키워드가 포함된 리스트만 볼 수 있도록 리사이클러뷰를 필터링해보자!!


TabLayout 구성


1. TabLayout안에 원하는 tabItem을 배치한다(ex: All, LEARNING, GAME)
2. tabItem의 text, icon 색상은 tabLayout에서 변경 가능하다.

<com.google.android.material.tabs.TabLayout
                android:id="@+id/tabLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@color/black"
                app:layout_scrollFlags="scroll|enterAlways"
                app:tabIconTint="@color/white"
                app:tabIndicatorColor="@color/white"
                app:tabSelectedTextColor="#B0FFFF"
                app:tabTextColor="@color/white">

                <com.google.android.material.tabs.TabItem
                    android:id="@+id/unFilteredList"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:text="ALL"
                    android:icon="@drawable/ic_baseline_person_24"/>

                <com.google.android.material.tabs.TabItem
                    android:id="@+id/filteredList1"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:text="LEARNING"
                    android:icon="@drawable/ic_baseline_psychology_24"/>

                <com.google.android.material.tabs.TabItem
                    android:id="@+id/filteredList2"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:icon="@drawable/ic_baseline_videogame_asset_24"
                    android:text="GAME"/>
            </com.google.android.material.tabs.TabLayout>

Activity

1. addOnTabSelectedListener()메서드를 이용해서 모든 탭의 동작을 처리할 수 있다
2. onTabSelected()에서 각각의 tab을 when()으로 tab의 파라미터인 position을 구별한다.
(왼쪽부터 0, 1, 2 순서)

3. 리사이클러뷰 어댑터의 filter() 메서드를 사용하여 필터링 하고싶은 텍스트를 넣어준다.
(전체를 다 보여주고 싶다면 " "을 넣어준다)

ContentsListActivity.kt

binding.tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
            override fun onTabSelected(tab: TabLayout.Tab?) {
                Log.e("TAG", "${tab!!.position}")
                when(tab.position){
                    0 ->{
                        mListAdapter.filter.filter("")
                    }
                    1 -> {
                        mListAdapter.filter.filter("LEARNING")
                    }
                    2 -> {
                        mListAdapter.filter.filter("GAME")
                    }
                }
            }

            override fun onTabUnselected(tab: TabLayout.Tab?) {
                tab!!.view.setBackgroundColor(Color.TRANSPARENT)
            }

            override fun onTabReselected(tab: TabLayout.Tab?) {
            }
        })

RecyclerViewAdapter

구현방법

1. 자신의 리사이클러뷰 어댑터에 Filterable을 상속받는다.
2. 액티비티에서 받아온 텍스트(필터링하고 싶은 단어)를 아이템의 텍스트와 비교해서 일치하면 filteringList에 item을 넣어준다. (나는 itme.type과 비교했다.)

3. 받아온 String 값이 공백(" ")이면 필터링이 안된 전체 리스트를(unfilterdList)를 보여준다.

RecyclerViewAdapter.kt

class RecyclerViewAdapter(items: ArrayList<UnitsDto?>?) : RecyclerView.Adapter<RecyclerView.ViewHolder>(), Filterable
{
  
    private var context:Context? = null
    private var unFilteredList = items
    private var filteredList = items


    override fun getFilter(): Filter {
        return object : Filter() {
            override fun performFiltering(constraint: CharSequence?): FilterResults {
                val charString = constraint.toString()
                filteredList = if (charString.isEmpty()) {
                    unFilteredList
                } else {
                    val filteringList = ArrayList<UnitsDto?>()
                    for (item in unFilteredList!!) {
                        if (item!!.type == charString) filteringList.add(item)
                    }
                    filteringList
                }
                val filterResults = FilterResults()
                filterResults.values = filteredList
                return filterResults
            }

            override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
                filteredList = results?.values as ArrayList<UnitsDto?>?
                notifyDataSetChanged()
            }
        }

    }
    `
    `
    `//이하 생략



}

결과물

LEARNING, GAME 2가지 키워드가 포함된 리스트만 볼 수 있는 리사이클러뷰 완성!

👩‍💻리사이클러뷰 무한스크롤 구현해보기

1개의 댓글

comment-user-thumbnail
2022년 1월 11일

이렇게하면 혹시 unFilteredList 와 filteredList의 메모리가 같아져서 필터링이 중복으로 걸리진 않을까요?
unFiltered에서 새로 계속 필터링 걸어야하는데 filteredList에 삽입할때 unFilteredList에서도 같은 리스트로 들어가는 현상? 궁금해서 질문드립니다 ㅎㅎ

답글 달기