【问题标题】:Having trouble with SearchView, won't filterSearchView 出现问题,无法过滤
【发布时间】:2020-07-15 01:56:03
【问题描述】:

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

MainActivity.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

【问题讨论】:

    标签: android kotlin filter android-recyclerview searchview


    【解决方案1】:

    您的过滤结果似乎存储在dataFilerList 中。但是dataFilerList 不会在您的适配器中的任何地方使用。

    因此,不要“绑定”数据并从 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()
            }
    
    
        }
    }
    

    【讨论】:

    • 您好,问题似乎没有解决。
    • 嗯,我明白了,很遗憾,这似乎也没有用。不知道是适配器有问题还是有其他问题。
    • 在我的机器 (TM) 上工作。仔细检查你的代码和我的代码。
    • 看来我遗漏了一些东西,可能在 xml 文件或 android 清单中有所不同。你介意分享一下吗?
    • 嗨,我终于找到了问题所在。由于数据为空,因此位于 onCreateOptionsMenu 下的 MainActivity 中。不过谢谢楼主的帮助,真的很感谢。我对编码很陌生,因为我现在正在学习它。 +1
    猜你喜欢
    • 2017-11-02
    • 1970-01-01
    • 2020-06-28
    • 1970-01-01
    • 1970-01-01
    • 2016-07-08
    • 1970-01-01
    • 1970-01-01
    • 2012-12-11
    相关资源
    最近更新 更多