简单实现电商购物车的一些逻辑

图片与代码不符大笑

购物车,无非就是对复选框的全选、反选、数量增减,计算价格的一些逻辑

在这里,视图代码就不上了,主要上Adapter适配器的逻辑

在这里,本人使用的是ExpandableListView二级列表展示的,相对来说,逻辑比较清晰一点

下面是适配器里面的主要逻辑代码

 
 
 
 
    //父条目视图View
    @Override
    public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        //使用ViewHolder进行条目优化
        MyGroupViewHolder myGroupViewHolder = null;
        //convertView条目复用
        if (convertView == null) {
            //获取父视图
            convertView = LayoutInflater.from(context).inflate(R.layout.group_item, parent, false);
            CheckBox cb = convertView.findViewById(R.id.group_cb);
            TextView name = convertView.findViewById(R.id.group_name);
            myGroupViewHolder = new MyGroupViewHolder(cb, name);
            convertView.setTag(myGroupViewHolder);
        } else {
            myGroupViewHolder = (MyGroupViewHolder) convertView.getTag();
        }
        //初始化父条目数据
        myGroupViewHolder.getGroup_cb().setChecked(list.get(groupPosition).isGroupFlag());
        myGroupViewHolder.getGroup_name().setText(list.get(groupPosition).getSellerName());
        //父条目复选框点击事件
        myGroupViewHolder.getGroup_cb().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //把v强转成CheckBox并获取它的选中状态
                CheckBox box = (CheckBox) v;
                boolean boxChecked = box.isChecked();
                //给父条目数据Bean赋值
                list.get(groupPosition).setGroupFlag(boxChecked);
                //判断当复选框选中的时候,记录选中一个
                if (boxChecked) {
                    count++;
                } else {
                    //当它未选中的时候,记录原来选中数如果大于0时的减一
                    if (count > 0) {
                        count--;
                    }
                }
                //获取到子条目数据集合
                List<CartBean.ChildBean> childList = MyAdapter.this.list.get(groupPosition).getList();
                for (int i = 0; i < childList.size(); i++) {
                    //遍历集合给子条目的复选框选中状态设为父条目复选框的选中状态,父条目及其子条目的全选和反选,
                    childList.get(i).setChildFlag(boxChecked);
                }
                //使用自定义接口把获取到的条目选中数量传出去
                onGetCount.getCount(count);
                //调用刷新适配器的方法
                setNotifyDataSetChanged();
            }
        });
        return convertView;
    }

    //子条目视图,优化方式同上,就不一一讲解了
    @Override
    public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        MyChildViewHolder myChildViewHolder = null;
        if (convertView == null) {
            convertView = LayoutInflater.from(context).inflate(R.layout.child_item, parent, false);
            CheckBox child_cb = convertView.findViewById(R.id.child_cb);
            SimpleDraweeView child_simple = convertView.findViewById(R.id.child_simple);
            TextView child_title = convertView.findViewById(R.id.child_title);
            TextView child_scount = convertView.findViewById(R.id.child_scount);
            TextView child_delete = convertView.findViewById(R.id.child_delete);
            SumLayout sumLayout = convertView.findViewById(R.id.sumlayout);
            myChildViewHolder = new MyChildViewHolder(child_cb, child_simple, child_title, child_scount, child_delete,sumLayout);
            convertView.setTag(myChildViewHolder);
        } else {
            myChildViewHolder = (MyChildViewHolder) convertView.getTag();
        }
        //初始化子条目数据
        final List<CartBean.ChildBean> childList = this.list.get(groupPosition).getList();
        myChildViewHolder.getChild_cb().setChecked(childList.get(childPosition).isChildFlag());
        String images = childList.get(childPosition).getImages().split("\\|")[0];
        myChildViewHolder.getChild_simple().setImageURI(images);
        myChildViewHolder.getChild_title().setText(childList.get(childPosition).getTitle());
        myChildViewHolder.getChild_scount().setText(childList.get(childPosition).getSubhead());
        //得到数据里面的购买数量
        num = list.get(groupPosition).getList().get(childPosition).getNum();
        //给视图赋值
        myChildViewHolder.getSumLayout().setCount(num+"");
        //自定义加减框点击事件
        final MyChildViewHolder finalMyChildViewHolder1 = myChildViewHolder;
        myChildViewHolder.getSumLayout().setOnDownSumLayoutListener(new SumLayout.OnDownSumLayouListener() {
            @Override
            public void onDownSumLayout() {
                //得到改变后的购买数量
                String count = finalMyChildViewHolder1.getSumLayout().getCount();
                //转为int型
                int i = Integer.parseInt(count);
                //并重新给子条目数据的购买数量赋值
                list.get(groupPosition).getList().get(childPosition).setNum(i);
                //调用刷新适配器的方法
                setNotifyDataSetChanged();
            }
        });

        //删除购物车数据  目前仅仅是删除listview视图 没有删除数据
        myChildViewHolder.getChild_delete().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                List<CartBean.ChildBean> childList = MyAdapter.this.list.get(groupPosition).getList();
                childList.remove(childPosition);
                setNotifyDataSetChanged();
            }
        });
        final MyChildViewHolder finalMyChildViewHolder = myChildViewHolder;
        //子条目复选框点击事件
        myChildViewHolder.getChild_cb().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //得到子条目复选框的选中状态
                boolean checked = finalMyChildViewHolder.getChild_cb().isChecked();
                //得到子条目数据集合
                List<CartBean.ChildBean> childList = MyAdapter.this.list.get(groupPosition).getList();
//                把选中状态赋值给数据集合
                childList.get(childPosition).setChildFlag(checked);
                //判断当为选中状态时选中数量加一
                if (checked) {
                    count++;
                } else {//否则减一
                    if (count > 0) {
                        count--;
                    }
                }
                //设置标记flag 默认为true
                boolean flag = true;
                //遍历子条目数据里面的复选框状态,有一个为false,那么父条目数据复选框状态就为false
                for (int i = 0; i < childList.size(); i++) {
                    boolean childFlag = childList.get(i).isChildFlag();
                    if (childFlag == false) {
                        flag = false;
                    }
                }
                //当子条目复选框全部选中时,父条目复选框,也选中
                list.get(groupPosition).setGroupFlag(flag);
                //使用自定义接口把获取到的条目选中数量传出去
                onGetCount.getCount(count);
                //调用刷新适配器的方法
                setNotifyDataSetChanged();
            }
        });
        return convertView;
    }

    /**
     * 刷新适配器的方法
     */
    public void setNotifyDataSetChanged() {
        //刷洗适配器
        notifyDataSetChanged();
        //重新请求网络数据
        CartPresenterImpl cartPresenter = new CartPresenterImpl();
        //请求计算接口
        cartPresenter.formJisuan(new CartModelImpl(cartPresenter), iCartView);
    }
    //复选框选中个数的内部接口
    public interface OnGetCount {
        void getCount(int count);
    }
    //访问接口的放发
    public void setOnGetCount(OnGetCount onGetCount) {
        this.onGetCount = onGetCount;
    }

我这里使用的是Retrofit+RxJava+MVP进行请求网络数据比较繁琐

Model层接口

public interface ICartModel {
    //获取购物车数据方法
    void formCartDatas(Map<String,String> params);
    //获取购物车计算价格数据方法
    void formCartJisuan(List<CartBean.DataBean> data,ICartPresenter iCartPresenter);
}

Model层接口实现类

public class CartModelImpl implements ICartModel {
    private static final String TAG = "CartModelImpl";
    private final ICartPresenter iCartPresenter;
    //构造方法得到P层的实例
    public CartModelImpl(ICartPresenter iCartPresenter) {
        this.iCartPresenter = iCartPresenter;
    }
    //获取购物车数据方法
    @Override
    public void formCartDatas(Map<String, String> params) {
        //得到网络请求工具类Retrofit+RxJava
        NetWorkUtils netWorkUtils = NetWorkUtils.getNetWorkUtils();
        RtrofitService rtrofitService = netWorkUtils.creatRequest(RtrofitService.class);
        Observable<CartBean> cartBean = rtrofitService.getCartBean(params);
        cartBean.subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<CartBean>() {
                    //请求完成
                    @Override
                    public void onCompleted() {
                        Log.d(TAG, "onCompleted: 完成");
                    }
                    //请求失败
                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "onError: " + e.getMessage());
                        iCartPresenter.formDataError(e.getMessage());
                    }
                    //请求中
                    @Override
                    public void onNext(CartBean cartBean) {
                        Log.d(TAG, "onNext: " + cartBean);
                        String code = cartBean.getCode();
                        //根据code进行判断 如果code等于0为请求成功 否则请求失败
                        if (code.equals("0")) {
                            iCartPresenter.formDataSuccess(cartBean.getData());
                        } else {
                            iCartPresenter.formDataError(cartBean.getMsg());
                        }
                    }
                });
    }
    //获取购物车计算价格数据方法  一定是View层返回的集合
    @Override
    public void formCartJisuan(List<CartBean.DataBean> data,ICartPresenter iCartPresenter) {
        //初始值为0  记录总价
        double sum = 0;
        //遍历父条目数据集合
        for (int i = 0; i < data.size(); i++) {
            //得到子条目数据集合
            List<CartBean.ChildBean> childList = data.get(i).getList();
            //遍历子条目数据集合
            for (int j = 0; j < childList.size(); j++) {
                //如果,子条目复选框为选中状态时,则累加总价
                if (childList.get(j).isChildFlag()){
                    //得到总价sum  总价=数量*单价
                    sum+=childList.get(j).getNum()*childList.get(j).getPrice();
                }
            }
        }
        Log.d(TAG, "formCartJisuan: "+sum);
        //把得到的总价传到Presenter层
        iCartPresenter.getPrice(sum);
    }

Presenter层接口

public interface ICartPresenter {
    //获取Model层和View层方法 和构造方法效果一样
    void formDataModelView(ICartModel iCartModel, ICartView iCartView);
    //获取数据成功方法
    void formDataSuccess(List<CartBean.DataBean> data);
    //获取数据失败方法
    void formDataError(String error);
    //获取计算总价方法
    void formJisuan(ICartModel iCartModel,ICartView iCartView);
    //的到总价方法
    void getPrice(double price);
}

Presenter层接口实现类

扫描二维码关注公众号,回复: 1370365 查看本文章
public class CartPresenterImpl implements ICartPresenter {
    private static final String TAG = "CartPresenterImpl";
    private ICartView iCartView;
    //获取Model层和View层方法 和构造方法效果一样
    @Override
    public void formDataModelView(ICartModel iCartModel, ICartView iCartView) {
        //得到View层实例
        this.iCartView = iCartView;
        Map<String,String> params = new HashMap<>();
        params.put("uid",iCartView.getUid());
        //调用Model层获取购物车数据方法
        iCartModel.formCartDatas(params);
    }
    //获取数据成功方法
    @Override
    public void formDataSuccess(List<CartBean.DataBean> data) {
        Log.d(TAG, "formDataSuccess: "+data);
        //调用view层获取数据成功的方法
        iCartView.formCartViewSuccess(data);
    }
    //获取数据失败方法
    @Override
    public void formDataError(String error) {
        Log.d(TAG, "formDataError: "+error);
        //调用view层获取数据失败的方法
        iCartView.formCaRTViewError(error);
    }
    //获取计算总价方法
    @Override
    public void formJisuan(ICartModel iCartModel, ICartView iCartView) {
        this.iCartView = iCartView;
        //调用Model层计算总价的方法
        iCartModel.formCartJisuan(iCartView.getList(),this);
    }
    //得到总价方法
    @Override
    public void getPrice(double price) {
        Log.d(TAG, "getPrice: "+price);
        //把获取到的总价传递给View
        iCartView.getSum(price);
    }
}

View层接口

public interface ICartView {
    //获取数据成功方法
    void formCartViewSuccess(List<CartBean.DataBean> data);
    //获取数据失败方法
    void formCaRTViewError(String error);
    //返回UID方法
    String getUid();
    //获取总价方法
    void getSum(double price);
    //放回购物车数据方法
    List<CartBean.DataBean> getList();
}

MainActivity类View层实现类

public class MainActivity extends AppCompatActivity implements ICartView {
    private static final String TAG = "MainActivity";
    @BindView(R.id.main_back)
    TextView mainBack;
    @BindView(R.id.expandable)
    ExpandableListView expandable;
    @BindView(R.id.main_checkAll)
    CheckBox mainCheckAll;
    @BindView(R.id.main_sum)
    TextView mainSum;
    @BindView(R.id.main_pay)
    TextView mainPay;
    private List<CartBean.DataBean> list;
    private MyAdapter myAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //使用ButterKnife
        ButterKnife.bind(this);
        //初始化视图/数据
        initViews();

    }
    private void initViews() {
        //请求网络
        CartPresenterImpl cartPresenter = new CartPresenterImpl();
        cartPresenter.formDataModelView(new CartModelImpl(cartPresenter), MainActivity.this);
    }
    @OnClick({R.id.main_back, R.id.main_checkAll, R.id.main_pay})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.main_back:
                Toast.makeText(this, "我点击了返回", Toast.LENGTH_SHORT).show();
                break;
            case R.id.main_checkAll://全选复选框点击事件
                //得到全选框的选中状态
                boolean checked = mainCheckAll.isChecked();
                for (int i = 0; i < list.size(); i++) {
                    //遍历购物车数据得到子条目数据集合 把父条目复选框设为全选框状态
                    list.get(i).setGroupFlag(checked);
                    List<CartBean.ChildBean> childList = this.list.get(i).getList();
                    for (int j = 0; j < childList.size(); j++) {
                        //把子条目复选框设全选框状态
                        childList.get(j).setChildFlag(checked);
                    }
                }
                //刷洗适配器
                myAdapter.notifyDataSetChanged();
                //重新计算总价
                CartPresenterImpl cartPresenter = new CartPresenterImpl();
                //刷新总价
                cartPresenter.formJisuan(new CartModelImpl(cartPresenter),this);
                break;
            case R.id.main_pay:
                break;
        }
    }
//    获取购物车数据成功方法
    @Override
    public void formCartViewSuccess(List<CartBean.DataBean> data) {
        //把购物车数据提升作用域
        this.list = data;
        Log.d(TAG, "formCartViewSuccess: " + data);
        //实例化Adapter
        myAdapter = new MyAdapter(this, data, this);
        //ExpandableListView设置适配器
        expandable.setAdapter(myAdapter);
        //调用adapter的复选框选中个数的内部接口
        myAdapter.setOnGetCount(new MyAdapter.OnGetCount() {
            @Override
            public void getCount(int count) {
                Log.d(TAG, "getCount: " + count);
                //给TextView赋值
                mainPay.setText("去支付(" + count + ")");
            }
        });
        //展开子条目
        int count = expandable.getCount();
        for (int i = 0; i < count; i++) {
            expandable.expandGroup(i);
        }
    }
    //获取购物车数据失败方法
    @Override
    public void formCaRTViewError(String error) {
        Log.d(TAG, "formCaRTViewError: " + error);
    }
    //返回Uid方法
    @Override
    public String getUid() {
        return 71 + "";
    }
    //获取总价方法
    @Override
    public void getSum(double price) {
        Log.d(TAG, "getSum: " + price);
        mainSum.setText("合计:¥" + price);
    }
    //返回购物车数据方法
    @Override
    public List<CartBean.DataBean> getList() {
        return list;
    }
}

当然,还要有自定义加减框了 SumLayout

public class SumLayout extends LinearLayout implements View.OnClickListener {

    private TextView sub;
    private TextView count;
    private TextView add;
    private OnDownSumLayouListener onDownSumLayoutListener;
    //自定义View的构造方法
    public SumLayout(Context context) {
        this(context, null);
    }
    
    public SumLayout(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SumLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //加载视图
        View view = View.inflate(context, R.layout.sumlayout, this);
        //获取控件
        sub = view.findViewById(R.id.sub);
        count = view.findViewById(R.id.count);
        add = view.findViewById(R.id.add);
        //注册点击事件
        sub.setOnClickListener(this);
        add.setOnClickListener(this);
    }
    //点击事件
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.sub://数量减减
                //得到数量
                String ss = count.getText().toString();
                //转为int型
                int i = Integer.parseInt(ss);
                //减减
                i--;
                //判断当i大于等于0时给TextView赋值
                if (i >= 0) {
                    setCount(i + "");
                    //调用自定义接口点击事件
                    onDownSumLayoutListener.onDownSumLayout();
                }
                break;
            case R.id.add://数量加加
                //获取数量
                String s = count.getText().toString();
                //转为int型
                int i1 = Integer.parseInt(s);
                //数量加加
                i1++;
                //给数量TextView赋值
                setCount(i1 + "");
                //调用自定义接口点击事件
                onDownSumLayoutListener.onDownSumLayout();
                break;
        }
    }
    //给数量TextView赋值的方法
    public void setCount(String counts) {
        count.setText(counts);
    }
    //获取数量方法
    public String getCount() {
        return count.getText().toString();
    }
    //自定义接口点击事件
    public interface OnDownSumLayouListener {
        void onDownSumLayout();
    }
    //外部访问接口的方法
    public void setOnDownSumLayoutListener(OnDownSumLayouListener onDownSumLayoutListener) {
        this.onDownSumLayoutListener = onDownSumLayoutListener;
    }
}

别着急下面是自定义组合控件的xml文件  sumlayout.xml

<?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="wrap_content">
    <TextView
        android:id="@+id/sub"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:background="@drawable/sumbgcolor"
        android:text="-"/>
    <TextView
        android:id="@+id/count"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:background="@drawable/sumbgcolor"
        android:text="0"/>
    <TextView
        android:id="@+id/add"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:background="@drawable/sumbgcolor"
        android:text="+"/>
</LinearLayout>

还有自定义背景的xml文件 sumbgcolor.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <stroke android:width="0.1dp" android:color="#000000"></stroke>
    <size android:width="25dp" android:height="15dp"></size>
</shape>

猜你喜欢

转载自blog.csdn.net/zjc_null/article/details/80526734
今日推荐