SearchView 有问题,不会过滤

Having trouble with SearchView, won't filter

正在尝试使用 searchview 从 recyclerview 过滤我的 json 数据。 recyclerview 工作正常,我可以列出数据,单击它们并获取我想要的。但是我无法过滤数据的名称。

MainAcctivity.kt

class MainActivity : AppCompatActivity() {

// Declare Variables
lateinit var adapter: MainAdapter
lateinit var recyclerView: RecyclerView

val studentDb = BaseDataBase(this)


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

    recyclerView = findViewById(R.id.recyclerView)
    recyclerView.layoutManager = LinearLayoutManager(this)
    recyclerView.setHasFixedSize(true)



    fetchJson()
}

private fun fetchJson() {
    println("Attempting to FetchJson")


    val url = HttpUrl.Builder()
        .scheme("https")
        .host("www.noforeignland.com")
        .addPathSegment("home")
        .addPathSegment("api")
        .addPathSegment("v1")
        .addPathSegment("places")
        .build()
        println(url)

    val request = Request.Builder()
        .url(url)
        .cacheControl(CacheControl.Builder().noCache().build())
        .build()

    val client = OkHttpClient()
    client.newCall(request).enqueue(object : Callback {

        override fun onResponse(call: Call, response: Response) {
            val body = response.body?.string()
            println(body)

            val gson = GsonBuilder().create()

            val list = mutableListOf<Properties>()
            when(response.code) {
                200 ->{
                    Thread(Runnable {

                    })
                }
            }

            val homeFeed = gson.fromJson(body, Assigment::class.java)


            runOnUiThread {
                adapter = MainAdapter(homeFeed)
                recyclerView.adapter = adapter

            }
        }

        override fun onFailure(call: Call, e: IOException) {
            println("Failed to execute request")
        }
    })

}


override fun onCreateOptionsMenu(menu: Menu?): Boolean {
    val manager = getSystemService(Context.SEARCH_SERVICE) as SearchManager
    val searchItem = menu?.findItem(R.id.searchView2)
    val searchView = searchItem?.actionView as? SearchView

    searchView?.setSearchableInfo(manager.getSearchableInfo(componentName))

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

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

}

}

MainAdapter.kt

class MainAdapter(var homeFeed: Assigment) : RecyclerView.Adapter<MainAdapter.CustomViewHolder>(), Filterable {

    lateinit var dataFilerList : Assigment


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

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
    val layoutInflater = LayoutInflater.from(parent?.context)
    val cellForRow = layoutInflater.inflate(R.layout.activity_data, parent, false)
    return CustomViewHolder(cellForRow)
}

override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
    val model = homeFeed.features.get(position)
    holder?.view?.texViewTitle?.text = model.properties.name

    holder?.jsonData = model

}


class CustomViewHolder(val view: View, var jsonData: Feature? = null) : RecyclerView.ViewHolder(view) {




    companion object {
        val title_key = "title"
        val id_key = "id"
        val latitude_key = "latitude"
        val longitude_key = "longitude"
    }

    init {
        view.setOnClickListener {
            val intent = Intent(view.context, CourseDetailActivity::class.java)

            intent.putExtra(title_key, jsonData?.properties?.name)
            intent.putExtra(id_key, jsonData?.properties?.id)

            view.context.startActivity(intent)
        }

        view.gps_view.setOnClickListener{
            val intent = Intent(view.context, MapsActivity::class.java)

            intent.putExtra(title_key, jsonData?.properties?.name)
            intent.putExtra(latitude_key, jsonData?.geometry?.coordinates?.last())
            intent.putExtra(longitude_key, jsonData?.geometry?.coordinates?.first())

            view.context.startActivity(intent)
        }

    }

}


override fun getFilter(): Filter {
    return object : Filter() {
        override fun performFiltering(charString: CharSequence?): FilterResults {
            val charsearch = charString?.toString()?.toLowerCase()
            if (charsearch!!.isEmpty()) {
                dataFilerList = homeFeed
            } else {
                val resultList = ArrayList<Feature>()
                for (row in homeFeed.features) {
                    if (row.properties.name.toLowerCase().contains(charsearch.toLowerCase())
                    ) {
                        resultList.add(row)
                    }
            }
        }

        val filterResult = FilterResults()
        filterResult.values = dataFilerList
        return filterResult
    }

        override fun publishResults(charSequence: CharSequence?, filterResults: FilterResults) {
            dataFilerList = (filterResults.values as? Assigment)!!
            notifyDataSetChanged()
        }


    }
}

}

Assigment.kt

data class Assigment(
val features: List<Feature>,
val type: String

)

我确实知道可能出了什么问题,但我对 kotlin 还是很陌生。

App screenshot

您的筛选结果似乎存储在 dataFilerList 中。但是 dataFilerList 没有在您的适配器中的任何地方使用。

因此,不是 "binding" 数据并从 homeFeed 获取大小,而是将显示的数据基于 dataFilerList

初始化 dataFilerList 等于 homeFeed

class MainAdapter(homeFeed: Assigment) : RecyclerView.Adapter<MainAdapter.CustomViewHolder>(), Filterable {

    var dataFilerList: Assigment
    init {
        dataFilerList = homeFeed
    }


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

...

override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
    val model = dataFilerList.features.get(position)
    holder?.view?.texViewTitle?.text = model.properties.name

    holder?.jsonData = model

}
...

让我知道这是否解决了问题。

编辑:

过滤器中还有另一个问题,您没有将过滤后的 resultList 设置为 dataFilerList。所以过滤后的结果实际上丢失了。

override fun getFilter(): Filter {
    return object : Filter() {
        override fun performFiltering(charString: CharSequence?): FilterResults {
            val charsearch = charString?.toString()?.toLowerCase()
            if (charsearch!!.isEmpty()) {
                dataFilerList = homeFeed
            } else {
                val resultList = ArrayList<Feature>()
                for (row in homeFeed.features) {
                    if (row.properties.name.toLowerCase().contains(charsearch.toLowerCase())
                    ) {
                        resultList.add(row)
                    }
                }
                dataFilerList = Assigment(resultList, homeFeed.type)
            }

            val filterResult = FilterResults()
            filterResult.values = dataFilerList
            return filterResult
        }

        override fun publishResults(charSequence: CharSequence?, filterResults: FilterResults) {
            dataFilerList = (filterResults.values as? Assigment)!!
            notifyDataSetChanged()
        }


    }
}