单击 Recyclerview 中的项目后,OnItem 单击无法正常工作
Posted
技术标签:
【中文标题】单击 Recyclerview 中的项目后,OnItem 单击无法正常工作【英文标题】:OnItem click not working properly after clicking on the item in Recyclerview 【发布时间】:2019-12-06 12:31:21 【问题描述】:我尝试在回收站视图中实现搜索功能。为此,我在“Main.kt”类中编写了以下代码
搜索功能对我来说很好用,
问题是当我从列表中搜索项目并单击该项目时,我得到了错误的位置。
请帮我解决这个问题。
adapter = DynamicListAdapter(dynamicList)
dynamic_list_recyclerview.layoutManager = LinearLayoutManager(this, LinearLayout.VERTICAL,false) as RecyclerView.LayoutManager
dynamic_list_recyclerview.adapter = adapter
adapter!!.setRecyclerViewItemClickLister(this)
我已编辑文本并添加了 addTextChangedListener
edt_search_dynamic.addTextChangedListener(object : TextWatcher
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int)
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int)
override fun afterTextChanged(editable: Editable?)
filter(editable.toString())
)
fun filter(text : String)
var filteredList = mutableListOf<DynamicModel>()
for(list in dynamicList)
if(list.vehicleno.toLowerCase().contains(text.toLowerCase()))
filteredList.add(list)
adapter?.filterList(filteredList)
这是我的适配器类
class DynamicListAdapter (var dynamiclist : List<DynamicModel>) : RecyclerView.Adapter<DynamicListAdapter.DynamicViewHolder>()
var recyclerViewOnItemClickListener : RecyclerViewOnItemClickListener? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DynamicViewHolder
val inflatedView = LayoutInflater.from(parent.context)
.inflate(R.layout.singlerowdynamiclist,parent,false)
return DynamicViewHolder(inflatedView,dynamiclist)
override fun getItemCount(): Int
return dynamiclist.size
override fun onBindViewHolder(holder: DynamicViewHolder, position: Int)
holder.bindItem(dynamiclist[position])
inner class DynamicViewHolder(itemView : View, var dynamiclists : List<DynamicModel>) : RecyclerView.ViewHolder(itemView), View.OnClickListener
private var txtStatus : TextView? = null
init
txtStatus = itemView.findViewById(R.id.txtStatus)
itemView.setOnClickListener(this)
fun bindItem(dynamiclist : DynamicModel)
txtStatus?.text = dynamiclist.vehiclestatus
override fun onClick(view: View?)
when(view)
itemView -> if(recyclerViewOnItemClickListener!= null)
recyclerViewOnItemClickListener!!.onItemClick(adapterPosition,view)
// method of outer class
fun setRecyclerViewItemClickLister(onRecyclerviewItemClickListener : RecyclerViewOnItemClickListener)
this.recyclerViewOnItemClickListener = onRecyclerviewItemClickListener
// for filter the list
fun filterList(dymaniclist : List<DynamicModel>)
this.dynamiclist = dymaniclist
notifyDataSetChanged()
这是我在 Main.kt 类中实现的接口
interface RecyclerViewOnItemClickListener
fun onItemClick(position : Int, view: View)
【问题讨论】:
您的预期结果是什么?你想获得哪个职位?过滤前还是过滤后对象的位置? 我需要打开新的活动onItem click并发送点击位置的数据。 OnItem click 在没有应用过滤器时工作正常,但是当我在列表中搜索特定项目并单击该项目时,我没有从列表中获得所需的位置和相应的项目 您尝试从哪个列表中获取具有onItemClick
方法给出的位置的元素?来自未过滤的列表还是来自过滤的列表?
如果没有应用过滤器,那么我需要来自未过滤的过滤器,如果应用了过滤器,那么它应该来自过滤的过滤器。
这很奇怪。您的代码在我的机器上按预期工作。我想也许您是从过滤列表中获取位置,然后尝试在未过滤列表中使用它。您能否提供任何包含数据、过滤器文本、接收到的位置和项目以及所需位置的示例?
【参考方案1】:
应用过滤器后,您将无法获得所需的位置(未过滤列表中的位置),因为在创建新过滤列表并将其放入 DynamicListAdapter
时会丢失该信息。
假设在adapter
中有一个包含以下项目的列表:
val dynamicList = listOf(
"#0 A", // 0th position
"#1 B", // 1st position
"#2 AB" // 2nd position
)
现在让我们使用您的filter
方法:
filter("A")
最后将DynamicListAdapter
中的旧dynamicList
替换为全新的filteredList
,如下所示:
val filteredList = listOf(
"#0 A", // 0th position
"#2 AB", // 1st position
)
现在单击#2 AB
时,您将获得值1
(不需要2
)的位置,因为它是新filteredList
中的项目索引。
有多种方法可以实现你想要的,但如果你只想要来自被点击项目的数据,只需返回对象而不是它在项目点击上的位置:
interface RecyclerViewOnItemClickListener
fun onItemClick(dynamicModel: DynamicModel, view: View)
// inside DynamicListAdapter
inner class DynamicViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
fun bindItem(dynamiclist : DynamicModel)
with (itemView)
txtStatus.text = dynamiclist.vehiclestatus
setOnClickListener
recyclerViewOnItemClickListener?.onItemClick(dynamiclist, this)
但是,如果您需要返回位置并且以上不是一个选项,我建议将原始列表留在adapter
中并让它自己处理过滤,例如:
// _dynamicList is always the original list
class DynamicListAdapter (private val _dynamicList: List<DynamicModel>) : RecyclerView.Adapter<DynamicListAdapter.DynamicViewHolder>()
var recyclerViewOnItemClickListener : RecyclerViewOnItemClickListener? = null
var filterText: String = ""
set(value)
field = value
notifyDataSetChanged()
// return original list (_dynamicList) if no filter should be applied or return the filtered list based on the filterText
private val dynamicList: List<DynamicModel>
get() = if (filterText.isBlank()) _dynamicList
else _dynamicList.filter it.vehicleno.contains(filterText, ignoreCase = true)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DynamicViewHolder
val inflatedView = LayoutInflater.from(parent.context).inflate(R.layout.singlerowdynamiclist,parent,false)
return DynamicViewHolder(inflatedView)
override fun getItemCount(): Int
return dynamicList.size
override fun onBindViewHolder(holder: DynamicViewHolder, position: Int)
holder.bindItem(dynamicList[position])
inner class DynamicViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
fun bindItem(dynamicModel: DynamicModel)
with (itemView)
txtStatus.text = dynamicModel.vehiclestatus
// get the item's original position (before filtering)
val position = _dynamicList.indexOf(dynamicModel)
setOnClickListener
recyclerViewOnItemClickListener?.onItemClick(position, this)
// filter method
fun filter(text: String)
adapter?.filterText = text
【讨论】:
【参考方案2】:我提出了我的解决方案,它可能会对某人有所帮助。
鉴于:recyclerView 工作正常。
问题:在实现 searchview 后单击项目不起作用。
解决方案:在onQueryTextChange
中再次添加mAdapter.setOnItemClickListener
,如下所示:
@Override
public boolean onQueryTextChange(String newText)
mAdapter = new MyAdapter(getApplicationContext(), OtherInofYouWantToPass);
recyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(new MyAdapter.OnItemClickListener()
@Override
public void onItemClick(View view, MyObj obj, int position)
add your work here
);
return false;
【讨论】:
以上是关于单击 Recyclerview 中的项目后,OnItem 单击无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章
单击按钮后,Recyclerview适配器中的项目会跳转到右侧
如何通过单击 recyclerview 中的项目来打开新活动 [重复]
过滤 RecyclerView 项目并单击它后会给出错误的项目
在使用 FirebaseRecyclerPagingAdapter 时,第二次单击 RecyclerView 中的项目时,片段显示为空