Android购物车(二级列表ExpandableListView)

简单版购物车 是用二级列表 框架是MVP 请求网络的方法是OKHttp
以下是效果图
在这里插入图片描述

展开后的效果
在这里插入图片描述
部分中加减的功能是用自定义view实现的
在这里插入图片描述
GitHub地址 https://github.com/zzzzzjson/GoodsListDemo
以下上主要代码
布局文件 MVP框架不在展示
需要的依赖

    implementation 'com.github.bumptech.glide:glide:4.8.0'
    implementation 'com.google.code.gson:gson:2.8.5'
    implementation 'com.squareup.okhttp3:okhttp:3.12.0'

适配器

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;

import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.concurrent.ForkJoinPool;

import soexample.umeng.com.androidgoodslist.MyView;
import soexample.umeng.com.androidgoodslist.R;
import soexample.umeng.com.androidgoodslist.bean.MyBean;

public class MyAdapter extends BaseExpandableListAdapter {
    private ArrayList<MyBean.DataBean> list;
    private Context context;


    public MyAdapter(ArrayList<MyBean.DataBean> list, Context context) {
        this.list = list;
        this.context = context;
    }

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

    @Override
    public int getChildrenCount(int groupPosition) {
        return list.get(groupPosition).getSpus().size();
    }

    @Override
    public Object getGroup(int groupPosition) {
        return null;
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return null;
    }

    @Override
    public long getGroupId(int groupPosition) {
        return 0;
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return 0;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @Override
    public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        groupViewHolder viewHolder = null;
        if (convertView == null) {
            convertView = View.inflate(context, R.layout.group_view, null);
            viewHolder = new groupViewHolder();
            viewHolder.Group_ck = convertView.findViewById(R.id.Group_ck);
            viewHolder.Group_title = convertView.findViewById(R.id.Group_title);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (groupViewHolder) convertView.getTag();
        }
        viewHolder.Group_title.setText(list.get(groupPosition).getName());
        boolean childAllCheck = isChildAllCheck(groupPosition);
        viewHolder.Group_ck.setChecked(childAllCheck);
        viewHolder.Group_ck.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (adapterCallback != null) {
                    adapterCallback.setGroupCheck(groupPosition);
                }
            }
        });
        return convertView;
    }

    @Override
    public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        childViewHolder viewHolder = null;
        if (convertView == null) {
            convertView = View.inflate(context, R.layout.child_view, null);
            viewHolder = new childViewHolder();
            viewHolder.Child_ck = convertView.findViewById(R.id.Child_ck);
            viewHolder.Child_img = convertView.findViewById(R.id.Child_img);
            viewHolder.Child_price = convertView.findViewById(R.id.Child_price);
            viewHolder.Child_title = convertView.findViewById(R.id.Child_title);
            viewHolder.myView = convertView.findViewById(R.id.My_view);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (childViewHolder) convertView.getTag();
        }
        viewHolder.Child_title.setText(list.get(groupPosition).getSpus().get(childPosition).getName() + "");
        viewHolder.Child_price.setText(list.get(groupPosition).getSpus().get(childPosition).getSkus().get(0).getPrice() + "");
        viewHolder.Child_ck.setChecked(list.get(groupPosition).getSpus().get(childPosition).isChildChecked());
        viewHolder.myView.setNumber(list.get(groupPosition).getSpus().get(childPosition).getPraise_num());
        Glide.with(context).load(list.get(groupPosition).getSpus().get(childPosition).getPic_url()).into(viewHolder.Child_img);
        viewHolder.Child_ck.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (adapterCallback != null) {
                    adapterCallback.setChildCheck(groupPosition, childPosition);
                }
            }
        });
        viewHolder.myView.setOnChange(new MyView.OnCountChange() {
            @Override
            public void setCount(int count) {
                if (adapterCallback!=null){
                    adapterCallback.setNumber(groupPosition,childPosition,count);
                }
            }
        });
        return convertView;
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return false;
    }

    class groupViewHolder {
        CheckBox Group_ck;
        TextView Group_title;
    }

    class childViewHolder {
        CheckBox Child_ck;
        ImageView Child_img;
        TextView Child_title;
        TextView Child_price;
        MyView myView;
    }

    //因为点击Group和Child第CheckBox在主页面都需要刷新值所以做成接口回调
    //整个项目的用到的大致方法   接口回调会使用
    public interface AdapterCallback {
        //group的按钮
        void setGroupCheck(int groupPosition);

        //每个child的按钮点击事件
        void setChildCheck(int groupPosition, int childPosition);

        //加减的点击事件
        void setNumber(int groupPosition, int childPosition, int number);
    }

    private AdapterCallback adapterCallback;

    public void setCallback(AdapterCallback adapterCallback) {
        this.adapterCallback = adapterCallback;
    }

    //点击group的CheckBox让所有child选中
    //联动 让child跟着group的状态
    public void childAllCheck(int groupPosition, boolean isChecked) {
        List<MyBean.DataBean.SpusBean> spus = list.get(groupPosition).getSpus();
        for (int i = 0; i < spus.size(); i++) {
            spus.get(i).setChildChecked(isChecked);
        }
    }

    //判断group是否被选中的状态
    public boolean isChildAllCheck(int groupPosition) {
        boolean boo = true;
        List<MyBean.DataBean.SpusBean> spus = list.get(groupPosition).getSpus();
        for (int i = 0; i < spus.size(); i++) {
            MyBean.DataBean.SpusBean spusBean = spus.get(i);
            if (!spusBean.isChildChecked()) {
                return false;
            }
        }
        return boo;
    }

    //点击单独child给他赋值
    public void setChildChecked(int groupPosition, int childPosition, boolean isChecked) {
        MyBean.DataBean.SpusBean spusBean = list.get(groupPosition).getSpus().get(childPosition);
        spusBean.setChildChecked(isChecked);
    }

    //判断单独的child的选中状态
    public boolean isChildChecked(int groupPosition, int childPosition) {
        MyBean.DataBean.SpusBean spusBean = list.get(groupPosition).getSpus().get(childPosition);
        if (spusBean.isChildChecked()) {
            return true;
        }
        return false;
    }

    //给商品数量进行赋值
    public void setGoodsNumber(int groupPosition, int childPosition, int number) {
        list.get(groupPosition).getSpus().get(childPosition).setPraise_num(number);
    }

    //判断底部视图全选全不选的商品状态
    public boolean isAllGoods() {
        boolean boo = true;
        for (int i = 0; i < list.size(); i++) {
            MyBean.DataBean dataBean = list.get(i);
            for (int j = 0; j < dataBean.getSpus().size(); j++) {
                MyBean.DataBean.SpusBean spusBean = dataBean.getSpus().get(j);
                if (!spusBean.isChildChecked()) {
                    boo = false;
                }
            }
        }
        return boo;
    }
    //实现全选全不选的功能
    public void setAllGood(boolean isChecked){
        for (int i = 0; i < list.size(); i++) {
            MyBean.DataBean dataBean = list.get(i);
            for (int j = 0; j < dataBean.getSpus().size(); j++) {
                dataBean.getSpus().get(j).setChildChecked(isChecked);
            }
        }
    }
    //计算所有商品的数量
    public int getAllGoodsNumber(){
        int allNumber=0;
        for (int i = 0; i < list.size(); i++) {
            MyBean.DataBean dataBean = list.get(i);
            for (int j = 0; j < dataBean.getSpus().size(); j++) {
                MyBean.DataBean.SpusBean spusBean = dataBean.getSpus().get(j);
                if (spusBean.isChildChecked()){
                    allNumber+=spusBean.getPraise_num();
                }
            }
        }
        return allNumber;
    }
    //计算所有商品的价格
    public float getAllGoodsPrice(){
        float allPrice=0;
        for (int i = 0; i < list.size(); i++) {
            MyBean.DataBean dataBean = list.get(i);
            for (int j = 0; j < dataBean.getSpus().size(); j++) {
                MyBean.DataBean.SpusBean spusBean = dataBean.getSpus().get(j);
                if (spusBean.isChildChecked()){
                    allPrice+=spusBean.getPraise_num()*Float.parseFloat(spusBean.getSkus().get(0).getPrice());
                }
            }
        }
        return allPrice;
    }
}

MainActivity

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.CheckBox;
import android.widget.ExpandableListView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;

import soexample.umeng.com.androidgoodslist.adapter.MyAdapter;
import soexample.umeng.com.androidgoodslist.base.BaseActivity;
import soexample.umeng.com.androidgoodslist.bean.MyBean;
import soexample.umeng.com.androidgoodslist.presenter.PresenterIMpl;
import soexample.umeng.com.androidgoodslist.view.IView;

public class MainActivity<T> extends BaseActivity implements IView<T> {

    private ExpandableListView Expand_able;
    private CheckBox Check_box;
    private TextView Count_sum;
    private TextView Count_price;
    private PresenterIMpl presenterIMpl;
    private ArrayList<MyBean.DataBean> list = new ArrayList<>();
    private MyAdapter myAdapter;
    //接口
    private String mUrl = "http://www.wanandroid.com/tools/mockapi/6523/restaurant-list";

    @Override
    protected int getLayout() {
        return R.layout.activity_main;
    }

    @Override
    protected void initViews() {
        Expand_able = (ExpandableListView) findViewById(R.id.Expand_able);
        Check_box = (CheckBox) findViewById(R.id.Check_box);
        Count_sum = (TextView) findViewById(R.id.Count_sum);
        Count_price = (TextView) findViewById(R.id.Count_price);
        //去掉自带的箭头
        Expand_able.setGroupIndicator(null);
    }

    @Override
    protected void setOnClick() {
        Check_box.setOnClickListener(this);
    }

    @Override
    protected void processLogin() {
        presenterIMpl = new PresenterIMpl(this);
        myAdapter = new MyAdapter(list, this);
        Expand_able.setAdapter(myAdapter);
        presenterIMpl.startRequest(mUrl);
        myAdapter.setCallback(new MyAdapter.AdapterCallback() {
            //组的是否被选中
            @Override
            public void setGroupCheck(int groupPosition) {
                //判断group的状态
                boolean childAllCheck = myAdapter.isChildAllCheck(groupPosition);
                myAdapter.childAllCheck(groupPosition, !childAllCheck);
                myAdapter.notifyDataSetChanged();
                flushButtonLayout();
            }

            @Override
            public void setChildCheck(int groupPosition, int childPosition) {
                //判断child的状态
                boolean childChecked = myAdapter.isChildChecked(groupPosition, childPosition);
                myAdapter.setChildChecked(groupPosition, childPosition, !childChecked);
                myAdapter.notifyDataSetChanged();
                flushButtonLayout();
            }

            @Override
            public void setNumber(int groupPosition, int childPosition, int number) {
                myAdapter.setGoodsNumber(groupPosition, childPosition, number);
                myAdapter.notifyDataSetChanged();
                flushButtonLayout();
            }
        });
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.Check_box:
            //判断底部全选全不选的状态
            boolean allGoods = myAdapter.isAllGoods();
            myAdapter.setAllGood(!allGoods);
            myAdapter.notifyDataSetChanged();
            flushButtonLayout();
            break;
        }
    }

    @Override
    public void success(T user) {
        MyBean data = (MyBean) user;
        list.addAll(data.getData());
        myAdapter.notifyDataSetChanged();
    }

    @Override
    public void error(T error) {
        Toast.makeText(this, error + "", Toast.LENGTH_SHORT).show();
    }

    //释放资源
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (presenterIMpl != null) {
            presenterIMpl.onDetach();
        }
    }

    private void flushButtonLayout() {
        //上下checkbox联动
        boolean allGoods = myAdapter.isAllGoods();
        Check_box.setChecked(allGoods);
        int allGoodsNumber = myAdapter.getAllGoodsNumber();
        float allGoodsPrice = myAdapter.getAllGoodsPrice();
        Count_price.setText("合计:"+allGoodsPrice);
        Count_sum.setText("去结算(" + allGoodsNumber + ")");
    }
}

自定义文件

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class MyView extends LinearLayout implements View.OnClickListener {
    private TextView delete_text;
    private TextView number_text;
    private TextView add_text;
    //定义商品数量
    private int mCount;
    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
        LayoutInflater.from(context).inflate(R.layout.my_view, this);
        initView();
    }

    private void initView() {
        delete_text=findViewById(R.id.delete_text);
        number_text=findViewById(R.id.number_text);
        add_text=findViewById(R.id.add_text);
        add_text.setOnClickListener(this);
        delete_text.setOnClickListener(this);
    }
    public void setNumber(int number){
      this.mCount=number;
      number_text.setText(number+"");
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.add_text:
                mCount++;
                number_text.setText(mCount+"");
                if (countChange!=null){
                    countChange.setCount(mCount);
                }
                break;
            case R.id.delete_text:
                if (mCount>0){
                    mCount--;
                    number_text.setText(mCount+"");
                    if (countChange!=null){
                        countChange.setCount(mCount);
                    }
                }else {
                    Toast.makeText(getContext(), "商品已售空", Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }
    public interface OnCountChange{
        void setCount(int count);
    }
    private OnCountChange countChange;
    public void setOnChange(OnCountChange countChange){
        this.countChange=countChange;
    }
}

以上二级列表可展开 合住
如果只想要首次加载全部展开,并且点击Group不收缩的效果
可参考 https://blog.csdn.net/jerrywu145/article/details/53014332

  • 0
    点赞
  • 1
    评论
  • 3
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值