RecycleView多Type布局的实现以及点击事件

RecycleView是开发中最常用的组件之一,因其优秀的回收机制而得到了广泛使用。最常用的效果就是用来实现复杂多布局列表。

所以当项目里需要实现如下布局时,我最先想到的便是使用Recycleview。

RecycleView多Type布局的实现以及点击事件_第1张图片

可以看到,整个Recycleview是方向垂直,而第一个itrm中有个水平滑动的recycleview。

而我们的demo实现的效果如图:

现在让我们开始实现这一步骤:

1.先编写三个不同类型的item

RecycleView多Type布局的实现以及点击事件_第2张图片

RecycleView多Type布局的实现以及点击事件_第3张图片

RecycleView多Type布局的实现以及点击事件_第4张图片

2.在Adapter中分别三种布局对应的ViewHolder

RecycleView多Type布局的实现以及点击事件_第5张图片3.在Adapter中分别写出三种布局的逻辑

3.1 即使有多种type,Adapter中的集合实体类也是使用的同一个,所以,我们要先写一个实体类

public class MultiBean {

    int type;
    String itemText;
//  横向的数据集合
    ArrayList arrayList;

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public String getItemText() {
        return itemText;
    }

    public void setItemText(String itemText) {
        this.itemText = itemText;
    }

    public ArrayList getArrayList() {
        return arrayList;
    }

    public void setArrayList(ArrayList arrayList) {
        this.arrayList = arrayList;
    }
}

3.2在Adapter中,为了区分三种布局,我们需要重写 getItemViewType(int position)方法,然后在onCreateViewHolder(@NonNull ViewGroup parent, int viewType)方法中加载不同的布局,返回对应的viewHolder

 @Override
    public int getItemViewType(int position) {

        MultiBean multiBean = multiBeans.get(position);

        ArrayList arrayList = multiBean.getArrayList();
        if (arrayList!=null&&arrayList.size()>0){
            return TYPE_HORIZONTAL;
        }else if (TextUtils.isEmpty(multiBean.getItemText())){
            return TYPE_TITLE;
        }else {
            return TYPE_VERYICAL;
        }
    }
 @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view;
        switch (viewType) {
            case TYPE_HORIZONTAL://水平布局是个单独的recycleview
                view = inflater.inflate(R.layout.item_recycle, parent, false);
                return new ViewHorizVH(view);

            case TYPE_TITLE:
                view = inflater.inflate(R.layout.item_title, parent, false);
                return new ViewTitleVH(view);

            case TYPE_VERYICAL:
                view = inflater.inflate(R.layout.item_vertival, parent, false);
                return new ViewVerticalVH(view);

        }

        return null;

    }

3.3 在onBindViewHolder 中,区别三种布局,并绑定数据。

 int type = multiBeans.get(position).getType();
        switch (type) {
            case TYPE_HORIZONTAL:
                ViewHorizVH horizVH = (ViewHorizVH) holder;
             
                break;
            case TYPE_TITLE:
                ViewTitleVH titleVH = (ViewTitleVH) holder;
               

                break;

            case TYPE_VERYICAL:
                ViewVerticalVH verticalVH = (ViewVerticalVH) holder;
                
                break;

            default:
                break;
        }

现在,我们的Adapter已经编写好了,在Activity中使用即可。

4.填充假数据


    private void initData() {
        beans = new ArrayList<>();
//      水平数据
        ArrayList strings = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            strings.add("横向Item" + i);
        }

        MultiBean multiBean;
        for (int i = 0; i < 50; i++) {
            multiBean = new MultiBean();

            int num = i % 10;

            switch (num) {
                case 0:
                    multiBean.setType(0);
                    multiBean.setArrayList(strings);
                    break;
                case 1:
                    multiBean.setType(1);
                    break;
                default:
                    multiBean.setType(2);
                    multiBean.setItemText("垂直Item:" + i);
                    break;
            }
            beans.add(multiBean);
        }
    }
 private void initView() {
        recycle_public = findViewById(R.id.recycle_public);
        adapter = new MultiAdapter(beans, this);
        recycle_public.setAdapter(adapter);
        RecyclerView.LayoutManager lm = new LinearLayoutManager(this);
        ((LinearLayoutManager) lm).setOrientation(RecyclerView.VERTICAL);
        recycle_public.setLayoutManager(lm);
//      设置间隔线
        recycle_public.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL));
    }

好了,到这一步为止,多布局的适配器以及数据已经填充好了,接下来我们需要给这个recycleview加上点击事件。

5.添加点击事件:

5.1定义接口:

public interface MultiClickListener {
    void onClick(View view,
                 int position1,
                 Object obj,
                 int type);
}

5.2 在适配器中使用:

 private MultiClickListener clickListener;

    public void setClickListener(MultiClickListener clickListener) {
        this.clickListener = clickListener;
    }

//              onBindViewHolder 中设置点击事件
                verticalVH.itemView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        if (clickListener != null) {
                            clickListener.onClick(view, position,multiBeans.get(position).getItemText(), TYPE_VERYICAL);
                        }
                    }
                });

然后再Activity设置点击监听:

 adapter.setClickListener(new MultiClickListener() {
            @Override
            public void onClick(View view, int position1, Object obj, int type) {
                LogUtils.i(obj.toString());
            }
        });

现在我们在控制台查看一下输出:

RecycleView多Type布局的实现以及点击事件_第6张图片

OK,已经大功告成了。

因横向滑动的item只是一个recycleview,需要在onBindViewHolder中初始化,设置数据,并添加点击事件,其代码与逻辑跟上述类似,就不在这里展开了,需要的同学可以在github上查看项目。

注意:区分item的布局方式其实是有两种,一种是通过Adapter的方法getItemViewType来实现,这种方式在开发中用的比较多。

但是还有一种,是在实体类中设置单独的字段type来区别,这一种的局限性就在于,实际接口中使用的数据几乎不会有这个字段,需要经过二次加工。

个人建议使用第一种方式来区分。

附上github地址:https://github.com/zhang-yanpeng/RiverPlayer

你可能感兴趣的:(Android开发技巧)