仿京东购物车 ExpandableListview

Android 仿淘宝购物车实现 功能基本和淘宝购物车一样,商品按照店铺分类显示,全选,反选,选中商品数量变化,总价随之变化。效果图 购物车页面布局文件activity_shopping_car <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res 阅读详情




首先是购物车的Fragment:


public class ShopCarFragment extends BaseFragment<CartPresenter> implements ICartView, CarttAdapter.CheckInterface,
        CarttAdapter.ModifyCountInterface {




    @BindView(R.id.back)
    ImageView back;
    @BindView(R.id.ex_ListView)
    ExpandableListView exListView;
    @BindView(R.id.chekbox_all)
    CheckBox chekboxAll;
    @BindView(R.id.price_all)
    TextView priceAll;
    @BindView(R.id.goto_pay)
    TextView gotoPay;
    Unbinder unbinder;
    // 组元素数据列表
    private List<StoreInfo> groups = new ArrayList<>();
    // 子元素数据列表
    private Map<String, List<GoodsInfo>> children = new HashMap<>();
    // 购买的商品总价
    private double totalPrice = 0.00;
    // 购买的商品总数量
    private int totalCount = 0;
    private List<GoodsInfo> products;
    private CarttAdapter selva;


    @Override
    protected void initView() {


    }


    @Override
    protected int isLayoutId() {
        return R.layout.fragment_shopcar;
    }


    @Override
    protected BaseModel initModel() {
        return new CartModel();
    }


    @Override
    protected CartPresenter initPresenter() {
        return new CartPresenter();
    }


    @Override
    protected void initDate() {
        presenter.select(71);
    }


    @Override
    public void onSelect(SelectCartBean selectCartBean) {


        List<SelectCartBean.DataBean> data = selectCartBean.getData();
        for (int i = 0; i < data.size(); i++) {
            groups.add(new StoreInfo(data.get(i).getSellerid(), data.get(i).getSellerName()));
            products = new ArrayList<>();
            for (int j = 0; j < data.get(i).getList().size(); j++) {
                String images = data.get(i).getList().get(j).getImages();
                String[] split = images.split("[|]");
                String[] split1 = split[0].split("[!]");
                List<SelectCartBean.DataBean.ListBean> list = data.get(i).getList();
                products.add(new GoodsInfo(list.get(j).getPid() + "", "商品", list.get(j).getTitle(), Double.valueOf(list.get(j).getPrice() + ""), Integer.parseInt(list.get(j).getNum() + ""), "", "1", split1[0], Double.valueOf(list.get(j).getBargainPrice())));
            }
            // 将组元素的一个唯一值,这里取Id,作为子元素List的Key
            children.put(groups.get(i).getId(), products);
        }
        selva = new CarttAdapter(groups, children, getContext());
        selva.setCheckInterface(this);// 关键步骤1,设置复选框接口
        selva.setModifyCountInterface(this);// 关键步骤2,设置数量增减接口
        exListView.setAdapter(selva);
        //默认展开
        for (int i = 0; i < selva.getGroupCount(); i++) {
            // 关键步骤3,初始化时,将ExpandableListView以展开的方式呈现
            exListView.expandGroup(i);
        }


    }


    @Override
    public void onDelete(DeleteCartBean deleteCartBean) {
        Toast.makeText(getContext(), deleteCartBean.getMsg(), Toast.LENGTH_SHORT).show();
    }


    @OnClick({R.id.back, R.id.chekbox_all, R.id.goto_pay})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.back:
                break;
            case R.id.chekbox_all:
                doCheckAll();
                break;
            case R.id.goto_pay:
                /**
                 * 支付提示
                 */
                AlertDialog alert = new AlertDialog.Builder(getContext()).create();
                alert.setTitle("操作提示");
                alert.setMessage("总计:\n" + totalCount + "种商品\n" + totalPrice + "元");
                alert.setButton(DialogInterface.BUTTON_NEGATIVE, "取消",
                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                return;
                            }
                        });
                alert.setButton(DialogInterface.BUTTON_POSITIVE, "确定",
                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                if (totalCount == 0) {
                                    Toast.makeText(getContext(), "请选择要支付的商品", Toast.LENGTH_LONG).show();
                                    return;
                                }
                            }
                        });
                alert.show();
                break;
        }
    }


    /**
     * 全选反选
     */
    private void doCheckAll() {
        for (int i = 0; i < groups.size(); i++) {
            groups.get(i).setChoosed(chekboxAll.isChecked());
            StoreInfo group = groups.get(i);
            List<GoodsInfo> childs = children.get(group.getId());
            for (int j = 0; j < childs.size(); j++) {
                childs.get(j).setChoosed(chekboxAll.isChecked());
            }
        }
        //调用计算总数量与总价方法
        calculate();
        //刷新
        selva.notifyDataSetChanged();
    }


    /**
     * 计算总数量与总价
     */
    private void calculate() {
        totalCount = 0;
        totalPrice = 0.00;
        for (int i = 0; i < groups.size(); i++) {
            StoreInfo group = groups.get(i);
            List<GoodsInfo> childs = children.get(group.getId());
            for (int j = 0; j < childs.size(); j++) {
                GoodsInfo product = childs.get(j);
                if (product.isChoosed()) {
                    totalCount++;
                    totalPrice += product.getDiscountPrice() * product.getCount();
                }
            }
        }
        priceAll.setText("¥" + totalPrice);
        gotoPay.setText("结算(" + totalCount + ")");
    }


    /**
     * 判断所有组选框状态是否全部选中
     *
     * @return
     */
    private boolean isAllCheck() {


        for (StoreInfo group : groups) {
            if (!group.isChoosed())
                return false;
        }
        return true;
    }


    /**
     * 组选框状态改变触发的事件
     *
     * @param groupPosition 组元素位置
     * @param isChecked     组元素选中与否
     */
    @Override
    public void checkGroup(int groupPosition, boolean isChecked) {
        StoreInfo group = groups.get(groupPosition);
        List<GoodsInfo> childs = children.get(group.getId());
        for (int i = 0; i < childs.size(); i++) {
            childs.get(i).setChoosed(isChecked);
        }
        if (isAllCheck())
            chekboxAll.setChecked(true);
        else
            chekboxAll.setChecked(false);
        selva.notifyDataSetChanged();
        calculate();
    }


    /**
     * 子选框状态改变时触发的事件
     *
     * @param groupPosition 组元素位置
     * @param childPosition 子元素位置
     * @param isChecked     子元素选中与否
     */
    @Override
    public void checkChild(int groupPosition, int childPosition, boolean isChecked) {
        // 判断改组下面的所有子元素是否是同一种状态
        boolean allChildSameState = true;
        StoreInfo group = groups.get(groupPosition);
        List<GoodsInfo> childs = children.get(group.getId());
        for (int i = 0; i < childs.size(); i++) {
            // 不全选中
            if (childs.get(i).isChoosed() != isChecked) {
                allChildSameState = false;
                break;
            }
        }
        //获取店铺选中商品的总金额
        if (allChildSameState) {
            // 如果所有子元素状态相同,那么对应的组元素被设为这种统一状态
            group.setChoosed(isChecked);
        } else {
            // 否则,组元素一律设置为未选中状态
            group.setChoosed(false);
        }
        if (isAllCheck()) {
            // 全选
            chekboxAll.setChecked(true);
        } else {
            // 反选
            chekboxAll.setChecked(false);
        }
        selva.notifyDataSetChanged();
        calculate();
    }


    /**
     * 添加
     *
     */
    @Override
    public void doIncrease(int groupPosition, int childPosition, View showCountView, boolean isChecked) {
        GoodsInfo product = (GoodsInfo) selva.getChild(groupPosition, childPosition);
        int currentCount = product.getCount();
        currentCount++;
        product.setCount(currentCount);
        ((TextView) showCountView).setText(currentCount + "");
        calculate();
        selva.notifyDataSetChanged();
    }


    /**
     * 删除
     *
     */
    @Override
    public void doDecrease(int groupPosition, int childPosition, View showCountView, boolean isChecked) {
        GoodsInfo product = (GoodsInfo) selva.getChild(groupPosition, childPosition);
        int currentCount = product.getCount();
        if (currentCount == 1) {
            Toast.makeText(getContext(), "数量不能少于1", Toast.LENGTH_SHORT).show();
            return;
        }
        currentCount--;
        product.setCount(currentCount);
        ((TextView) showCountView).setText(currentCount + "");
        calculate();
        selva.notifyDataSetChanged();
    }


    /**
     * 删除Child
     *
     */
    @Override
    public void childDelete(final int groupPosition, final int childPosition, int pid) {
        children.get(groups.get(groupPosition).getId()).remove(childPosition);
        StoreInfo group = groups.get(groupPosition);
        List<GoodsInfo> childs = children.get(group.getId());
        if (childs.size() == 0) {
            presenter.delete(71, pid);
//            Log.e("del----pid", pid + "");
            groups.remove(groupPosition);
        }
        selva.notifyDataSetChanged();
    }
}


model层:

public class CartModel extends BaseModel {


    public void getSelect(int uid, final ICartModel iCartModel) {
        RetrofitFactory.getINSTANCE().getHomeApi()
                .getSelect(uid)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<SelectCartBean>() {
                    @Override
                    public void onSubscribe(Disposable d) {


                    }


                    @Override
                    public void onNext(SelectCartBean selectCartBean) {
                        iCartModel.onSelect(selectCartBean);
                    }


                    @Override
                    public void onError(Throwable e) {


                    }


                    @Override
                    public void onComplete() {


                    }
                });
    }




    public void getDelete(int uid, int pid, final ICartModel iCartModel) {
        RetrofitFactory.getINSTANCE().getHomeApi()
                .getDelete(uid, pid)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<DeleteCartBean>() {
                    @Override
                    public void onSubscribe(Disposable d) {


                    }


                    @Override
                    public void onNext(DeleteCartBean deleteCartBean) {
                        iCartModel.onDelete(deleteCartBean);
                    }


                    @Override
                    public void onError(Throwable e) {


                    }


                    @Override
                    public void onComplete() {


                    }
                });
    }


    public interface ICartModel {
        void onSelect(SelectCartBean selectCartBean);


        void onDelete(DeleteCartBean deleteCartBean);
    }


}


presenter层:

public class CartPresenter extends BasePresenter<CartModel, ICartView> {


    public void select(int uid) {
        model.getSelect(uid, new CartModel.ICartModel() {
            @Override
            public void onSelect(SelectCartBean selectCartBean) {
                view.onSelect(selectCartBean);
            }


            @Override
            public void onDelete(DeleteCartBean deleteCartBean) {


            }
        });
    }


    public void delete(int uid, int pid) {
        model.getDelete(uid, pid, new CartModel.ICartModel() {
            @Override
            public void onSelect(SelectCartBean selectCartBean) {


            }


            @Override
            public void onDelete(DeleteCartBean deleteCartBean) {
                view.onDelete(deleteCartBean);
            }
        });
    }


}


view接口:

public interface ICartView extends IBaseView {
    void onSelect(SelectCartBean selectCartBean);
    void onDelete(DeleteCartBean deleteCartBean);
}


bean类


查询购物车:

public class SelectCartBean {


    /**
     * msg : 请求成功
     * code : 0
     * data : [{"list":[{"bargainPrice":111.99,"createtime":"2017-10-03T23:53:28","detailUrl":"https://item.m.jd.com/product/4719303.html?utm_source=androidapp&utm_medium=appshare&utm_campaign=t_335139774&utm_term=QQfriends","images":"https://m.360buyimg.com/n0/jfs/t9004/210/1160833155/647627/ad6be059/59b4f4e1N9a2b1532.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t7504/338/63721388/491286/f5957f53/598e95f1N7f2adb87.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t7441/10/64242474/419246/adb30a7d/598e95fbNd989ba0a.jpg!q70.jpg","num":1,"pid":6,"price":7.99,"pscid":1,"selected":1,"sellerid":22,"subhead":"每个中秋都不能简单,无论身在何处,你总需要一块饼让生活更圆满,京东月饼让爱更圆满京东自营,闪电配送,更多惊喜,快用手指戳一下","title":"北京稻香村 稻香村中秋节月饼 老北京月饼礼盒655g"}],"sellerName":"商家22","sellerid":"22"}]
     */


    private String msg;
    private String code;
    private List<DataBean> data;


    public String getMsg() {
        return msg;
    }


    public void setMsg(String msg) {
        this.msg = msg;
    }


    public String getCode() {
        return code;
    }


    public void setCode(String code) {
        this.code = code;
    }


    public List<DataBean> getData() {
        return data;
    }


    public void setData(List<DataBean> data) {
        this.data = data;
    }


    public static class DataBean {
        /**
         * list : [{"bargainPrice":111.99,"createtime":"2017-10-03T23:53:28","detailUrl":"https://item.m.jd.com/product/4719303.html?utm_source=androidapp&utm_medium=appshare&utm_campaign=t_335139774&utm_term=QQfriends","images":"https://m.360buyimg.com/n0/jfs/t9004/210/1160833155/647627/ad6be059/59b4f4e1N9a2b1532.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t7504/338/63721388/491286/f5957f53/598e95f1N7f2adb87.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t7441/10/64242474/419246/adb30a7d/598e95fbNd989ba0a.jpg!q70.jpg","num":1,"pid":6,"price":7.99,"pscid":1,"selected":1,"sellerid":22,"subhead":"每个中秋都不能简单,无论身在何处,你总需要一块饼让生活更圆满,京东月饼让爱更圆满京东自营,闪电配送,更多惊喜,快用手指戳一下","title":"北京稻香村 稻香村中秋节月饼 老北京月饼礼盒655g"}]
         * sellerName : 商家22
         * sellerid : 22
         */


        private String sellerName;
        private String sellerid;
        private List<ListBean> list;


        public String getSellerName() {
            return sellerName;
        }


        public void setSellerName(String sellerName) {
            this.sellerName = sellerName;
        }


        public String getSellerid() {
            return sellerid;
        }


        public void setSellerid(String sellerid) {
            this.sellerid = sellerid;
        }


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


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


        public static class ListBean {
            /**
             * bargainPrice : 111.99
             * createtime : 2017-10-03T23:53:28
             * detailUrl : https://item.m.jd.com/product/4719303.html?utm_source=androidapp&utm_medium=appshare&utm_campaign=t_335139774&utm_term=QQfriends
             * images : https://m.360buyimg.com/n0/jfs/t9004/210/1160833155/647627/ad6be059/59b4f4e1N9a2b1532.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t7504/338/63721388/491286/f5957f53/598e95f1N7f2adb87.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t7441/10/64242474/419246/adb30a7d/598e95fbNd989ba0a.jpg!q70.jpg
             * num : 1
             * pid : 6
             * price : 7.99
             * pscid : 1
             * selected : 1
             * sellerid : 22
             * subhead : 每个中秋都不能简单,无论身在何处,你总需要一块饼让生活更圆满,京东月饼让爱更圆满京东自营,闪电配送,更多惊喜,快用手指戳一下
             * title : 北京稻香村 稻香村中秋节月饼 老北京月饼礼盒655g
             */


            private double bargainPrice;
            private String createtime;
            private String detailUrl;
            private String images;
            private int num;
            private int pid;
            private double price;
            private int pscid;
            private int selected;
            private int sellerid;
            private String subhead;
            private String title;


            public double getBargainPrice() {
                return bargainPrice;
            }


            public void setBargainPrice(double bargainPrice) {
                this.bargainPrice = bargainPrice;
            }


            public String getCreatetime() {
                return createtime;
            }


            public void setCreatetime(String createtime) {
                this.createtime = createtime;
            }


            public String getDetailUrl() {
                return detailUrl;
            }


            public void setDetailUrl(String detailUrl) {
                this.detailUrl = detailUrl;
            }


            public String getImages() {
                return images;
            }


            public void setImages(String images) {
                this.images = images;
            }


            public int getNum() {
                return num;
            }


            public void setNum(int num) {
                this.num = num;
            }


            public int getPid() {
                return pid;
            }


            public void setPid(int pid) {
                this.pid = pid;
            }


            public double getPrice() {
                return price;
            }


            public void setPrice(double price) {
                this.price = price;
            }


            public int getPscid() {
                return pscid;
            }


            public void setPscid(int pscid) {
                this.pscid = pscid;
            }


            public int getSelected() {
                return selected;
            }


            public void setSelected(int selected) {
                this.selected = selected;
            }


            public int getSellerid() {
                return sellerid;
            }


            public void setSellerid(int sellerid) {
                this.sellerid = sellerid;
            }


            public String getSubhead() {
                return subhead;
            }


            public void setSubhead(String subhead) {
                this.subhead = subhead;
            }


            public String getTitle() {
                return title;
            }


            public void setTitle(String title) {
                this.title = title;
            }
        }
    }
}


商家信息bean类

public class StoreInfo
{  
    protected String Id;  
    protected String name;  
    protected boolean isChoosed;  
    private boolean isEdtor;  
  
    public boolean isEdtor() {  
        return isEdtor;  
    }  
  
    public void setIsEdtor(boolean isEdtor) {  
        this.isEdtor = isEdtor;  
    }  
  
    public StoreInfo(String id, String name) {  
        Id = id;  
        this.name = name;  
    }  
  
    public String getId() {  
        return Id;  
    }  
  
    public void setId(String id) {  
        Id = id;  
    }  
  
    public String getName() {  
        return name;  
    }  
  
    public void setName(String name) {  
        this.name = name;  
    }  
  
    public boolean isChoosed() {  
        return isChoosed;  
    }  
  
    public void setChoosed(boolean isChoosed) {  
        this.isChoosed = isChoosed;  
    }  
}


商品信息bean类:


public class GoodsInfo {
    protected String Id;
    protected String name;
    protected boolean isChoosed;
    private String imageUrl;
    private String desc;
    private double price;
    private int count;
    private int position;// 绝对位置,只在ListView构造的购物车中,在删除时有效  
    private String color;
    private String size;
    private String goodsImg;
    private double discountPrice;


    public double getDiscountPrice() {
        return discountPrice;
    }


    public void setDiscountPrice(double discountPrice) {
        this.discountPrice = discountPrice;
    }


    public String getGoodsImg() {
        return goodsImg;
    }


    public void setGoodsImg(String goodsImg) {
        this.goodsImg = goodsImg;
    }


    public String getColor() {
        return color;
    }


    public void setColor(String color) {
        this.color = color;
    }


    public String getSize() {
        return size;
    }


    public void setSize(String size) {
        this.size = size;
    }


    public GoodsInfo(String id, String name, String desc, double price, int count, String color,
                     String size, String goodsImg, double discountPrice) {
        this.Id = id;
        this.name = name;
        this.desc = desc;
        this.price = price;
        this.count = count;
        this.color = color;
        this.size = size;
        this.goodsImg = goodsImg;
        this.discountPrice = discountPrice;
    }


    public String getId() {
        return Id;
    }


    public void setId(String id) {
        Id = id;
    }


    public String getName() {
        return name;
    }


    public void setName(String name) {
        this.name = name;
    }


    public boolean isChoosed() {
        return isChoosed;
    }


    public void setChoosed(boolean isChoosed) {
        this.isChoosed = isChoosed;
    }


    public String getImageUrl() {
        return imageUrl;
    }


    public void setImageUrl(String imageUrl) {
        this.imageUrl = imageUrl;
    }


    public String getDesc() {
        return desc;
    }


    public void setDesc(String desc) {
        this.desc = desc;
    }


    public int getCount() {
        return count;
    }


    public void setCount(int count) {
        this.count = count;
    }


    public double getPrice() {
        return price;
    }


    public void setPrice(double price) {
        this.price = price;
    }


    public int getPosition() {
        return position;
    }


    public void setPosition(int position) {
        this.position = position;
    }
}


删除bean类

public class DeleteCartBean {


    /**
     * msg : 购物车数据不存在
     * code : 1
     */


    private String msg;
    private String code;


    public String getMsg() {
        return msg;
    }


    public void setMsg(String msg) {
        this.msg = msg;
    }


    public String getCode() {
        return code;
    }


    public void setCode(String code) {
        this.code = code;
    }
}


购物车适配器 ExpandableListview实现




import android.content.Context;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.StrikethroughSpan;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;




import com.bumptech.glide.Glide;
import java.util.List;
import java.util.Map;
import bwie.com.R;
import bwie.com.shoppingcar.bean.GoodsInfo;
import bwie.com.shoppingcar.bean.StoreInfo;




public class CarttAdapter extends BaseExpandableListAdapter {
    private List<StoreInfo> groups;
    private Map<String, List<GoodsInfo>> children;
    private Context context;
    private CheckInterface checkInterface;
    private ModifyCountInterface modifyCountInterface;


    /**
     * 构造函数
     *
     * @param groups   组元素列表
     * @param children 子元素列表
     * @param context
     */
    public CarttAdapter(List<StoreInfo> groups, Map<String, List<GoodsInfo>> children, Context context) {
        this.groups = groups;
        this.children = children;
        this.context = context;
    }


    public void setCheckInterface(CheckInterface checkInterface) {
        this.checkInterface = checkInterface;
    }


    public void setModifyCountInterface(ModifyCountInterface modifyCountInterface) {
        this.modifyCountInterface = modifyCountInterface;
    }


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


    @Override
    public int getChildrenCount(int groupPosition) {
        String groupId = groups.get(groupPosition).getId();
        return children.get(groupId).size();
    }


    @Override
    public Object getGroup(int groupPosition) {
        return groups.get(groupPosition);
    }


    @Override
    public Object getChild(int groupPosition, int childPosition) {
        List<GoodsInfo> childs = children.get(groups.get(groupPosition).getId());
        return childs.get(childPosition);
    }


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


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


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


    @Override
    public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        final GroupViewHolder gholder;
        if (convertView == null) {
            gholder = new GroupViewHolder();
            //父列表
            convertView = View.inflate(context, R.layout.cart_group_item, null);
            gholder.cb_check = (CheckBox) convertView.findViewById(R.id.determine_chekbox);
            gholder.tv_group_name = (TextView) convertView.findViewById(R.id.tv_source_name);
            convertView.setTag(gholder);
        } else {
            gholder = (GroupViewHolder) convertView.getTag();
        }
        final StoreInfo group = (StoreInfo) getGroup(groupPosition);
        if (group != null) {
            //商家名称
            gholder.tv_group_name.setText(group.getName());
            //商家复选框
            gholder.cb_check.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //复选框状态
                    group.setChoosed(((CheckBox) v).isChecked());
                    // 暴露组选接口
                    checkInterface.checkGroup(groupPosition, ((CheckBox) v).isChecked());
                }
            });
            gholder.cb_check.setChecked(group.isChoosed());
        } else {
            groups.remove(groupPosition);
        }


        return convertView;
    }


    @Override
    public View getChildView(final int groupPosition, final int childPosition, final boolean isLastChild, View convertView, final ViewGroup parent) {
        final ChildViewHolder cholder;
        if (convertView == null) {
            cholder = new ChildViewHolder();
            //子列表
            convertView = View.inflate(context, R.layout.cart_child_item, null);
            cholder.cb_check = (CheckBox) convertView.findViewById(R.id.check_box);
            cholder.tv_product_desc = (TextView) convertView.findViewById(R.id.tv_intro);
            cholder.tv_price = (TextView) convertView.findViewById(R.id.tv_price);
            cholder.iv_increase = (TextView) convertView.findViewById(R.id.tv_add);
            cholder.iv_decrease = (TextView) convertView.findViewById(R.id.tv_reduce);
            cholder.tv_count = (TextView) convertView.findViewById(R.id.tv_num);
            cholder.rl_no_edtor = (RelativeLayout) convertView.findViewById(R.id.rl_no_edtor);
            cholder.tv_discount_price = (TextView) convertView.findViewById(R.id.tv_discount_price);
            cholder.tv_buy_num = (TextView) convertView.findViewById(R.id.tv_buy_num);
            cholder.tv_goods_delete = (TextView) convertView.findViewById(R.id.tv_goods_delete);
            cholder.iv_adapter_list_pic = (ImageView) convertView.findViewById(R.id.iv_adapter_list_pic);
            convertView.setTag(cholder);
        } else {
            cholder = (ChildViewHolder) convertView.getTag();
        }
        final GoodsInfo goodsInfo = (GoodsInfo) getChild(groupPosition, childPosition);
        if (goodsInfo != null) {
            cholder.tv_product_desc.setText(goodsInfo.getDesc());
            cholder.tv_price.setText("¥" + goodsInfo.getDiscountPrice() + "");
            cholder.tv_count.setText(goodsInfo.getCount() + "");
            Glide.with(context).load(goodsInfo.getGoodsImg()).into(cholder.iv_adapter_list_pic);
            //给原价加横线
            SpannableString spanString = new SpannableString("¥" + String.valueOf(goodsInfo.getPrice()));
            StrikethroughSpan span = new StrikethroughSpan();
            spanString.setSpan(span, 0, String.valueOf(goodsInfo.getPrice()).length() + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            cholder.tv_discount_price.setText(spanString);
            cholder.tv_buy_num.setText("x" + goodsInfo.getCount());
            cholder.cb_check.setChecked(goodsInfo.isChoosed());
            //商品复选框点击事件
            cholder.cb_check.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //复选框状态
                    goodsInfo.setChoosed(((CheckBox) v).isChecked());
                    cholder.cb_check.setChecked(((CheckBox) v).isChecked());
                    // 暴露子选接口
                    checkInterface.checkChild(groupPosition, childPosition, ((CheckBox) v).isChecked());
                }
            });
            //增加
            cholder.iv_increase.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // 暴露增加接口
                    modifyCountInterface.doIncrease(groupPosition, childPosition, cholder.tv_count, cholder.cb_check.isChecked());
                }
            });
            //删减
            cholder.iv_decrease.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // 暴露删减接口
                    modifyCountInterface.doDecrease(groupPosition, childPosition, cholder.tv_count, cholder.cb_check.isChecked());
                }
            });
            //删除 购物车  
            cholder.tv_goods_delete.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    modifyCountInterface.childDelete(groupPosition, childPosition, Integer.valueOf(goodsInfo.getId()));
                }
            });
        }
        return convertView;
    }


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


    /**
     * 组元素绑定器
     */
    private class GroupViewHolder {
        CheckBox cb_check;
        TextView tv_group_name;
    }


    /**
     * 子元素绑定器
     */
    private class ChildViewHolder {
        CheckBox cb_check;
        ImageView iv_adapter_list_pic;
        TextView tv_product_desc;
        TextView tv_price;
        TextView iv_increase;
        TextView tv_count;
        TextView iv_decrease;
        RelativeLayout rl_no_edtor;
        TextView tv_discount_price;
        TextView tv_buy_num;
        TextView tv_goods_delete;
    }


    /**
     * 复选框接口
     */
    public interface CheckInterface {
        /**
         * 组选框状态改变触发的事件
         *
         * @param groupPosition 组元素位置
         * @param isChecked     组元素选中与否
         */
        public void checkGroup(int groupPosition, boolean isChecked);


        /**
         * 子选框状态改变时触发的事件
         *
         * @param groupPosition 组元素位置
         * @param childPosition 子元素位置
         * @param isChecked     子元素选中与否
         */
        public void checkChild(int groupPosition, int childPosition, boolean isChecked);
    }


    /**
     * 改变数量的接口
     */
    public interface ModifyCountInterface {
        /**
         * 增加操作
         *
         * @param groupPosition 组元素位置
         * @param childPosition 子元素位置
         * @param showCountView 用于展示变化后数量的View
         * @param isChecked     子元素选中与否
         */
        public void doIncrease(int groupPosition, int childPosition, View showCountView, boolean isChecked);


        /**
         * 删减操作
         *
         * @param groupPosition 组元素位置
         * @param childPosition 子元素位置
         * @param showCountView 用于展示变化后数量的View
         * @param isChecked     子元素选中与否
         */
        public void doDecrease(int groupPosition, int childPosition, View showCountView, boolean isChecked);


        /**
         * 删除子item
         *
         * @param groupPosition
         * @param childPosition
         */
        public void childDelete(int groupPosition, int childPosition, int pid);
    }


}



最后附上github地址

https://github.com/Wittman0980/New_AndroidJD_06


ps:萌新勿喷..






Android模仿淘宝购物车 Android模仿淘宝购物车实现店铺分类商品,单选多选计算总价前,单个编辑商品的数量,总体的编辑 立即下载

相关推荐

Android-使用ExpandableListView实现的购物车

使用ExpandableListView实现的购物车,解决了EditText输入与焦点错乱问题,用二阶贝塞尔曲线实现购物车动画

Android购物车的实现(升级版 仿淘宝)

前面有篇文章实现了Android 简单的购物车 这篇实现了购物车中商品按照店铺分类显示的 也就是淘宝购物车的显示方式。

山寨戴王 2万+

ExpandableListview实现安卓购物车功能

用ListView实现了安卓购物车的数量增减,全选,反选,组选,子选。

Android仿淘宝购物车,玩转电商购物车

前言其实做一个电商购物车,还真不是一个轻松的活。但是只要掌握思路,一步一步来做,就会发现也就这样。废物不多说,直接上效果图 完整代码,github链接,希望能给个星,谢谢效果图 主要思路整一个布局就是ExpandableListView,然后自定义一个ActionBar,ActionBar上面显示购物车数量,通过ActionBar上面的编辑状态,店铺布局,所有商品布局,底部布局要进行相应的变化,

cmazxiaoma的博客 1432

ExpandableListView实现Android购物车

Android购物车

Android开发丶教你使用ExpandableListView一步步从零实现商城购物车(含demo超详细)

使用expandable完成电商项目常用的购物车模块,里面涵盖了大部分的常见功能,删除,增减,结算,多店铺多商品的逻辑处理优化,欢迎下载!

安卓APP源码和设计报告——仿淘宝购物APP

2021—2022学年第二学期期末考试《Android手机软件开发》实践考核项目设计说明书项目名称: 购物APP的设计与实现专 业: 计算机科学与技术学 号:姓 名:任课教师:2022年6月12日目 录1.项目概述112.项目需求分析113.开发环境224.界面设计224.1登录224.2主页面224.3商品详情页面334.4商品页面444.5购物车页面554.6个人界面665.数据存储776.项目开发与实现886.1登录886.2主页面886.3商品详情页面886.4商品页面886.5购物车页面996.6

科大云炬 5088

Android实现的仿淘宝购物车demo示例

主要介绍了Android实现的仿淘宝购物车demo示例,结合实例形式分析了Android购物车的功能、布局及逻辑实现技巧,需要的朋友可以参考下

二级列表ExpandableListView 仿京东购物车

public class CartAdaper extends BaseExpandableListAdapter{     Context context;     List data;     iPresenter iPresenter ;     CartView cartView;     public CartAdaper(CartView cartView, Context

XiaoZhuang__的博客 503

OnlyOffice Docker部署全攻略:解除连接限制+文件大小限制+中文字体优化

本文详细介绍了OnlyOffice企业级Docker部署的完整解决方案,重点破解连接限制、文件大小限制和中文字体优化三大核心痛点。通过定制化镜像部署、性能调优配置和中文字体深度优化,帮助企业实现高效稳定的文档协作平台。

weixin_28837817的博客 366

方差分析ANOVA、T检验、卡方检验的区别

T检验和ANOVA都是用来看样本之间均值是否相等,但是两者又有什么区别呢? 卡方检验是用来看分类变量之间有没有相关性。 自变量X类型 自变量X组数 因变量Y类型 分析方法 离散(类别) 仅仅2组 连续(均值) t检验 离散(类别) 2组及以上 连续(均值) ANOVA 离散(类别) 2组及以上 离散(类别) 卡方检验 进一步细分 方差分析 从理论上讲,方差分析有两个前提条件,一是因变量Y需要满足正态性要求,二是满足方差齐检验。 方差不齐时可使用‘非参数检验’,同时还可使用wel

itslifeng的博客 4万+

Android-ExpandableListView 仿京东淘宝购物车

先上项目效果图项目分析1、拿到这个需求的时候以为是用ListView做的,然后发现自己好天真,因为它的店铺个数是不确定的,然后同一个店铺下面的商品也可能是多个的,so 然后自己百度了下,发现Android原生有个ExpandableListView列表组件,就可以用来搞这个购物车正好合适。 2、ExpandableListView原生的样式是隐藏列表内容,所以我们只需要用个for循环把每个列表的内容

q771410116的博客 976

告别手动群发!用IDA Pro和CE搞定企业微信4.1.38.6011的HOOK开发(附完整代码)

本文详细介绍了如何利用IDA Pro和Cheat Engine进行企业微信4.1.38.6011的HOOK开发,实现自动化群发功能。从逆向工程环境配置、关键函数定位到HOOK框架设计,提供完整代码示例,帮助企业提升运营效率。

weixin_42533120的博客 478

ExpandableListview购物车

一、ViewPage: 1.xml <android.support.v4.view.ViewPager android:id="@+id/pager" android:layout_weight="1" android:layout_width="match_parent" andr...

qq_43578439的博客 233

计组实验4 控制冒险与分支预测

目录前言实验内容背景知识分支预测技术⭐阻塞周期计算方法不开启 BTB开启 BTBpart 1 矩阵乘法与优化未开启 BTB 的分析开启 BTB 的分析part 2 设计代码使 BTB 无效part 3 循环展开优化矩阵乘法未开启 BTB开启 BTB结束语结论 前言 上一篇博客:计组实验3 mips冒险之流水线冒险 摸了半个月了。。。咕咕咕 今天来写计组实验 4 这个实验非常简单,就是有点难。 这个实验比较容易算错,或者是被模拟器出人意料的结果搞的神神叨叨的,所以今天来记录并且详细分析该实验。 注:请务必阅

AKGWSB 's blog 5667

Android 10 根文件系统和编译系统(十):Android.mk编译动态库

配套系列教学视频链接: Android 10.0 AOSP源码编译: 2-AOSP源码开发环境搭建 Android 10.0 根文件系统和编译系统: 3-Android根文件系统和编译系统 说明 系统:AOSP Android10.0 设备:Android模拟器 前言 本文章重点讲解Android.mk如何控制编译源码编译成动态库 ...

ldswfun的专栏 932

ExpandableListView购物车—+okhttp封装

MainActivity的代码 package likuo.bwie.com.day19; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget....

Hypoc7isyLK的博客 350

WorkBuddy 集成 飞书CLI,全程10分钟,丝滑无比,老板要注意了...

飞书CLI实测:10分钟实现AI操控飞书办公 飞书CLI作为命令行工具,让用户通过简单命令完成飞书各项操作。本文记录了从安装到使用的完整过程:一键安装仅需10分钟,支持200多条命令覆盖飞书全部功能,与AI结合后可实现自然语言办公。实测中成功用语音指令创建了7天发文计划日程,验证了其便捷性。虽然首次认证存在超时问题,但整体体验流畅。该工具将复杂操作简化为自然语言指令,大幅提升办公效率,特别适合需要频繁使用飞书的用户。后续还将探索更多自动化办公场景。

三棱球的专栏 1142

仿京东购物车页面

、、依赖//ok implementation 'com.squareup.okhttp3:okhttp:3.9.0' //gson implementation 'com.google.code.gson:gson:2.8.4' //拦截器的依赖 implementation 'com.squareup.okhttp3:logging-interceptor:3.9.0' //reclervie...

chenyibai的博客 882

基于阻抗控制的工业机器人轨迹跟踪系统 Simulink/Simscape 仿真

  本文是对文献 [1] 的复现。 关于阻抗控制   阻抗控制的提出可以追溯到 1984 年,Neville Hogan 在 American Control Conference 发表的 Impedance Control:An Approach to Manipulation ,次年,Hogan N. 又在 Journal of Dynamic Systems Measurement and Control-transactions of The Asme 发表了阻抗控制经典三部曲 —— Imped.

-贝塔- 的博客 2万+

eCognition易康操作教程(二):多尺度分割基于多光谱数据构建规则集,结合DSM高程数据提取建筑物、树木和绿地

一、数据 数据来源:教程中的实验数据,共包含RGB三个波段,还有数字地表模型(以下简称DSM)文件。 图一 RGB影像 数据特征:数据范围较小,要素种类少,仅包含较多的建筑和大片的绿地。由于建筑的房顶使用的材料和材料颜色不同,所以建筑的光谱特征没有规律,是不连续的特征。而绿地的光谱特征则十分容易分辨。 但是建筑通常具有规则的形状,而且建筑相比于周围其他要素...

蒹葭苍苍 8302

仿京东Cart购物车

在这里购物车我以 fragment 和 expandableListView 的形式展示,小伙伴只需要在main.xml中添加一个fragment控件,记得加上“name属性”哦 fragment package com.qh.xuezhimin.sort3.fragment; import android.os.Bundle; import android.support.annotat...

mingxiangzhimin的博客 305

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

仿京东之购物车

1、使用二级列表 在原数据上添加Check属性  /** * 改变一级列表选中状态 * */ public void changeParentState(int parid,boolean flag){ data.get(parid).setChecked(flag); }/** * 改变二级列表选中状态 * */ public void changeChildState(int...

qq_40688026的博客 206

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

仿京东购物车布局

//购物车主布局    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    andr

cdGuoXianSheng的博客 613

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

上一篇: 仿京东分类 RecyclerView嵌套
下一篇: Fresco工具类
Melect
博客等级 码龄9年 10粉丝 46原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值