Android 如何处理嵌套回收视图中的单击
有人能解释一下处理这件事的逻辑吗 我有一个片段,在一个WebSocket调用后,它膨胀了2个Recyclerviews 子Recyclerview嵌套到父Recyclerview,父适配器调用子适配器。 我想为click listener设置一个接口,该接口处理片段中子项的单击 我应该把接口放在哪里,哪个类应该实现它?1)您应该把接口放在子适配器中,然后在父适配器中实现它,然后传递另一个接口(长进程)Android 如何处理嵌套回收视图中的单击,android,android-fragments,android-recyclerview,interface,listener,Android,Android Fragments,Android Recyclerview,Interface,Listener,有人能解释一下处理这件事的逻辑吗 我有一个片段,在一个WebSocket调用后,它膨胀了2个Recyclerviews 子Recyclerview嵌套到父Recyclerview,父适配器调用子适配器。 我想为click listener设置一个接口,该接口处理片段中子项的单击 我应该把接口放在哪里,哪个类应该实现它?1)您应该把接口放在子适配器中,然后在父适配器中实现它,然后传递另一个接口(长进程) 2) 使用本地广播管理器您将在父适配器中添加ClickListener,并将其添加到适配器的构
2) 使用本地广播管理器您将在父适配器中添加ClickListener,并将其添加到适配器的构造函数中
public interface HandleClickListener
{
void onItemClicked(int position, SurveysListModel surveysListModel);
}
制作clicklistener的一个实例,然后在holderclick listner上从模型列表中获取项目的位置及其值
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handleClickListener.onItemClicked(position, yourModelList.get(position));
});
然后像这样开始你的活动,制作你的适配器实例
adapter = new InstrumentsSearchAdapter(yourModelsList, activity.this, new SearchAdapter.HandleClickListener() {
@Override
public void onItemClicked(int position, Model listModel) {
instumentChild = listModel.getInstrument_title();
Intent intent = new Intent(Activity.this, Listing.class);
intent.putExtra("selectedQuestions", listModel.getQuestions());
startActivityForResult(intent, 5);
}
});
如果您想转到父RecycleView类实现onActivityResutlt方法,并通过intent从子级获取数据,并在onActivityResutlt方法中获取该意图,那么您尝试执行的操作已经执行了多次 您可以尝试各种方法,但一般来说,责任是这样的:
override fun bind(thing: Thing) {
if (clickHandler != null) {
someViewYourViewHolderInflated.setOnClickListener(this) // this assumes your ViewHolder implements View.OnClickListener from the framework
}
}
YourContext
(片段/活动)
- 使用
为布局充气李>RecyclerView
- 实例化
YourAdapter
- 订阅、请求、等待您的数据,并将其传递到
YourAdapter
- 维护用于单击处理的界面,如:
- 可以是
,或者如果您愿意,您可以保留它的匿名/本地实例。我通常先做前者,然后在片段/活动中实现单击内容时的YourContext:YourThingClickHandler
,这取决于单击项目时需要做什么李>乐趣(…)
YourAdapter
- 需要一个
和一个事物列表
实例。因此,在您的片段/活动中,您将执行以下操作(伪代码):YourThingClickHandler
YourThingClickHandler
)不为空,则从适配器的数据源中获取该项,并将其传递
如何将此内部处理程序与每个视图持有者关联?
当您在创建ViewHolder时,onCreateViewHolder
,有一个可以。。。您猜到了,一个内部ClickDelegate
实例,然后
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val inflater = LayoutInflater.from(parent.context)
// decide which viewHolder you're inflating... and...
return YourViewHolder(whateverViewYouInflate, internalClickHandler)
现在,您的ViewHolder已引用此内部单击处理程序
因此,当您对BindViewHolder(…)执行操作时,您可能会调用您选择的常用ViewHolder方法,例如,如果您的ViewHolder可以是不同的类型,那么您可能会有一个抽象的ViewHolder,它带有一个有趣的绑定(thing:thing)
方法或每个具体的ViewHolder子类型都必须实现的类似方法。。。在那里,你会做这样的事情:
override fun bind(thing: Thing) {
if (clickHandler != null) {
someViewYourViewHolderInflated.setOnClickListener(this) // this assumes your ViewHolder implements View.OnClickListener from the framework
}
}
因为您的ViewHolder实现了View.OnClickListener
,所以必须在其中实现onClick方法:
override fun onClick(v: View?) {
clickHandler?.onItemTappedAt(adapterPosition)
}
这就是你的ViewHolder如何在onClick
方法中从Android接收点击/点击事件,如果你提供了一个点击处理程序(当你传递internalClickHandler时,你在adapter onCreateViewHolder中做了),它只会在点击时冒泡,传递位置adapterPosition
是Kotlin等价于在RecyclerView适配器中调用getAdapterPosition()
太长了,没看图表
- 片段:ExternalClickListener->将其实例传递给适配器
- 适配器:接收外部ClickListener,将内部ClickListener传递给每个视图持有者
- ViewHolder:接收内部单击侦听器,将自身设置为可单击(整个
或任何要使其可单击的小部件,如果希望整个单元格可单击,只需使用itemView
,它是ViewHolder的“整体”视图itemView
onClick
方法。在这里,由于您在viewHolder中,您可以执行getAdapterPosition()并将其传递给收到的内部
单击处理程序
然后,适配器可以将该位置转换回数据,并且因为您提供了一个外部的点击监听器,所以它可以将实际项目传递回外部点击监听器
等等,但是嵌套的RecyclerView怎么样。
这没什么特别的,您只需要提供相同的机制,并不断地传递信息。您要做什么或拥有多少接口,完全取决于您要实现什么;正如我在开始时所说的,每个解决方案都是不同的,在制作architectura时必须考虑其他因素我会做决定
一般来说,请记住这一点:关注点的分离:保持事情的小而中肯。例如:拥有这个双重界面似乎很疯狂,但每个界面的作用都很清楚。内部界面只关心“视图”中的“点击”,并在列表中提供所述点击发生的位置
这是适配器获取数据并对真正点击的项目进行知情猜测所需的“全部”
片段不知道(或不关心)关于“位置”的信息,这是适配器的实现细节;positions
存在的事实对片段来说是不存在的;但是片段很高兴,因为它在回调中接收到了东西,
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val inflater = LayoutInflater.from(parent.context)
// decide which viewHolder you're inflating... and...
return YourViewHolder(whateverViewYouInflate, internalClickHandler)
override fun bind(thing: Thing) {
if (clickHandler != null) {
someViewYourViewHolderInflated.setOnClickListener(this) // this assumes your ViewHolder implements View.OnClickListener from the framework
}
}
override fun onClick(v: View?) {
clickHandler?.onItemTappedAt(adapterPosition)
}