Hallo Selamat sore, lama tidak berjumpa nih, pada kesempatan kali ini rackspira akan berbagi tutorial untuk membuat searchview pada expandablelistview nih.

 

Expandablelistview sendiri merupakan sebuah list yang di dalamnya terdapat sebuah listview lagi,pada konsepnya searchview pada expandable hampir mirip pada searchview di list biasa hanya saja kita memerlukan perulangan tambahan untuk melakukan pencarian pada list yang menjadi child atau list yang ada pada listview.

 

Hasil nya kurang lebih akan seperti berikut

Tampilan awal

hasil searchview

 

Nah langsung satu, pertama buat sebuah projek baru di androdi studio, pada tutorial ini rackspira menggunakan bahasa pemrograman kotlin.


Setelah berhasil membuat projek baru, kita harus membuat tampilan untuk expandablelist, 

untuk tampilan silahkan di sesuaikan dengan kreatifitas masing masing ya

main.xml

<?xml version='1.0' encoding='utf-8'?>
<android.support.constraint.ConstraintLayout
        xmlns:android='http://schemas.android.com/apk/res/android'
        xmlns:tools='http://schemas.android.com/tools'
        xmlns:app='http://schemas.android.com/apk/res-auto'
        android:layout_width='match_parent'
        android:layout_height='match_parent'
        tools:context='.MainActivity'>

    <SearchView android:layout_width='match_parent' android:layout_height='wrap_content'
    android:id='@+id/searchView'
                app:layout_constraintTop_toTopOf='parent'
                app:layout_constraintStart_toStartOf='parent'
                app:layout_constraintEnd_toEndOf='parent'/>

    <ExpandableListView android:layout_width='match_parent'
                        android:layout_height='wrap_content'
                        android:id='@+id/expandableList'
                        app:layout_constraintTop_toBottomOf='@id/searchView'
                        app:layout_constraintStart_toStartOf='parent'
                        app:layout_constraintEnd_toEndOf='parent'/>
</android.support.constraint.ConstraintLayout>

 

Kemudian kita harus membuat list untuk group dan child nya, group akan menjadi list header, dan child akan menjadi list yang berada di dalam group

header.xml

<?xml version='1.0' encoding='utf-8'?>
<LinearLayout
        xmlns:android='http://schemas.android.com/apk/res/android'
        xmlns:tools='http://schemas.android.com/tools' android:layout_width='match_parent'
        android:layout_height='match_parent'
        android:orientation='vertical'>

    <TextView
            android:id='@+id/listTitle'
            android:layout_width='match_parent'
            android:layout_height='wrap_content'
            android:paddingBottom='10dp'
            android:paddingStart='?android:attr/expandableListPreferredItemPaddingLeft'
            android:paddingTop='10dp'
            android:textColor='@android:color/black' tools:ignore='RtlSymmetry'/>

</LinearLayout>

child.xml

<LinearLayout
        xmlns:android='http://schemas.android.com/apk/res/android'
        xmlns:tools='http://schemas.android.com/tools' android:layout_width='match_parent'
        android:layout_height='wrap_content'
        android:orientation='vertical'>

    <TextView
            android:id='@+id/expandedListItem'
            android:layout_width='match_parent'
            android:layout_height='wrap_content'
            android:paddingBottom='10dp'
            android:paddingStart='?android:attr/expandableListPreferredChildPaddingLeft'
            android:paddingTop='10dp' tools:ignore='RtlSymmetry'/>

</LinearLayout>

Setelah tampilan sudah selesai kita persiapkan, selanjutnya kita harus membuat model yang akan menampung data dari list yang akan kita buat, model yang kita bikin juga terdiri dari file yaitu model untuk provinsi yang sebagai title dan model untuk kabupaten/kota sebagai child

title.kt

class TitleModel(val name:String,
                 var dataChild:MutableList<ChildModel>)

child.kt

class ChildModel(val name:String) {
}

 

nah setalah kita selesai membuat model yang di butuhkan selanjutnya kita membuat adapter untuk expandablelist kita, di dalam expandablelist ini kita akan mengimplementasikan BaseExpandablelist yang sudah menjadi bawaan untuk mengatur list nya serta Filterable yang akan di gunakan untuk melakuan filtering data dari kata kunci yang kita masukkan

 

ExpandableAdapter.kt

class ExpandableAdapter(private val context: Context, private val titleList: MutableList<TitleModel>) :
    BaseExpandableListAdapter(), Filterable {

    var itemsCopy: List<TitleModel> = titleList
    var expanAll = false
    override fun getGroup(groupPosition: Int): Any {
        return itemsCopy[groupPosition].name
    }

    override fun isChildSelectable(groupPosition: Int, childPosition: Int): Boolean {
        return true
    }

    override fun hasStableIds(): Boolean {
        return false
    }

    @SuppressLint('InflateParams')
    override fun getGroupView(groupPosition: Int, isExpanded: Boolean, convertView: View?, parent: ViewGroup?): View {
        var convertView = convertView
        val title = titleList[groupPosition].name
        val mExpandableListView = parent as ExpandableListView
        Log.d('isian', '${titleList[groupPosition].name}  $groupPosition')
        if (expanAll) {
            mExpandableListView.expandGroup(groupPosition)
        } else {
            mExpandableListView.collapseGroup(groupPosition)
        }

        if (convertView == null) {
            val layoutInflater = this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
            convertView = layoutInflater.inflate(R.layout.header_layout, null)
        }

        val listTitle = convertView!!.findViewById<TextView>(R.id.listTitle)
        listTitle.setTypeface(null, Typeface.BOLD)
        listTitle.text = title
        return convertView
    }

    override fun getChildrenCount(groupPosition: Int): Int {
        return itemsCopy[groupPosition].dataChild.size
    }

    override fun getChild(groupPosition: Int, childPosition: Int): Any {
        return itemsCopy[groupPosition].dataChild[childPosition].name
    }

    override fun getGroupId(groupPosition: Int): Long {
        return groupPosition.toLong()
    }

    override fun getChildView(
        groupPosition: Int,
        childPosition: Int,
        isLastChild: Boolean,
        convertView: View?,
        parent: ViewGroup?
    ): View {
        var convertView = convertView
        val expandedListText = getChild(groupPosition, childPosition) as String
        if (convertView == null) {
            val layoutInflater = this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
            convertView = layoutInflater.inflate(R.layout.child_layout, null)
        }
        val expandedListTextView = convertView!!.findViewById<TextView>(R.id.expandedListItem)
        expandedListTextView.text = expandedListText
        return convertView

    }

    override fun getChildId(groupPosition: Int, childPosition: Int): Long {
        return childPosition.toLong()
    }

    override fun getGroupCount(): Int {
        return itemsCopy.size
    }

    override fun getFilter(): Filter {

        return object : Filter() {
            override fun performFiltering(charSequence: CharSequence): Filter.FilterResults {
                val charString = charSequence.toString()

                if (charString.isEmpty()) {
                    itemsCopy = titleList
                } else {

                     val filteredList = arrayListOf<TitleModel>()
                    expanAll = true
                    for (row in titleList.indices) {

                        val cities = titleList[row].dataChild
                        val citiesnew :MutableList<ChildModel> = mutableListOf<ChildModel>()

                        for(city in cities){
                            if(city.name.toLowerCase().contains(charString.toLowerCase())){
                                citiesnew.add(city)
                            }
                        }

                        if(citiesnew.size > 0){
                            filteredList.add(TitleModel(titleList[row].name,citiesnew))
                        }

                    }

                    itemsCopy = filteredList
                }
                val filterResults = Filter.FilterResults()
                filterResults.values = itemsCopy
                return filterResults
            }

            override fun publishResults(charSequence: CharSequence, filterResults: Filter.FilterResults) {
                itemsCopy = filterResults.values as List<TitleModel>
                notifyDataSetChanged()
            }
        }
    }
}

 

Jika semua sudah selesai di bikin, langkah terakhir kita tinggal memanggilnyaa di dalam class activity seperti kita mendeklarsikan list biasa

MainActivity.kt

class MainActivity : AppCompatActivity() {

    private  var listtitleModel: MutableList<TitleModel> = mutableListOf()
    private lateinit var adapter: ExpandableAdapter

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

        val child1 : MutableList<ChildModel>  = mutableListOf()
        child1.add(ChildModel('Solo'))
        child1.add(ChildModel('Wonogiri'))
        child1.add(ChildModel('Semarang'))
        child1.add(ChildModel('Wonosobo'))

        val child2 : MutableList<ChildModel>  = mutableListOf()
        child2.add(ChildModel('Bantul'))
        child2.add(ChildModel('Sleman'))
        child2.add(ChildModel('Gunung Kidul'))
        child2.add(ChildModel('Kulon Progo'))

        val child3 : MutableList<ChildModel>  = mutableListOf()
        child3.add(ChildModel('Pacitan'))
        child3.add(ChildModel('Ponorogo'))
        child3.add(ChildModel('Surabaya'))
        child3.add(ChildModel('Jember'))

        listtitleModel.add(TitleModel('Jawa Tengah',child1))
        listtitleModel.add(TitleModel('Yogyakarta',child2))
        listtitleModel.add(TitleModel('Jawa Timur',child3))


        adapter = ExpandableAdapter(this,listtitleModel)
        expandableList.setAdapter(adapter)

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

            override fun onQueryTextChange(newText: String?): Boolean {
               adapter.filter.filter(newText)
                return false
            }

        })
    }


}

 

Cukup mudah bukan??

ouh iya bagi yang ingin mendapatkan source code nya dapat langsung clone dari github berikut ini :

https://github.com/blank15/ExpandablelistviewSearch

 

Sekian tutorial pada sore hari ini semoga bisa menambah pengetahuan teman teman semua, 

Salam RackEdanRackSpiro

Share :

0 Komentar

Berikan Komentar

*Komentar yang memuat konten kurang pantas akan dihapus secara permanen



Apabila Anda ingin membuat artikel untuk kami sertakan dalam daftar artikel website kami, silakan submit artikel Anda disini

Rack Edan, Rack Spira