为什么过滤 属性 不适用于 android 中的搜索栏?
Why filtering property not work for search bar in android?
我有一个简单的 android 项目,在用户列表的片段中有一个回收器视图,我想为这些用户使用搜索栏,这就是我使用过滤来搜索用户的原因列表视图,一切正常,但当我搜索用户名时,没有任何变化,过滤 属性 对用户名不起作用。任何想法将不胜感激。
游戏适配器:
class GameAdapter(
private val userId: String,
var chatList: ArrayList<Game>
): RecyclerView.Adapter<GameAdapter.GamesHolder>(), Filterable {
private var clickListener: ClickListener? = null
var filteredUserDataList: MutableList<Game>
inner class GamesHolder(view: View) : RecyclerView.ViewHolder(view), View.OnClickListener, View.OnLongClickListener {
val textGameTitle: TextView = view.findViewById(R.id.textUsername)
}
override fun onBindViewHolder(holder: GamesHolder, position:
Int) {
val game = filteredUserDataList[position]
holder.textGameTitle.text =
game.getGameName(userId).toString()
}
override fun getItemCount(): Int {
return filteredUserDataList.size
}
override fun getFilter(): Filter {
return filter
}
private var filter = object : Filter() {
override fun performFiltering(keyword: CharSequence): FilterResults {
val filtereddata = java.util.ArrayList<Game>()
if (keyword.toString().isEmpty()) filtereddata.addAll(gameList) else {
for (obj in gameList) {
if (obj.getGameName(userId).toLowerCase()
.contains(keyword.toString().toLowerCase())
) filtereddata.add(obj)
}
}
val results = FilterResults()
results.values = filtereddata
return results
}
override fun publishResults(constraint: CharSequence, results: FilterResults) {
gameList.clear()
gameList.addAll((results.values as ArrayList<Game>))
notifyDataSetChanged()
}
init {
filteredUserDataList = gameList
}
}
fun getItem(index: Int): Game {
return filteredUserDataList[index]
}
游戏片段:
class GameFragment : Fragment() {
lateinit var recyclerViewGame: RecyclerView
var searchView: EditText? = null
var search: CharSequence = ""
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_games, container, false)
recyclerViewGame = view.findViewById(R.id.game_list)
configureRecycler(gameList)
return view
}
private fun configureRecycler(games: ArrayList<Game>) {
val userId = userPresenter.getGame().id
val gamesAdapter = context?.let {
GameAdapter(userId, it, games)
}
searchView = view?.findViewById(R.id.search_bar)
searchView?.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {
gamesAdapter.filter.filter(charSequence)
search = charSequence
}
override fun afterTextChanged(editable: Editable) {}
})
} }
我能看到这些东西
filteredUserDataList 应该用 gameList
初始化
改变
覆盖乐趣 getItemCount() = gameList.size
至
覆盖乐趣 getItemCount() = filteredUserDataList.size
并记住 filteredUserDataList 是主列表,实际
gameList只是为了在用户清除或更改搜索查询时保持原始数据
您检查的是 userName
而不是 userId
。这让我有点困惑,因为您在 predicate 中使用 userId
而 userId
在您的案例中是一个全局字段。我不明白这里userId
的作用。
无论如何,我正在根据我的理解在下面添加一个解决方案。试一试
override fun performFiltering(charSequence: CharSequence): FilterResults {
val searchTerm = charSequence.toString().lowercase(Locale.getDefault())
filteredUserDataList = if(searchTerm.isEmpty()){
gameList
}else{
val lstFiltered: ArrayList<Game> = ArrayList()
for (row in gameList) {
val user = row.participants.find {
it.username.lowercase(Locale.getDefault()).contains(searchTerm)
}
if (user!=null) {
lstFiltered.add(row)
}
}
lstFiltered
}
val filterResults = FilterResults()
filterResults.values = filteredUserDataList
return filterResults
}
override fun publishResults(charSequence: CharSequence, filterResults: FilterResults) {
filteredUserDataList = filterResults.values as ArrayList<Game>
notifyDataSetChanged()
}
如果您尝试按 username
和 userId
两个字段进行搜索,那么在应用过滤器时必须同时考虑这两个字段。
我有一个简单的 android 项目,在用户列表的片段中有一个回收器视图,我想为这些用户使用搜索栏,这就是我使用过滤来搜索用户的原因列表视图,一切正常,但当我搜索用户名时,没有任何变化,过滤 属性 对用户名不起作用。任何想法将不胜感激。
游戏适配器:
class GameAdapter(
private val userId: String,
var chatList: ArrayList<Game>
): RecyclerView.Adapter<GameAdapter.GamesHolder>(), Filterable {
private var clickListener: ClickListener? = null
var filteredUserDataList: MutableList<Game>
inner class GamesHolder(view: View) : RecyclerView.ViewHolder(view), View.OnClickListener, View.OnLongClickListener {
val textGameTitle: TextView = view.findViewById(R.id.textUsername)
}
override fun onBindViewHolder(holder: GamesHolder, position:
Int) {
val game = filteredUserDataList[position]
holder.textGameTitle.text =
game.getGameName(userId).toString()
}
override fun getItemCount(): Int {
return filteredUserDataList.size
}
override fun getFilter(): Filter {
return filter
}
private var filter = object : Filter() {
override fun performFiltering(keyword: CharSequence): FilterResults {
val filtereddata = java.util.ArrayList<Game>()
if (keyword.toString().isEmpty()) filtereddata.addAll(gameList) else {
for (obj in gameList) {
if (obj.getGameName(userId).toLowerCase()
.contains(keyword.toString().toLowerCase())
) filtereddata.add(obj)
}
}
val results = FilterResults()
results.values = filtereddata
return results
}
override fun publishResults(constraint: CharSequence, results: FilterResults) {
gameList.clear()
gameList.addAll((results.values as ArrayList<Game>))
notifyDataSetChanged()
}
init {
filteredUserDataList = gameList
}
}
fun getItem(index: Int): Game {
return filteredUserDataList[index]
}
游戏片段:
class GameFragment : Fragment() {
lateinit var recyclerViewGame: RecyclerView
var searchView: EditText? = null
var search: CharSequence = ""
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_games, container, false)
recyclerViewGame = view.findViewById(R.id.game_list)
configureRecycler(gameList)
return view
}
private fun configureRecycler(games: ArrayList<Game>) {
val userId = userPresenter.getGame().id
val gamesAdapter = context?.let {
GameAdapter(userId, it, games)
}
searchView = view?.findViewById(R.id.search_bar)
searchView?.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {
gamesAdapter.filter.filter(charSequence)
search = charSequence
}
override fun afterTextChanged(editable: Editable) {}
})
} }
我能看到这些东西
filteredUserDataList 应该用 gameList
初始化改变
覆盖乐趣 getItemCount() = gameList.size
至
覆盖乐趣 getItemCount() = filteredUserDataList.size
并记住 filteredUserDataList 是主列表,实际 gameList只是为了在用户清除或更改搜索查询时保持原始数据
您检查的是 userName
而不是 userId
。这让我有点困惑,因为您在 predicate 中使用 userId
而 userId
在您的案例中是一个全局字段。我不明白这里userId
的作用。
无论如何,我正在根据我的理解在下面添加一个解决方案。试一试
override fun performFiltering(charSequence: CharSequence): FilterResults {
val searchTerm = charSequence.toString().lowercase(Locale.getDefault())
filteredUserDataList = if(searchTerm.isEmpty()){
gameList
}else{
val lstFiltered: ArrayList<Game> = ArrayList()
for (row in gameList) {
val user = row.participants.find {
it.username.lowercase(Locale.getDefault()).contains(searchTerm)
}
if (user!=null) {
lstFiltered.add(row)
}
}
lstFiltered
}
val filterResults = FilterResults()
filterResults.values = filteredUserDataList
return filterResults
}
override fun publishResults(charSequence: CharSequence, filterResults: FilterResults) {
filteredUserDataList = filterResults.values as ArrayList<Game>
notifyDataSetChanged()
}
如果您尝试按 username
和 userId
两个字段进行搜索,那么在应用过滤器时必须同时考虑这两个字段。