当前位置: 首页 > news >正文

实现淘宝购物车RecyclerView或LIstView的嵌套选择的逻辑

使用了RecyclerView嵌套RecyclerView的方案。

购物车的第一个界面为RecyclerView,每个Item里面包含一个店铺。在Item中使用RecyclerView包含店铺和店铺的多个商品。

实现思路:

使用接口回调将第二个adapter的商品选择的监听事件回调给第一个adapter后再在第一个adapter中回调给MainActivity。

使用接口回调将第一个adapter的商品选择的监听事件回调给MainActivity。

在MainActivity中处理第一个adapter和第二个adapter的事件监听。

MainActivity:

public class MainActivity extends AppCompatActivity {
    private RecyclerView recyclerView;
    private CheckBox checkBox;
    private recyclerAdapter adapter;
    private RecyclerView.LayoutManager manager;
    private List<bean> list;
    private List<cbean> cbeanList,cbeanListcp;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
        checkBox = (CheckBox) findViewById(R.id.shop_checkbox);

        list = new ArrayList<>();
        //第一个店铺的数据
        cbeanList = new ArrayList<>();
        cbean c = new cbean();
        c.setText("商品");
        c.setIscheck(false);
        cbean c1 = new cbean();
        c1.setText("商品1");
        c1.setIscheck(false);
        cbeanList.add(c);
        cbeanList.add(c1);
        bean b = new bean();
        b.setIscheck(false);
        b.setText("店名");
        b.setList(cbeanList);

        //第二个店铺的数据
        cbeanListcp = new ArrayList<>();
        cbean c2 = new cbean();
        c2.setText("商品2");
        c2.setIscheck(false);
        cbean c3 = new cbean();
        c3.setText("商品3");
        c3.setIscheck(false);
        cbeanListcp.add(c2);
        cbeanListcp.add(c3);
        bean b1 = new bean();
        b1.setIscheck(false);
        b1.setText("店名1");
        b1.setList(cbeanListcp);

        //不能添加有重复变量的数据
        list.add(b);
        list.add(b1);

        manager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(manager);
        //优化性能
        recyclerView.setHasFixedSize(true);
        adapter = new recyclerAdapter(list);
        recyclerView.setAdapter(adapter);
        //全选CheckBox监听
        checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked){
                     for (int i = 0;i < list.size();i++){
                         //选择店铺
                         if (!list.get(i).ischeck()){
                             list.get(i).setIscheck(true);
                         }
                         for (int j = 0;j <  list.get(i).getList().size();j++){
                             //选择店铺的商品
                             if (!list.get(i).getList().get(j).ischeck()){
                                 list.get(i).getList().get(j).setIscheck(true);
                             }
                         }
                     }
                }else {
                    //只有当点击全不选时才执行
                    // 解决点击取消选择店铺或商品时,
                    // 全选按钮取消选择状态,不会不变成全不选
                    if (allSelect() == list.size()){
                        for (int i = 0;i < list.size();i++){
                            if (list.get(i).ischeck()){
                                list.get(i).setIscheck(false);
                            }
                            for (int j = 0;j <  list.get(i).getList().size();j++){
                                if (list.get(i).getList().get(j).ischeck()){
                                    list.get(i).getList().get(j).setIscheck(false);
                                }
                            }
                        }
                    }
                }
                //更新
                UpdateRecyclerView();
            }
        });
     adapter.setCallBack(new recyclerAdapter.allCheck() {
         @Override
         public void OnCheckListener(boolean isSelected, int position) {
             //保存店铺点击状态
             list.get(position).setIscheck(isSelected);
             //通知全选CheckBox的选择状态
             if (allSelect() == list.size()){
                 checkBox.setChecked(true);
             }else {
                 checkBox.setChecked(false);
             }
             if (isSelected){
                 for (int i = 0;i <  list.get(position).getList().size();i++){
                     if (!list.get(position).getList().get(i).ischeck()){
                         list.get(position).getList().get(i).setIscheck(true);
                     }
                 }
             }else {
                 // 解决点击取消选择商品时,
                 // 店铺全选按钮取消选择状态,不会不变成全不选
                 if (allChildSelect(position) == list.get(position).getList().size()){
                     for (int i = 0;i <  list.get(position).getList().size();i++){
                         if (list.get(position).getList().get(i).ischeck()){
                             list.get(position).getList().get(i).setIscheck(false);
                         }
                     }
                 }
             }
             //更新
             UpdateRecyclerView();
         }

         @Override
         public void OnItemCheckListener(boolean isSelected, int parentposition, int chaildposition) {
             //保存商品点击状态
             list.get(parentposition).getList().get(chaildposition).setIscheck(isSelected);
             //通知店铺选择的状态
             if (allChildSelect(parentposition) == list.get(parentposition).getList().size()){
                 list.get(parentposition).setIscheck(true);
             }else {
                 list.get(parentposition).setIscheck(false);
             }
             UpdateRecyclerView();
         }
     });

    }
   /*
     *解决Recycleyview刷新报错问题
    */
    private void UpdateRecyclerView() {
        Handler handler = new Handler();
        final Runnable r = new Runnable() {
            public void run() {
                adapter.notifyDataSetChanged();
            }
        };
        handler.post(r);
    }
    //计算店铺的选择数量
    private int allSelect(){
        int sum = 0;
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).ischeck()){
                sum++;
            }
        }
        System.out.println(sum);
        return sum;
    }
    //计算每个店铺商品的选择数量
    private int allChildSelect(int position){
        int sum = 0;
        for (int i = 0; i < list.get(position).getList().size(); i++) {
            if (list.get(position).getList().get(i).ischeck()){
                sum++;
                System.out.println(position+":"+i+":"+list.get(position).getList().get(i).ischeck());
            }
        }
        return sum;
    }
}


第一个Adapter:

public class recyclerAdapter extends RecyclerView.Adapter<recyclerAdapter.MyHolder> {
    private List<bean> list;

    public recyclerAdapter(List<bean> list){
        this.list = list;
    }


    public static class MyHolder extends RecyclerView.ViewHolder{
        private RecyclerView recyclerView;
        private TextView textView;
        private CheckBox checkBox;
        private recyclerAdapter1 adapter;
        private RecyclerView.LayoutManager manager;

        public CheckBox getCheckBox() {
            return checkBox;
        }

        public RecyclerView getRecyclerView() {
            return recyclerView;
        }

        public TextView getTextView() {
            return textView;
        }

        public MyHolder(View itemView) {
            super(itemView);
            recyclerView = (RecyclerView) itemView.findViewById(R.id.list_items);
            textView = (TextView) itemView.findViewById(R.id.tv_name);
            checkBox = (CheckBox) itemView.findViewById(R.id.checkbox0);
            manager = new LinearLayoutManager(itemView.getContext());
            recyclerView.setLayoutManager(manager);
        }
    }

    @Override
    public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.shop_item,null);//解决嵌套显示条目不全
        MyHolder holder = new MyHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(final MyHolder holder, final int position) {

        holder.adapter = new recyclerAdapter1(list.get(position).getList());
        holder.recyclerView.setAdapter(holder.adapter);
        holder.getTextView().setText(list.get(position).getText());
        holder.getCheckBox().setChecked(list.get(position).ischeck());
        holder.getCheckBox().setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                //将店铺的checkbox的点击变化事件进行回调
                if (mCallBack!=null){
                    mCallBack.OnCheckListener(isChecked,position);
                }
            }
        });

        //实现第二层RecyclerView的回调接口
        holder.adapter.setCallBack(new recyclerAdapter1.allCheck() {
            @Override
            public void OnCheckListener(boolean isChecked, int childpostion) {
                //将店铺商品的checkbox的点击变化事件进行回调
                if (mCallBack!=null){
                    mCallBack.OnItemCheckListener(isChecked,position,childpostion);
                }
            }

        });
        holder.itemView.setTag(list.get(position));

    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    private allCheck mCallBack;

    public void setCallBack(allCheck callBack) {
        mCallBack = callBack;
    }

    public interface allCheck{
        //回调函数 将店铺的checkbox的点击变化事件进行回调
        public void OnCheckListener(boolean isSelected,int position);
        //回调函数 将店铺商品的checkbox的点击变化事件进行回调
        public void OnItemCheckListener(boolean isSelected,int parentposition,int chaildposition);
    }
}


第二个Adapter:

public class recyclerAdapter1 extends RecyclerView.Adapter<recyclerAdapter1.MyHolder> {
    private List<cbean> cbeanList, cbeanList1;

    public recyclerAdapter1(List<cbean> cbeanList) {
        this.cbeanList = cbeanList;
        cbeanList1 = cbeanList;
    }

    public static class MyHolder extends RecyclerView.ViewHolder {

        private TextView textView;
        private CheckBox checkBox;


        public TextView getTextView() {
            return textView;
        }

        public CheckBox getCheckBox() {
            return checkBox;
        }

        public MyHolder(View itemView) {
            super(itemView);
            textView = (TextView) itemView.findViewById(R.id.checkbox_tv);
            checkBox = (CheckBox) itemView.findViewById(R.id.checkbox1);
        }
    }

    @Override
    public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.check_item, parent,false);//解决显示不全
        MyHolder holder = new MyHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(final MyHolder holder, final int position) {
        holder.getTextView().setText(cbeanList.get(position).getText());
        holder.getCheckBox().setChecked(cbeanList.get(position).ischeck());

        holder.getCheckBox().setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                //将商品的checkbox的点击变化事件进行回调给第一个Recyclerview
                if (mCallBack != null) {
                    mCallBack.OnCheckListener(isChecked, position);
                }
            }
        });
        holder.itemView.setId(position);
    }

    @Override
    public int getItemCount() {
        return cbeanList.size();
    }

    private allCheck mCallBack;

    public void setCallBack(allCheck callBack) {
        mCallBack = callBack;
    }

    public interface allCheck {
        //回调函数 将店铺商品的checkbox的点击变化事件进行回调
        public void OnCheckListener(boolean isChecked, int childpostion);
    }

}


实体类保存数据和选择状态:

public class bean {
    private boolean ischeck;
    private String text;
    private List<cbean> list;

    public boolean ischeck() {
        return ischeck;
    }

    public void setIscheck(boolean ischeck) {
        this.ischeck = ischeck;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public List<cbean> getList() {
        return list;
    }

    public void setList(List<cbean> list) {
        this.list = list;
    }
}

public class cbean {
    private boolean ischeck;
    private String text;

    public boolean ischeck() {
        return ischeck;
    }

    public void setIscheck(boolean ischeck) {
        this.ischeck = ischeck;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }
}


布局文件:activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.cuboo.myapplication.MainActivity">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1">
    </android.support.v7.widget.RecyclerView>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <CheckBox
            android:id="@+id/shop_checkbox"
            android:layout_marginLeft="12dp"
            android:layout_width="24dp"
            android:layout_height="24dp"
            android:layout_gravity="left|center"
            android:padding="12dp"
            android:gravity="center" />
    </LinearLayout>

</LinearLayout>


shop_item.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <CheckBox
            android:id="@+id/checkbox0"
            android:layout_width="24dp"
            android:layout_height="24dp" />
        <TextView
            android:id="@+id/tv_name"
            android:text="店名"
            android:gravity="center"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>
    <View
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:background="@color/colorAccent"/>
    <android.support.v7.widget.RecyclerView
        android:id="@+id/list_items"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </android.support.v7.widget.RecyclerView>
    <View
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:background="@color/colorAccent"/>
</LinearLayout>


check_item:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="60dp">
    <CheckBox
        android:layout_gravity="center"
        android:id="@+id/checkbox1"
        android:layout_width="24dp"
        android:layout_height="24dp" />
    <TextView
        android:id="@+id/checkbox_tv"
        android:text="222"
        android:layout_weight="1"
        android:layout_gravity="center"
        android:gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>


 

简单的效果图:

相关文章:

  • (pt可视化)利用torch的make_grid进行张量可视化
  • MQTT协议规范总结
  • SAP EWM-拣货队列操作演示实例
  • 公众号查题功能接口系统使用教程
  • MySql5.7主从同步配置(gtid模式)
  • Linux文件系统管理
  • Python 程序的输出 | 第十一套(异常处理)
  • 每日算法刷题Day11-最大公约数、数组去重
  • 网络安全CTF竞赛模式、题目类别、所用工具小结
  • 80,90,00,房子最终砸在买房哪一代人手中?
  • 微服务项目:尚融宝(59)(核心业务流程:提现和还款(2))
  • jetson nano补充:根目录/usr刷机扩容 瘦身
  • Java工程师面试题
  • 网课查题接口使用
  • 算法练习(堆/栈/队列)
  • @angular/forms 源码解析之双向绑定
  • 【css3】浏览器内核及其兼容性
  • GitUp, 你不可错过的秀外慧中的git工具
  • HashMap剖析之内部结构
  • Spring思维导图,让Spring不再难懂(mvc篇)
  • 前端之Sass/Scss实战笔记
  • 驱动程序原理
  • 在Mac OS X上安装 Ruby运行环境
  • 阿里云重庆大学大数据训练营落地分享
  • 大数据全解:定义、价值及挑战
  • ​力扣解法汇总1802. 有界数组中指定下标处的最大值
  • "无招胜有招"nbsp;史上最全的互…
  • ## 临床数据 两两比较 加显著性boxplot加显著性
  • ### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException
  • $Django python中使用redis, django中使用(封装了),redis开启事务(管道)
  • (1)Map集合 (2)异常机制 (3)File类 (4)I/O流
  • (HAL库版)freeRTOS移植STMF103
  • (分类)KNN算法- 参数调优
  • (附源码)python房屋租赁管理系统 毕业设计 745613
  • (算法)Game
  • (幽默漫画)有个程序员老公,是怎样的体验?
  • (转)德国人的记事本
  • (转)负载均衡,回话保持,cookie
  • (转载)虚函数剖析
  • *(长期更新)软考网络工程师学习笔记——Section 22 无线局域网
  • **Java有哪些悲观锁的实现_乐观锁、悲观锁、Redis分布式锁和Zookeeper分布式锁的实现以及流程原理...
  • .htaccess 强制https 单独排除某个目录
  • .NET3.5下用Lambda简化跨线程访问窗体控件,避免繁复的delegate,Invoke(转)
  • /3GB和/USERVA开关
  • /usr/local/nginx/logs/nginx.pid failed (2: No such file or directory)
  • @serverendpoint注解_SpringBoot 使用WebSocket打造在线聊天室(基于注解)
  • @transaction 提交事务_【读源码】剖析TCCTransaction事务提交实现细节
  • [2016.7.Test1] T1 三进制异或
  • [Angular] 笔记 7:模块
  • [APIO2012] 派遣 dispatching
  • [HCIE] IPSec-VPN (手工模式)
  • [IE技巧] IE8中HTTP连接数目的变化
  • [java/jdbc]插入数据时获取自增长主键的值
  • [jQuery]div滚动条回到最底部
  • [Lucas定理]【学习笔记】