首页 > 解决方案 > 如何在listview kotlin中添加搜索过滤器栏

问题描述

我已经创建了一个列表视图并且代码工作正常。还创建了一个搜索框。我想根据列表的特定字段实现搜索功能。l 在分离类中使用的列表适配器不在主要活动类中。我想在类列表适配器中使用搜索栏过滤器。

主要活动课

package com.iraqairoirt.iraqairports

import android.app.AlertDialog
import android.os.AsyncTask
import android.support.design.widget.TabLayout
import android.support.v7.app.AppCompatActivity

import android.support.v4.app.Fragment
import android.support.v4.app.FragmentManager
import android.support.v4.app.FragmentPagerAdapter
import android.os.Bundle

import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.fragment_arrivel.*
import kotlinx.android.synthetic.main.fragment_dep.*
import org.json.JSONArray
import org.json.JSONObject
import java.net.HttpURLConnection
import java.net.URL

import android.widget.TextView
import com.iraqairoirt.iraqairports.flightsDep.ListAdapteDep
import com.iraqairoirt.iraqairports.flightsArr.ListAdapteArr


    class MainActivity : AppCompatActivity() {


        private var mSectionsPagerAdapter: SectionsPagerAdapter? = null

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




            val url = "xxxxxxxxxxxxxxxxxxxxxxx"
            Arr().execute(url)
            Dep().execute(url)


            setSupportActionBar(toolbar)
            // Create the adapter that will return a fragment for each of the three
            // primary sections of the activity.
            mSectionsPagerAdapter = SectionsPagerAdapter(supportFragmentManager)

            // Set up the ViewPager with the sections adapter.
            container.adapter = mSectionsPagerAdapter

            container.addOnPageChangeListener(TabLayout.TabLayoutOnPageChangeListener(tabs))
            tabs.addOnTabSelectedListener(TabLayout.ViewPagerOnTabSelectedListener(container))


        }
        //    full class for json api
        inner class Arr : AsyncTask<String, String, String>(){

            val progressDialog = AlertDialog.Builder(this@MainActivity)
            val dialogView = layoutInflater.inflate(R.layout.progress_dialog,null)
            val message = dialogView.findViewById<TextView>(R.id.message_id)
            val dialog = progressDialog.create()

            override fun onPreExecute() {
                super.onPreExecute()

                dialog.setMessage("loading")
                dialog.setCancelable(false)
                dialog.show()


            }

            //        for build connection
            override fun doInBackground(vararg url: String?): String{

                var text : String
                val connection = URL(url[0]).openConnection() as HttpURLConnection

                try {
                    connection.connect()
                    text = connection.inputStream.use { it.reader().use{reader -> reader.readText()} }


                } finally{

                    connection.disconnect()

                }
                return text
            }

            override fun onPostExecute(result: String?) {

                super.onPostExecute(result)
                handleJson(result)

                dialog.dismiss();

            }

            override fun onProgressUpdate(vararg text: String?) {


            }
            private fun handleJson (jsonString: String?){

                val schedule = pluginData.getJSONObject("schedule")
                val arrivals = schedule.getJSONObject("arrivals")
    //        val data = arrivals.getJSONObject("data")
                val jsonArray = JSONArray(arrivals.get("data").toString())

                val list =  ArrayList<FlightShdu>()
                var x = 0
                while (x < jsonArray.length()){

                    val jsonObject = jsonArray.getJSONObject(x)



                    list.add(FlightShdu(
                        jsonObject.getJSONObject("flight").getJSONObject("identification").getJSONObject("number").getString("default"),
                        jsonObject.getJSONObject("flight").getJSONObject("airline").getString("short"),
                        jsonObject.getJSONObject("flight").getJSONObject("status").getJSONObject("generic").getJSONObject("status").getString("text"),
                        jsonObject.getJSONObject("flight").getJSONObject("airline").getJSONObject("code").getString("icao"),
                        jsonObject.getJSONObject("flight").getJSONObject("time").getJSONObject("scheduled").getString("arrival"),
                        jsonObject.getJSONObject("flight").getJSONObject("airport").getJSONObject("origin").getJSONObject("code").getString("iata"),
                        jsonObject.getJSONObject("flight").getJSONObject("aircraft").getJSONObject("model").getString("text"),
    //                    for more information
                        jsonObject.getJSONObject("flight").getJSONObject("time").getJSONObject("real").getString("departure"),
                        jsonObject.getJSONObject("flight").getJSONObject("time").getJSONObject("estimated").getString("arrival"),
    //                    jsonObject.getJSONObject("flight").getJSONObject("time").getJSONObject("estimated").getString("arrival"),
                        jsonObject.getJSONObject("flight").getJSONObject("aircraft").getString("registration"),
                        jsonObject.getJSONObject("flight").getJSONObject("status").getJSONObject("generic").getJSONObject("status").getString("diverted"),
                        arrivals.getString("timestamp"),
                        jsonObject.getJSONObject("flight").getJSONObject("status").getString("icon")





                        ))


                    x++
                }
                list.forEach(::println)

                val adapter = ListAdapteArr(this@MainActivity, list)
                flight_arrivel_list.adapter = adapter




            }




        }




        /**
         * A [FragmentPagerAdapter] that returns a fragment corresponding to
         * one of the sections/tabs/pages.
         */
        inner class SectionsPagerAdapter(fm: FragmentManager) : FragmentPagerAdapter(fm) {

            override fun getItem(position: Int): Fragment? {

                return when (position) {
                    0 -> {
                        fragment_Arr()
                    }
                    1 ->{

                        fragment_Dep()
                    }
                    2->{
                        fragment_Weather()
                    }
                    else-> {
                        return null
                    }
                }

            }

            override fun getCount(): Int {
                // Show 3 total pages.
                return 2
            }

        }


    }

列表适配器

   class ListAdapteArr (val context: MainActivity, val list: ArrayList<FlightShdu>): BaseAdapter() {
        @SuppressLint("ViewHolder", "NewApi")
        override fun getView(p0: Int, convertView: View?, parent: ViewGroup?): View {

            val view : View = LayoutInflater.from(context).inflate(R.layout.arr_list,parent,false)


            val searchBar = view.findViewById(R.id.searchFlightId) as MaterialSearchBar

            Airport.text= list.Airport




            return view

        }




        override fun getItem(p0: Int): Any {
            return list [p0]
        }

        override fun getItemId(p0: Int): Long {
            return p0.toLong()
        }

        override fun getCount(): Int {
            return list.size
        }



    }

xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    <ListView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/flight_arrivel_list"
            style="@style/Widget.AppCompat.ListView"
            android:paddingStart="10sp"
            android:paddingEnd="10sp"
            android:paddingTop="0dp" android:layout_alignParentStart="true" android:layout_alignParentTop="true"
            android:layout_marginTop="58dp" android:layout_marginStart="0dp"/>
    <com.mancj.materialsearchbar.MaterialSearchBar
            style="@style/MaterialSearchBarLight"
            app:mt_speechMode="true"
            app:mt_hint="Custom hint"
            app:mt_maxSuggestionsCount="10"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/searchBar" />


</RelativeLayout>

在此处输入图像描述

l 添加了搜索栏过滤器来搜索列表视图中的任何项目,但仍然没有功能可以做到这一点

标签: androidlistviewkotlin

解决方案


在您的活动中,在您的列表中执行搜索并重新分配值(保留 a val baseListvar filteredList因此如果需要,您可以默认返回原始值。首先,我们要将嵌套适配器移动到活动的顶部,以便我们可以访问它在它实例化之后。我们还想为此使用两个列表,baseList就像filteredListprivate lateinit var adapter: ListAdapteArr? = null在活动顶部的下面一样。

private lateinit var adapter: ListAdapteArr? = null

private var baseList: List<FlightShdu> = listOf()
private var filteredList: MutableList<FlightShdu> = mutableListOf()

在您的handleJson()方法中,一旦列表中填充了所有FlightShdu对象,请将其分配给baseList

baseList = list

然后分配你的private lateinit var adapter

 adapter = ListAdapteArr(this@MainActivity, baseList)
                flight_arrivel_list.adapter = adapter

有一种方法可以获取编辑文本搜索词并将其与您的列表进行比较

   fun searchList() {
       filteredList.clear()
       baseList.forEach { 
       if (it.contains(search.text.toString())) {
          filteredList.add(it)
       }
    }
    adapter.updateList(filteredList)

然后在您的适配器更改中:

val list: ArrayList<FlightShdu>var list: ArrayList<FlightShdu>

并有一个方法,如:

 fun updateList(filteredList: List<FlightShdu>) {
    list.clear()
    list.addAll(filteredList)
    notifyDataSetChanged()
 }

使用活动中的更新列表,调用该方法adapter.updateList(filteredList)

我还建议使用 arecyclerview而不是listview RecyclerView 与 ListView

您还可以考虑使用DiffUtils它,因为它在适配器中的列表之间转换时提供了很好的平滑动画。这个答案只是为了让你滚蛋。

val diffResult = DiffUtil.calculateDiff(object : DiffUtil.Callback() {

                override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean = newList[newItemPosition] == oldList[oldItemPosition]

                override fun getOldListSize(): Int = oldList.size

                override fun getNewListSize(): Int = newList.size

                override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean = newList[newItemPosition] == oldList[oldItemPosition]
            }

diffResult.dispatchUpdatesTo(adapter)

推荐阅读