前言: 

  RecyclerView是android 最常见的列表控件,它现在几乎已经代替了listVIew和GridView的使用,RecyclerView自带强大的功能,实现多种样式,使用更加简单,封装也很容易,相对于listIView,RecyclerView没有自己的item点击事件,需要开发人员自行通过接口回调来实现点击事件,在近期工作不忙时,我查阅了一些开源的商城项目,写了一套很全面的商城app的购物车功能的demo。

闲话少说先上运行图:

RecyclerView 购物车功能      RecyclerView 购物车功能   RecyclerView 购物车功能

就上传这三张图,了解下大致功能。

1.项目搭配代码进行分析(这里只提供主要方法,详细的demo最下方分享)

1),个数的增加与减少实现:

自定义一个类,继承LinearLayoutb (AddSubView)

对加减按钮进行编写


通过回调方法进行回调

RecyclerView 购物车功能

响应回调方法

RecyclerView 购物车功能

2)最外层布局

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#fff"
    android:orientation="vertical">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:background="#fff">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:layout_marginLeft="30dp"
            android:layout_weight="1"
            android:text="购物车"
            android:textColor="#303235"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/tv_shopcart_edit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:text="编辑"
            android:textColor="#303235" />
    </RelativeLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="5dp"
        android:background="#eeee" />

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <android.support.v7.widget.RecyclerView
                android:id="@+id/recyclerview"
                android:layout_width="match_parent"
                android:layout_weight="1"
                android:layout_height="0dp"
                android:background="#eee" />

            <LinearLayout
                android:id="@+id/ll_check_all"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="#fff"
                android:orientation="horizontal"
                android:visibility="visible">

                <CheckBox
                    android:id="@+id/checkbox_all"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerVertical="true"
                    android:button="@null"
                    android:drawableLeft="@drawable/checkbox_selector"
                    android:drawablePadding="10dp"
                    android:padding="10dp"
                    android:paddingLeft="0dp"
                    android:text="全选"
                    android:textColor="#303235"
                    android:textSize="15sp" />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:padding="10dp"
                    android:text="合计:"
                    android:textColor="#303235"
                    android:textSize="15sp" />

                <TextView
                    android:id="@+id/tv_shopcart_total"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:padding="10dp"
                    android:text="¥0.00"
                    android:textColor="#ed3f3f"
                    android:textSize="15sp" />

                <Button
                    android:id="@+id/btn_check_out"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="#ed3f3f"
                    android:text="去结算"
                    android:textColor="#fff" />
            </LinearLayout>

            <LinearLayout
                android:id="@+id/ll_delete"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="#fff"
                android:orientation="horizontal"
                android:padding="5dp"
                android:visibility="gone">

                <CheckBox
                    android:id="@+id/cb_all"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerVertical="true"
                    android:layout_weight="1"
                    android:button="@null"
                    android:drawableLeft="@drawable/checkbox_selector"
                    android:drawablePadding="10dp"
                    android:padding="10dp"
                    android:paddingLeft="0dp"
                    android:text="全选"
                    android:textColor="#303235"
                    android:textSize="15sp" />

                <Button
                    android:id="@+id/btn_delete"
                    android:layout_width="wrap_content"
                    android:layout_height="35dp"
                    android:background="@drawable/words"
                    android:text="删除"
                    android:textColor="#303235"
                    android:textSize="15sp" />

                <Button
                    android:id="@+id/btn_collection"
                    android:layout_width="wrap_content"
                    android:layout_height="35dp"
                    android:layout_marginLeft="15dp"
                    android:background="@drawable/wordsred"
                    android:text="收藏"
                    android:textColor="#ed3f3f"
                    android:textSize="15sp" />
            </LinearLayout>
        </LinearLayout>

        <include layout="@layout/empty_cart" />
    </FrameLayout>
</LinearLayout>

3)购物车的activity

public class MainActivity extends Activity implements View.OnClickListener{

    private TextView tvShopcartEdit;
    private RecyclerView recyclerview;
    private LinearLayout llCheckAll;
    private CheckBox checkboxAll;
    private TextView tvShopcartTotal;
    private Button btnCheckOut;
    private LinearLayout llDelete;
    private CheckBox cbAll;
    private Button btnDelete;
    private Button btnColletion;
    private LinearLayout llViewNo;
    //编辑状态
    private static final int ACTION_EDIT = 1;
    //完成状态
    private static final int ACTION_COMPLETE = 2;
    private ShoppingCartAdapter shoppingCartAdapter;
    List<GoodsBean> allData;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        allData = new ArrayList<>();
        initUI();
    }

    private void initUI() {
        tvShopcartEdit =  findViewById(R.id.tv_shopcart_edit);
        recyclerview = findViewById(R.id.recyclerview);
        llCheckAll = findViewById(R.id.ll_check_all);
        checkboxAll = findViewById(R.id.checkbox_all);
        tvShopcartTotal = findViewById(R.id.tv_shopcart_total);
        btnCheckOut = findViewById(R.id.btn_check_out);
        llDelete = findViewById(R.id.ll_delete);
        cbAll = findViewById(R.id.cb_all);
        btnDelete = findViewById(R.id.btn_delete);
        btnColletion = findViewById(R.id.btn_collection);
        //没有数据的布局
        llViewNo = findViewById(R.id.ll_empty_shopcart);


        btnCheckOut.setOnClickListener(this);
        btnDelete.setOnClickListener(this);
        btnColletion.setOnClickListener(this);

        inistener();
    }


    @Override
    protected void onResume() {
        super.onResume();
        showData();
    }

    private void showData() {

        GoodsBean goodsBean1 = new GoodsBean();
        goodsBean1.setCover_price("159");
        goodsBean1.setFigure("http://img3.imgtn.bdimg.com/it/u=344195214,1892239641&fm=26&gp=0.jpg");
        goodsBean1.setName("时尚男士韩版T血,挥泪大甩卖");
        goodsBean1.setNumber(0);
        GoodsBean goodsBean2 = new GoodsBean();
        goodsBean2.setCover_price("1599.00");
        goodsBean2.setFigure("http://img3.imgtn.bdimg.com/it/u=2757819565,4220707122&fm=26&gp=0.jpg");
        goodsBean2.setName("时尚女性");
        goodsBean2.setNumber(0);
        GoodsBean goodsBean3 = new GoodsBean();
        goodsBean3.setCover_price("1259.00");
        goodsBean3.setFigure("http://img3.imgtn.bdimg.com/it/u=344195214,1892239641&fm=26&gp=0.jpg");
        goodsBean3.setName("时尚男士韩版T血,挥泪大甩卖");
        goodsBean3.setNumber(1);
        GoodsBean goodsBean4 = new GoodsBean();
        goodsBean4.setCover_price("9.99");
        goodsBean4.setFigure("http://img3.imgtn.bdimg.com/it/u=902518220,2743667191&fm=26&gp=0.jpg");
        goodsBean4.setName("时尚男士韩版T血,挥泪大甩卖");
        goodsBean4.setNumber(0);
        allData.add(goodsBean1);
        allData.add(goodsBean2);
        allData.add(goodsBean3);
        allData.add(goodsBean4);
        if(allData != null && allData.size()>0){
            tvShopcartEdit.setVisibility(View.VISIBLE);
            llCheckAll.setVisibility(View.VISIBLE);
            //有数据
            //把当没有数据显示的布局隐藏
            llViewNo.setVisibility(View.GONE);
            //设置适配器
            shoppingCartAdapter = new ShoppingCartAdapter(MainActivity.this,allData,tvShopcartTotal,checkboxAll,cbAll);
            recyclerview.setLayoutManager(new LinearLayoutManager(MainActivity.this,LinearLayoutManager.VERTICAL,false));
            recyclerview.setAdapter(shoppingCartAdapter);
        }else{
            //没有数据 显示数据为空的页面
            emprtyShppingCart();

        }

    }

    private void emprtyShppingCart() {
        llViewNo.setVisibility(View.VISIBLE);
        tvShopcartEdit.setVisibility(View.GONE);
        llDelete.setVisibility(View.GONE);
    }


    private void inistener() {
      //设置默认状态的编辑
        tvShopcartEdit.setTag(ACTION_EDIT);
        tvShopcartEdit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int action = (int) v.getTag();
                if(action == ACTION_EDIT){
                    //切换完成状态
                    showDelete();
                }else{
                    //切换成编辑状态
                    hideDelete();
                }
            }
        });
    }

    /**
     * 编辑状态
     * */
    private void hideDelete() {
        //设置状态文本为完成装填
        tvShopcartEdit.setTag(ACTION_EDIT);
        tvShopcartEdit.setText("编辑");
        //变成非勾选
        if(shoppingCartAdapter != null){
            shoppingCartAdapter.checkAll_none(true);
            shoppingCartAdapter.checkAll();
            shoppingCartAdapter.ShowTotalPrice();
        }
        //删除的视图
        llDelete.setVisibility(View.GONE);
        //结算视图隐藏
        llCheckAll.setVisibility(View.VISIBLE);
    }

    /**
     * 完成状态
     * */
    private void showDelete() {
        //设置状态文本为完成装填
        tvShopcartEdit.setTag(ACTION_COMPLETE);
        tvShopcartEdit.setText("完成");

        //删除的视图
        llDelete.setVisibility(View.VISIBLE);
        //结算视图隐藏
        llCheckAll.setVisibility(View.GONE);
    }

    @Override
    public void onClick(View v) {
        if (v == btnDelete) {
            //删除选中
            shoppingCartAdapter.deleteData();
            //校验
            shoppingCartAdapter.checkAll();
            //数据大小为0
            if(shoppingCartAdapter.getItemCount() == 0){
                emprtyShppingCart();
            }
        }
    }
}

4)适配器的编写

public class ShoppingCartAdapter extends RecyclerView.Adapter<ShoppingCartAdapter.ViewHolder> {

    private Context context;
    private List<GoodsBean> mAllData;
    private TextView mTvShopcartTotal;
    private CheckBox mCheckboxAll;
    /**
     * 完成状态下的删除
     */
    private CheckBox mCbAll;


    public ShoppingCartAdapter(Context mContext, List<GoodsBean> allData, TextView tvShopcartTotal, CheckBox checkboxAll, CheckBox cbAll) {

        this.context = mContext;
        this.mAllData = allData;
        this.mTvShopcartTotal = tvShopcartTotal;
        this.mCheckboxAll = checkboxAll;
        this.mCbAll = cbAll;
        /**
         * 总金额
         * */
        ShowTotalPrice();
        /**
         * 设置点击事件
         * */
        setListener();
        /**
         * 校验是否全选
         * */
        checkAll();

    }

    /**
     * 设置点击事件
     */
    private void setListener() {

        setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(int positon) {
                //根据位置得到对应的bean
                GoodsBean goodsBean = mAllData.get(positon);
                //设置取反装填
                goodsBean.setSelected(!goodsBean.isSelected());
                //刷新数据
                notifyItemChanged(positon);
                //校验是否是全选
                checkAll();
                //重新计算
                ShowTotalPrice();
            }
        });
        //设置全选和非全选按钮的点击事件
        mCheckboxAll.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //得到状态
                boolean isChecked = mCheckboxAll.isChecked();
                //根据状态设置全选和非全选
                checkAll_none(isChecked);
                //计算总价格
                ShowTotalPrice();
            }
        });

        mCbAll.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //得到状态
                boolean isChecked = mCbAll.isChecked();
                //根据状态设置全选非全选
                checkAll_none(isChecked);
            }
        });
    }

    /**
     * 设置全选和非全选
     */
    public void checkAll_none(boolean isChecked) {

        if (mAllData != null && mAllData.size() >= 0) {
            for (int i = 0; i < mAllData.size(); i++) {
                GoodsBean goodsBean = mAllData.get(i);
                goodsBean.setSelected(isChecked);
                notifyItemChanged(i);
            }
        }

    }

    /**
     * 校验是否全选
     */
    public void checkAll() {
        if (mAllData != null && mAllData.size() >= 0) {
            int number = 0;
            for (int i = 0; i < mAllData.size(); i++) {
                GoodsBean goodsBean = mAllData.get(i);
                if (!goodsBean.isSelected()) {
                    //非全选
                    mCheckboxAll.setChecked(false);
                    mCbAll.setChecked(false);
                } else {
                    number++;
                }
            }
            if (number == mAllData.size()) {
                //全选
                mCheckboxAll.setChecked(true);
                mCbAll.setChecked(true);
            }

        } else {
            mCheckboxAll.setChecked(false);
            mCbAll.setChecked(false);
        }
    }

    /**
     * 合计金额
     */
    public void ShowTotalPrice() {
        mTvShopcartTotal.setText("合计:" + getTotalPrices());
    }

    private double getTotalPrices() {

        double totalPrice = 0.0;
        if (mAllData != null && mAllData.size() >= 0) {
            for (int i = 0; i < mAllData.size(); i++) {
                GoodsBean goodsBean = mAllData.get(i);
                if (goodsBean.isSelected()) {
                    totalPrice = totalPrice + Double.valueOf(goodsBean.getNumber()) * Double.valueOf(goodsBean.getCover_price());
                }
            }
        }
        return totalPrice;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = View.inflate(context, R.layout.item_shop_cart, null);
        return new ViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, final int position) {
        //根据位置得到对应的bean
        final GoodsBean goodsBean = mAllData.get(position);
        //设置数据
        holder.cb_gov.setChecked(goodsBean.isSelected());
      Glide.with(context).load(goodsBean.getFigure()).into(holder.iv_gov);
        holder.tv_desc_gov.setText(goodsBean.getName());
        holder.tv_price_gov.setText("¥" + goodsBean.getCover_price());
        holder.add_sub_view.setValue(goodsBean.getNumber());
        holder.add_sub_view.setMinValue(1);
        holder.add_sub_view.setMaxValue(100);
        /**
         * 设置商品数量的变化
         * */
        holder.add_sub_view.setOnNumberChangerListener(new AddSubView.OnNumberChangerListener() {
            @Override
            public void onNumberChange(int value) {
                //列表更新
                goodsBean.setNumber(value);
                //刷新适配器
                notifyItemChanged(position);
                //再次计算总价格
                ShowTotalPrice();
            }
        });
    }
    public void deleteData() {

        if (mAllData != null && mAllData.size() > 0) {
            for (int i = 0; i < mAllData.size(); i++) {
                //删除选中的
                GoodsBean goodsBean = mAllData.get(i);
                if (goodsBean.isSelected()) {
                    //列表移除
                    mAllData.remove(goodsBean);
                    //刷新
                    notifyItemChanged(i);
                }
            }
        }

    }

    @Override
    public int getItemCount() {
        return mAllData == null ? 0 : mAllData.size();
    }

    /**
     * 监听者
     */
    public interface OnItemClickListener {
        /**
         * 点击某一条目的时候暴露的接口方法
         */
        void onItemClick(int positon);

    }

    private OnItemClickListener onItemClickListener;

    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }

    public class ViewHolder extends RecyclerView.ViewHolder{
        private CheckBox cb_gov;
        private ImageView iv_gov;
        private TextView tv_desc_gov;
        private TextView tv_price_gov;
        private AddSubView add_sub_view;


        public ViewHolder(View itemView) {
           super(itemView);
            cb_gov = itemView.findViewById(R.id.cb_gov);
            iv_gov = itemView.findViewById(R.id.iv_gov);
            tv_desc_gov = itemView.findViewById(R.id.tv_desc_gov);
            tv_price_gov = itemView.findViewById(R.id.tv_price_gov);
            add_sub_view = itemView.findViewById(R.id.add_sub_view);
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (onItemClickListener != null) {
                        onItemClickListener.onItemClick(getLayoutPosition());
                    }

                }
            });
        }
    }
}

5)适配器的item布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="10dp">

        <CheckBox
            android:id="@+id/cb_gov"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:button="@drawable/checkbox_selector"
            android:checked="true"
            android:clickable="false" />

        <ImageView
            android:id="@+id/iv_gov"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:background="@drawable/ic_launcher"
            android:scaleType="fitXY" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginLeft="5dp"
            android:orientation="vertical">

            <TextView
                android:id="@+id/tv_desc_gov"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:ellipsize="end"
                android:lines="2"
                android:text="华硕(ASUS)经典系列X554LP 15.6英寸笔记本 (i5-5200U 4G 500G R5-M230 1G独显 蓝牙 Win8.1 黑色)"
                android:textColor="#404040"
                android:textSize="16sp" />

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">

                <TextView
                    android:id="@+id/tv_price_gov"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_gravity="right"
                    android:layout_weight="1"
                    android:gravity="center_vertical"
                    android:text="¥0.0"
                    android:textColor="#f00"
                    android:textSize="16sp" />

                <com.zzsy.shoppingcardemo.view.AddSubView
                    android:id="@+id/add_sub_view"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content" />
            </LinearLayout>
        </LinearLayout>


    </LinearLayout>

    <View

        android:layout_width="match_parent"
        android:layout_height="0.6dp"
        android:background="#22000000" />

</LinearLayout>

整个购物车功能就实现了,里面的注释讲解了该方法的作用。

项目地址:

csdn:

https://download.csdn.net/download/wk_beicai/11064669

github:

https://gitee.com/wangkuo_123456/shopping_cart.git

 

 

相关文章: