SearchView 在回收站视图中不起作用
Posted
技术标签:
【中文标题】SearchView 在回收站视图中不起作用【英文标题】:SearchView in Not Working in Recycler View 【发布时间】:2021-11-02 07:18:33 【问题描述】:我正在尝试在 recyclerview 上添加 searchview,但它无法正常工作,甚至没有显示任何错误。我在***上准备了很多答案,但它们对我不起作用。请告诉我我的代码中有什么错误。当我调试我的代码时,搜索的值显示在结果变量中,但没有显示在 recyclerview 中。我想搜索 1) 国家名称 2) 大写 3) 和 id 可以帮助我
我的适配器在这里
class ProfileListAdapter(var profiles:ArrayList<Profile>):RecyclerView.Adapter<ProfileListAdapter.ProfileViewHolder>(),Filterable
fun updateProfile(newProfiles:List<Profile>)
profiles.clear()
profiles.addAll(newProfiles)
notifyDataSetChanged()
var profileFilterList = ArrayList<Profile>()
init
profileFilterList = profiles
class ProfileViewHolder(view: View):RecyclerView.ViewHolder(view)
private var id = view.findViewById<TextView>(R.id.tv_id)
private var name = view.findViewById<TextView>(R.id.tv_name)
private var fatherName = view.findViewById<TextView>(R.id.tv_father_name)
private var profileImage = view.findViewById<ImageView>(R.id.iv_profile_image)
private var progressDrawable = getProgressDrawable(view.context)
fun bind(profile: Profile)
id.text = profile.id.toString()
name.text = profile.name
fatherName.text = profile.fatherName
profileImage.loadImage(profile.profilePicture,progressDrawable)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ProfileViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.rv_dummy_items,parent,false)
)
override fun onBindViewHolder(holder: ProfileViewHolder, position: Int)
holder.bind(profiles[position])
override fun getItemCount() = profiles.size
// Search items
override fun getFilter(): Filter
return object : Filter()
override fun performFiltering(constraint: CharSequence?): FilterResults
val charString = constraint?.toString() ?: ""
if (charString.isEmpty())
profiles.also profileFilterList = it
else
val filteredList = ArrayList<Profile>()
profiles
.filter
(it.name.contains(constraint!!)) or (it.fatherName.contains(constraint))
.forEach filteredList.add(it)
profileFilterList = filteredList
return FilterResults().apply values = profileFilterList
override fun publishResults(constraint: CharSequence?, results: FilterResults?)
profileFilterList = if (results?.values == null) ArrayList()
else
results.values as ArrayList<Profile>
notifyDataSetChanged()
我的主要活动在这里
class MainActivity : AppCompatActivity()
lateinit var binding: ActivityMainBinding
lateinit var viewModel: ListViewModel
var profileAdapter = ProfileListAdapter(arrayListOf())
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
//here I'm calling search profile function
searchProfile()
//
viewModel = ViewModelProviders.of(this).get(ListViewModel::class.java)
viewModel.refresh()
binding.rvProfileList.apply
layoutManager = LinearLayoutManager(context)
adapter = profileAdapter
observeViewModel()
filterButtons()
fun observeViewModel()
viewModel.profiles.observe(this, Observer profiles: List<Profile>? ->
profiles?.let
binding.rvProfileList.visibility = View.VISIBLE
profileAdapter.updateProfile(it)
)
viewModel.profileLoadingError.observe(this, Observer isError: Boolean? ->
isError?.let
binding.listError.visibility = if (it) View.VISIBLE else View.GONE
)
viewModel.loading.observe(this, Observer isLoading ->
isLoading?.let
binding.loadingView.visibility = if (it) View.VISIBLE else View.GONE
)
//search function
fun searchProfile()
binding.searchView.setOnQueryTextListener(object: SearchView.OnQueryTextListener
override fun onQueryTextSubmit(query: String?): Boolean
profileAdapter.filter.filter(query)
return false
override fun onQueryTextChange(newText: String?): Boolean
profileAdapter.filter.filter(newText)
return false
)
【问题讨论】:
请修剪您的代码,以便更容易找到您的问题。请按照以下指南创建minimal reproducible example。 【参考方案1】:你的代码质量真的很差。我反复阅读以了解您的意思。
首先,您在 OnQueryTextListener 中进行了两次过滤。相反,您只能过滤一次。将您的 searchProfile 函数更改为
fun searchProfile()
binding.searchView.setOnQueryTextListener(object: SearchView.OnQueryTextListener
override fun onQueryTextSubmit(query: String?): Boolean
return false
override fun onQueryTextChange(newText: String?): Boolean
profileAdapter.filter.filter(newText)
return false
)
您的失败可能是因为重新分配了您的 profiles 和 profileFilterList 列表。
在少数情况下,您将 profiles 分配给 profileFilterList,而不是复制!两个列表都有相同的引用。因此,如果其中一个发生变化,其他列表会直接发生变化。
从
更改您的适配器初始化块init
profileFilterList = profiles
到
init
profileFilterList = ArrayList(profiles)
从
更改您的 getFilter 函数 override fun getFilter(): Filter
return object : Filter()
override fun performFiltering(constraint: CharSequence?): FilterResults
val charString = constraint?.toString() ?: ""
if (charString.isEmpty())
profiles.also profileFilterList = it
else
val filteredList = ArrayList<Profile>()
profiles
.filter
(it.name.contains(constraint!!)) or (it.fatherName.contains(constraint))
.forEach filteredList.add(it)
profileFilterList = filteredList
return FilterResults().apply values = profileFilterList
override fun publishResults(constraint: CharSequence?, results: FilterResults?)
profileFilterList = if (results?.values == null) ArrayList()
else
results.values as ArrayList<Profile>
notifyDataSetChanged()
到
override fun getFilter(): Filter
return object : Filter()
override fun performFiltering(constraint: CharSequence?): FilterResults
val filteredList = mutableListOf<Profile>()
if (constraint == null || constraint.isEmpty())
filteredList.addAll(profiles)
else
filteredList.addAll(
profiles.filter (it.name.contains(constraint!!)) or (it.fatherName.contains(constraint)) )
return FilterResults().apply values = filteredList
override fun publishResults(constraint: CharSequence?, results: FilterResults?)
profileFilterList.clear()
results?.values?.let
profileFilterList.addAll(it as MutableList<Profile>)
notifyDataSetChanged()
【讨论】:
非常感谢您的回答。先生,它仍然无法正常工作 你能解释一下'不工作'是什么意思吗? 表示当我搜索某些东西时,它不搜索 提交答案后,我稍作修改。你可以试试当前的代码吗?【参考方案2】:我在您的适配器中进行编辑,并且过滤器在修改后对我的代码正常工作
class ProfileListAdapter():RecyclerView.Adapter<ProfileListAdapter.ProfileViewHolder>(),Filterable
var profileList: ArrayList<Profile> = ArrayList()
var profileListFiltered: ArrayList<Profile> = ArrayList()
fun updateProfile(newProfiles:List<Profile>)
profileList = ArrayList(newProfiles)
profileListFiltered = profileList
notifyDataSetChanged()
class ProfileViewHolder(view: View):RecyclerView.ViewHolder(view)
private var id = view.findViewById<TextView>(R.id.tv_id)
private var name = view.findViewById<TextView>(R.id.tv_name)
private var fatherName = view.findViewById<TextView>(R.id.tv_father_name)
private var profileImage = view.findViewById<ImageView>(R.id.iv_profile_image)
private var progressDrawable = getProgressDrawable(view.context)
fun bind(profile: Profile)
id.text = profile.id.toString()
name.text = profile.name
fatherName.text = profile.fatherName
profileImage.loadImage(profile.profilePicture,progressDrawable)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
ProfileViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.rv_dummy_items,parent,false)
)
override fun onBindViewHolder(holder: ProfileViewHolder, position: Int)
holder.bind(profileListFiltered[position])
override fun getItemCount() = profileListFiltered.size
// Search items
override fun getFilter(): Filter
return object : Filter()
override fun performFiltering(constraint: CharSequence?): FilterResults
val charString = constraint?.toString() ?: ""
if (charString.isEmpty())
profileListFiltered = profileList
else
val filteredList = ArrayList<Profile>()
profileList
.filter
(it.name.contains(constraint!!)) or
(it.fatherName.contains(constraint))
.forEach filteredList.add(it)
profileFilterList = filteredList
return FilterResults().apply values = profileFilterList
override fun publishResults(constraint: CharSequence?, results:
FilterResults?)
profileFilterList = if (results?.values == null) ArrayList()
else
results.values as ArrayList<Profile>
notifyDataSetChanged()
在您的活动中,只需在使用适配器 updateProfile 中的函数获取数据后声明不带参数构造函数的适配器,然后您的 ISA 即可正常工作
为您的适配器编辑
class ProfileListAdapter(var
profiles:ArrayList<Profile>)
:RecyclerView.Adapter<ProfileListAdapter.Profile
ViewHolder>(),Filterable
fun updateProfile(newProfiles:List<Profile>)
profiles.clear()
profiles.addAll(newProfiles)
notifyDataSetChanged()
var profileFilterList = ArrayList<Profile>()
init
profileFilterList = profiles
class ProfileViewHolder(view: View):RecyclerView.ViewHolder(view)
private var id = view.findViewById<TextView>(R.id.tv_id)
private var name = view.findViewById<TextView>(R.id.tv_name)
private var fatherName = view.findViewById<TextView>
(R.id.tv_father_name)
private var profileImage = view.findViewById<ImageView>
(R.id.iv_profile_image)
private var progressDrawable = getProgressDrawable(view.context)
fun bind(profile: Profile)
id.text = profile.id.toString()
name.text = profile.name
fatherName.text = profile.fatherName
profileImage.loadImage(profile.profilePicture,progressDrawable)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
ProfileViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.rv_dummy_items,parent,false)
)
override fun onBindViewHolder(holder: ProfileViewHolder, position:
Int)
holder.bind(profileFilterList[position])
override fun getItemCount() = profileFilterList.size
// Search items
override fun getFilter(): Filter
return object : Filter()
override fun performFiltering(constraint: CharSequence?):
FilterResults
val charString = constraint?.toString() ?: ""
if (charString.isEmpty())
profileFilterList = profiles
else
val filteredList = ArrayList<Profile>()
profiles
.filter
(it.name.contains(constraint!!)) or
(it.fatherName.contains(constraint))
.forEach filteredList.add(it)
profileFilterList = filteredList
return FilterResults().apply values = profileFilterList
override fun publishResults(constraint: CharSequence?, results:
FilterResults?)
profileFilterList = if (results?.values == null) ArrayList()
else
results.values as ArrayList<Profile>
notifyDataSetChanged()
【讨论】:
如果我删除此行:profiles.addAll(newProfiles) 则列表未显示,如果我添加此行则搜索不起作用 这是适配器工作与你合作?@faizdev @faizdev 您的适配器没有问题您使用配置文件列表绑定视图并为其返回计数您必须在适配器中使用 profileFilterList 并从此列表中返回计数只是尝试它会与您一起使用我想,但我尝试将我的适配器与我一起很好地用于过滤器 我看不懂你能编辑我的代码吗? 没有 searchview 这个适配器对我来说很好用以上是关于SearchView 在回收站视图中不起作用的主要内容,如果未能解决你的问题,请参考以下文章
DiffUtil 在嵌套的 recyclerview Kotlin 中不起作用
Constraintlayout Vertical Bias 在Android的两个视图中不起作用