Android 如何处理嵌套回收视图中的单击

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,并将其添加到适配器的构

有人能解释一下处理这件事的逻辑吗

我有一个片段,在一个WebSocket调用后,它膨胀了2个Recyclerviews

子Recyclerview嵌套到父Recyclerview,父适配器调用子适配器。 我想为click listener设置一个接口,该接口处理片段中子项的单击

我应该把接口放在哪里,哪个类应该实现它?

1)您应该把接口放在子适配器中,然后在父适配器中实现它,然后传递另一个接口(长进程)


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
    实例。因此,在您的片段/活动中,您将执行以下操作(伪代码):
此内部处理程序将用于从viewHolder返回到适配器的对话,以及将点击气泡上升到外部单击处理程序

现在,您可以有一个这样定义的适配器类的实例(请记住这是伪代码):

因此,如果外部单击处理程序(您提供的
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
    或任何要使其可单击的小部件,如果希望整个单元格可单击,只需使用
    itemView
    ,它是ViewHolder的“整体”视图
点击viewHolder的视图时,android会调用click listener的
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)
    }