RecyclerView嵌套R(shí)ecyclerView的子控件點(diǎn)擊事件獲取

最近寫的一個(gè)商城APP,布局比較復(fù)雜,其中有需要使用到Recyclerview嵌套R(shí)ecyclerView的地方。 另外,本例子使用的Adapter框架為BaseQuickAdapter 。如果有使用到其他的Adapter框架需要自己適當(dāng)修改。
BaseQuickAdapter 框架 Github地址:https://github.com/CymChad/BaseRecyclerViewAdapterHelper

TIM圖片20190929150843.png

紅色部分是一個(gè)Recyclerview 藍(lán)色部分又是一個(gè)RecyclerView。Adapter加載的數(shù)據(jù)格式應(yīng)該是List<data>,其中data又是一個(gè)List。當(dāng)用戶點(diǎn)擊內(nèi)層recyclerview時(shí)需要獲取第一層的List的Position又要獲取第二層的List的Positon。為了實(shí)現(xiàn)該效果,我們有兩個(gè)方法,先介紹第一種方法:

在外層RecyclerView的Adapter中添加接口,供Activity或Fragment使用:


 public class FirstAdapter extends BaseQuickAdapter<MyFirstList,BaseViewHolder> {

  private OnChildClickListener onItemClickListener;

  public FirstAdapter (int layoutResId,@Nullable List data) {

  super(layoutResId, data);

  }

    @Override
   protected void convert(BaseViewHolder helper, MyFirstList item) {
      if (item.getSecondlist().size()!=0){
        SecondAdapter secondadapter =new SecondAdapter (R.layout.item_second,item.getSecondlist());    //加載內(nèi)層RecyclerView的布局與數(shù)據(jù)
        secondadapter.setLayoutManager(new GridLayoutManager(mContext,3));
        secondadapter.setAdapter(secondadapter );
        secondadapter.addOnItemTouchListener(new com.chad.library.adapter.base.listener.OnItemClickListener() { //OnItemClickListener為BaseRecyclerView的子控件監(jiān)聽方法
        @Override
        public void onSimpleItemClick(BaseQuickAdapter adapter, View view,int position) {
                  onItemClickListener.success(position);
              }
        });
      }
    }

    public void setOnChildPositionListener(OnChildClickListener onItemClickListener){
        this.onItemClickListener = onItemClickListener;
    }

    public interface OnChildClickListener{
    //成功的方法傳 int 的索引
    void success(int index);
    }
}

在Activity或Fragment中填充外層RecyclerView數(shù)據(jù):

 RecyclerView firstview= (RecyclerView) findViewById(R.id.recyclerview);
 FirstAdapter firsrtAdapter= new FirstAdapter (R.layout.item_first,MyFirstList);
 firstview.setLayoutManager(new LinearLayoutManager(mContext));
 firstview.setAdapter(classificationListTwoAdapter);
 firstview.addOnItemTouchListener(new OnItemClickListener() {
     @Override
     public void onSimpleItemClick(BaseQuickAdapter adapter, View view, int position) {
          firsrtAdapter.setOnChildPositionListener(new ClassificationListTwoAdapter.OnChildClickListener() {
          @Override
          public void success(int index) {
              MyFirstList.get(position).getSecondlist().get(index)   //獲取內(nèi)層RecyclerView數(shù)據(jù)
           }
        });
   }
 });

然后介紹第二種方法,該方法主要是根據(jù)控件嵌套控件的點(diǎn)擊事件觸發(fā)邏輯去實(shí)現(xiàn)獲取內(nèi)層數(shù)據(jù)的效果,但是也需要在外層Recyclerview的Adapter中添加接口供Activity使用:

public class FirstAdpter extends BaseQuickAdapter<MyFirstList , BaseViewHolder> {

    int position ;
    private OnChildClickListener onItemClickListener;



    public int getPosition() {
        return position;
    }

    public void setPosition(int position) {
        this.position = position;
    }

    public FirstAdpter (int layoutResId, @Nullable List<MyFirstList > data) {
        super(layoutResId, data);
    }


    @Override
    protected void convert(BaseViewHolder helper, MyFirstList  item) {
        RecyclerView recyclerView = helper.itemView.findViewById(R.id.rv_item_recommend);
        helper.addOnClickListener(R.id.rv_item_recommend);       //給內(nèi)層RecyclerView增加點(diǎn)擊事件
        SecondAdapter secondadpter= new SecondAdapter (R.layout.item_item_recommend,item.getList());
        recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
        secondadpter.setOnItemClickListener((adapter, view1, position1) -> {
            onItemClickListener.success(position1,position);
        });
        recyclerView.setAdapter(secondadpter);
    }

    public void setOnChildPositionListener(OnChildClickListener onItemClickListener){
        this.onItemClickListener = onItemClickListener;
    }

    public interface OnChildClickListener{
        //成功的方法傳 int 的索引
        void success(int index,int position);
    }

}

在Activity或Fragment中填充外層RecyclerView數(shù)據(jù):

                //MyData為最外層的List數(shù)據(jù)
                RecyclerView firstview= (RecyclerView) findViewById(R.id.recyclerview)
                FirstAdapter firstadapter= new FirstAdapter (R.layout.item_first, MyData);
                firstview.addOnItemTouchListener(new OnItemChildClickListener() {
                    @Override
                    public void onSimpleItemChildClick(BaseQuickAdapter adapter, View view, int position) {
                        firstadapter.setPosition(position);
                    }
                });
                firstadapter.setOnChildPositionListener(new FirstAdapter.OnChildClickListener() {
                    @Override
                    public void success(int index,int positon) {
                          MyData.get(positon).getSecondlist().get(index); //獲取內(nèi)層 Recyclerview數(shù)據(jù)
                    }
                });
                firstview.setLayoutManager(new LinearLayoutManager(mContext));
                firstview.setAdapter(firstadapter);

PS:
Recyclerview嵌套R(shí)ecyclerview中,若在首個(gè)recyclerview中的onBindViewHolder方法里(若使用了BRAH,則是在convert()方法中),通過addOnItemTouchListener設(shè)置了第二個(gè)recyclerview的點(diǎn)擊事件,則需要在onBindViewHolder()添加判斷條件,防止外層Activity或Fragment中,調(diào)用第一個(gè)Recyclerview的notifyDataSetChanged()方法后,重復(fù)設(shè)置點(diǎn)擊事件導(dǎo)致子Recyclerview的點(diǎn)擊事件被重復(fù)觸發(fā)。

public class FirsrAdapter extends BaseQuickAdapter<xxx, BaseViewHolder> {
    private boolean setclick = false;
    ......
    @Override
    protected void convert(BaseViewHolder helper, xxx) {
      SecondAdapter secondadapter = new SecondAdapter(xxx,xxx);
      if (!setclick) {
          setclick = true;
          secondadapter.addOnItemTouchListener(...)
       }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容