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()
}
}
}
正在尝试使用 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()
}
}
}