京东购物车

xiaoxiao2025-10-15  5

最下面是0级列表

商家 -- 1级

商品  -- 2级

 

需要注意的三个点: 0 -- 选中/未选中1 -- 选中/未选中2 -- 选中/未选中

 

CheckBox会发生 复用问题

给它设置点击事件,每次都要对每个位置的box状态进行记录

 

圆角矩形、扁平化设计风格

 

F9:0A:2A:29:99:84:EB:F3:E9:7D:CC:9D:E1:AE:06:68:58:CC:52:06

 

购物车ShopperAdapter() /** * ShopperAdapter * 商家适配器 */ public class ShopperAdapter extends RecyclerView.Adapter<ShopperAdapter.ViewHolder> { private Context context; private List<Shopper<List<Product>>> list; public ShopperAdapter(Context context, List<Shopper<List<Product>>> list) { this.context = context; this.list = list; } // 一级列表(商家)发生变化的接口 public interface OnShopperClickListener { void onShopperClick(int position, boolean isCheck); } private OnShopperClickListener shopperClickListener; public void setOnShopperClickListener(OnShopperClickListener listener) { this.shopperClickListener = listener; } // 二级列表的加减器监听 private ProductAdapter.OnAddDecreaseProductListener productListener; public void setOnAddDecreaseProductListener(ProductAdapter.OnAddDecreaseProductListener listener) { this.productListener = listener; } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View v = View.inflate(context, R.layout.item_shopper, null); ViewHolder holder = new ViewHolder(v); return holder; } @Override public void onBindViewHolder(@NonNull final ViewHolder holder, final int position) { final Shopper<List<Product>> shopper = list.get(position); holder.txtShopperName.setText(shopper.getSellerName()); // 产品的列表 RecyclerView.LayoutManager pLayoutManager = new LinearLayoutManager(context); holder.rvProduct.setLayoutManager(pLayoutManager); final ProductAdapter adapter = new ProductAdapter(context, shopper.getList()); // 给二级列表添加一个加减器的监听 if (productListener != null) { adapter.setOnAddDecreaseProductListener(productListener); } // 二级条目(商品)复选框点击事件 adapter.setOnProductClickListener(new ProductAdapter.OnProductClickListener() { @Override public void onProductClick(int position, boolean isChecked) { // 当前商品未选中,商家也就未选中 if (!isChecked) { shopper.setChecked(false); // 只要是当前条目未选中,全选复选框也就没选中 shopperClickListener.onShopperClick(position, false); } else { // 当前商品如果选中,需要遍历商家所有的商品是否选中 // 循环遍历之前先设置一个true标志位,只要有一条商品没有被选中,商家也就选中,标志位变成false boolean isAllProductSelected = true; for (Product product : shopper.getList()) { if (!product.isChecked()) { isAllProductSelected = false; break; } } shopper.setChecked(isAllProductSelected); // 当前商品选中时,需要循环遍历所有的商家是否被选中来确认外部全选复选框的状态 shopperClickListener.onShopperClick(position, true); } // 数据发生变化之后刷新适配器 notifyDataSetChanged(); productListener.onChange(0, 0); } }); holder.rvProduct.setAdapter(adapter); // 先取消掉之前的点击变化监听 holder.cbSHopper.setOnCheckedChangeListener(null); // 设置好初始化的状态 holder.cbSHopper.setChecked(shopper.isChecked()); // 等设置完初始化状态之后再设置我们自己的监听 // 商家列表中的复选框 holder.cbSHopper.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { shopper.setChecked(isChecked); // 1.商家被选中的时候,子类所有的商品应该被选中 // if (isChecked) { List<Product> productList = shopper.getList(); for (Product product : productList) { product.setChecked(isChecked); } // 子类商品的适配器刷新 adapter.notifyDataSetChanged(); // } // 当点击一级条目的时候,外部的全选按钮状态发生变化 if (shopperClickListener != null) { shopperClickListener.onShopperClick(position, isChecked); } } }); } @Override public int getItemCount() { return list.size(); } class ViewHolder extends RecyclerView.ViewHolder { private CheckBox cbSHopper; private TextView txtShopperName; private RecyclerView rvProduct; public ViewHolder(View itemView) { super(itemView); cbSHopper = itemView.findViewById(R.id.cb_shopper); txtShopperName = itemView.findViewById(R.id.txt_shopper_name); rvProduct = itemView.findViewById(R.id.rv_product); } } } 商品ShopperAdapter /** * ProductAdapter 商品适配器 */ public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ViewHolder> { private Context context; private List<Product> list; // 二级条目(商品)点击监听 public interface OnProductClickListener { void onProductClick(int position, boolean isChecked); } private OnProductClickListener productClickListener; public void setOnProductClickListener(OnProductClickListener listener) { this.productClickListener = listener; } // 加减器发生变化的监听 public interface OnAddDecreaseProductListener { void onChange(int position, int num); } private OnAddDecreaseProductListener productListener; public void setOnAddDecreaseProductListener(OnAddDecreaseProductListener listener) { this.productListener = listener; } public ProductAdapter(Context context, List<Product> list) { this.context = context; this.list = list; } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View v = View.inflate(context, R.layout.item_product, null); ViewHolder holder = new ViewHolder(v); return holder; } @Override public void onBindViewHolder(@NonNull ViewHolder holder, final int position) { final Product product = list.get(position); String images = product.getImages(); // 商品图片 if (!TextUtils.isEmpty(images)) { String[] strings = images.split("\\|"); if (strings.length > 0) { Glide.with(context) .load(StringUtils.https2Http(strings[0])) .into(holder.imgProduct); } } holder.txtProductName.setText(product.getTitle()); holder.txtSinglePriice.setText(String.valueOf(product.getPrice())); holder.advProduct.setNum(product.getNum()); // 加减器添加点击事件 holder.advProduct.setOnAddDecreaseClickListener(new AddDecreaseView.OnAddDecreaseClickListener() { @Override public void add(int num) { product.setNum(num); if (productListener != null) { productListener.onChange(position, num); } } @Override public void decrease(int num) { product.setNum(num); if (productListener != null) { productListener.onChange(position, num); } } }); // 商品的复选框 holder.cbProduct.setOnCheckedChangeListener(null); holder.cbProduct.setChecked(product.isChecked()); holder.cbProduct.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { product.setChecked(isChecked); if (productClickListener != null) { productClickListener.onProductClick(position, isChecked); } } }); } @Override public int getItemCount() { return list.size(); } class ViewHolder extends RecyclerView.ViewHolder { private CheckBox cbProduct; private ImageView imgProduct; private TextView txtProductName; private TextView txtSinglePriice; private AddDecreaseView advProduct; public ViewHolder(View itemView) { super(itemView); cbProduct = itemView.findViewById(R.id.cb_product); imgProduct = itemView.findViewById(R.id.img_product); txtSinglePriice = itemView.findViewById(R.id.txt_single_price); advProduct = itemView.findViewById(R.id.adv_product); txtProductName = itemView.findViewById(R.id.txt_product_name); } } } 自定义加减器 ​​​​​​​ /** * AddDecreaseView,自定义加减器 */ public class AddDecreaseView extends RelativeLayout implements View.OnClickListener { private TextView txtAdd; private TextView txtDecrease; private TextView txtNum; private int num; public interface OnAddDecreaseClickListener { void add(int num); void decrease(int num); } private OnAddDecreaseClickListener listener; public void setOnAddDecreaseClickListener(OnAddDecreaseClickListener listener) { this.listener = listener; } public AddDecreaseView(Context context) { this(context, null); } public AddDecreaseView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public AddDecreaseView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } private void init(Context context) { View.inflate(context, R.layout.item_add_decrease, this); txtAdd = findViewById(R.id.txt_add); txtDecrease = findViewById(R.id.txt_decrease); txtNum = findViewById(R.id.txt_num); txtNum.setText("1"); txtAdd.setOnClickListener(this); txtDecrease.setOnClickListener(this); } public void setNum(int num) { this.num = num; txtNum.setText(num + ""); } public int getNum() { return num; } @Override public void onClick(View v) { switch (v.getId()) { case R.id.txt_add: num++; txtNum.setText(num + ""); if (listener != null) { listener.add(num); } break; case R.id.txt_decrease: if (num > 1) { num--; } txtNum.setText(num + ""); if (listener != null) { listener.decrease(num); } break; } } }

MainActvity页面: 

public class MainActivity extends AppCompatActivity implements IView { private static final String TAG = "MainActivity"; // MessageBean<List<ShopperAdapter<List<Product>>>> private TextView txtEditFinish; private CheckBox cbTotal; private TextView txtPrice; private Button btnCalu; private RecyclerView rvShoper; private CartPresenter presenter; private ShopperAdapter adapter; private List<Shopper<List<Product>>> list; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); initData(); setListener(); } private void setListener() { cbTotal.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { boolean isChecked = cbTotal.isChecked(); // 遍历一级列表,和下方的全选状态一致 for (Shopper<List<Product>> listShopper : list) { listShopper.setChecked(isChecked); // 遍历二级列表,和下方的全选状态一致 List<Product> products = listShopper.getList(); for (Product product : products) { product.setChecked(isChecked); } } calculatePrice(); adapter.notifyDataSetChanged(); } }); } private void initData() { list = new ArrayList<>(); // 商家的列表 adapter = new ShopperAdapter(this, list); // 添加一级条目(商家)状态发生变化时 adapter.setOnShopperClickListener(new ShopperAdapter.OnShopperClickListener() { @Override public void onShopperClick(int position, boolean isCheck) { // 为了效率考虑,当点击状态变成未选中时,全选按钮肯定就不是全选了,就不用再循环一次 if (!isCheck) { cbTotal.setChecked(false); } else { // 如果是商家变成选中状态时,需要循环遍历所有的商家是否被选中 // 循环遍历之前先设置一个true标志位,只要有一个是未选中就改变这个标志位为false boolean isAllShopperChecked = true; for (Shopper<List<Product>> listShopper : list) { // 只要有一个商家没有被选中,全选复选框就变成未选中状态,并且结束循环 if (!listShopper.isChecked()) { isAllShopperChecked = false; break; } } cbTotal.setChecked(isAllShopperChecked); } // 一级条目发生变化时,计算一下总价 calculatePrice(); } }); adapter.setOnAddDecreaseProductListener(new ProductAdapter.OnAddDecreaseProductListener() { @Override public void onChange(int position, int num) { calculatePrice(); } }); RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this); rvShoper.setLayoutManager(layoutManager); rvShoper.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL)); rvShoper.setAdapter(adapter); presenter = new CartPresenter(); presenter.attach(this); presenter.getData(); } // 计算商品总价 private void calculatePrice() { // 遍历商家 float totalPrice = 0; for (Shopper<List<Product>> listShopper : list) { // 遍历商家的商品 List<Product> list = listShopper.getList(); for (Product product : list) { // 如果商品被选中 if (product.isChecked()) { totalPrice += product.getNum() * product.getPrice(); } } } txtPrice.setText("总价:" + totalPrice); } private void initView() { txtEditFinish = findViewById(R.id.txt_edit_or_finish); cbTotal = findViewById(R.id.cb_total_select); txtPrice = findViewById(R.id.txt_total_price); btnCalu = findViewById(R.id.btn_calu); rvShoper = findViewById(R.id.rv_shopper); } @Override public void success(MessageBean<List<Shopper<List<Product>>>> data) { if (data != null) { // 获取商家列表 List<Shopper<List<Product>>> shoppers = data.getData(); if (shoppers != null) { list.clear(); list.addAll(shoppers); adapter.notifyDataSetChanged(); } } } @Override public void failed(Exception e) { Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show(); } @Override protected void onDestroy() { super.onDestroy(); if (presenter != null) { presenter.detach(); } } }

 

转载请注明原文地址: https://www.6miu.com/read-5037960.html

最新回复(0)