继承BottomSheetDialog实现选择规格的底部弹窗
先上效果图
img
实现思路
- 利用BottomSheetDialog底部弹出,且可方便实现背景透明的效果,
- 设置需要传入商品id进行查询,以及已经选中的规格下标
- 对可能进行的操作进行方法回调
- 使用了ButterKnife进行视图和方法绑定
- 使用了LoadSir进行视图替换
代码
ProductCategoryDialog.class
public class ProductCategoryDialog extends BottomSheetDialog {
@BindView(R.id.iv_close)
ImageView ivClose;
@BindView(R.id.riv_image)
RoundedImageView rivImage;
@BindView(R.id.tv_remainingAmount)
TextView tvRemainingAmount;
@BindView(R.id.tv_specification)
TextView tvSpecification;
@BindView(R.id.rv_type)
RecyclerView rvType;
@BindView(R.id.tv_buyNumTitle)
TextView tvBuyNumTitle;
@BindView(R.id.iv_reduce)
ImageView ivReduce;
@BindView(R.id.tv_buyNum)
TextView tvBuyNum;
@BindView(R.id.iv_add)
ImageView ivAdd;
@BindView(R.id.ll_num)
LinearLayout llNum;
@BindView(R.id.mb_addCar)
MaterialButton mbAddCar;
@BindView(R.id.content)
ConstraintLayout content;
@BindView(R.id.textView30)
TextView textView30;
@BindView(R.id.tv_product_name)
TextView tvProductName;
@BindView(R.id.tv_productPrice)
TextView tvProductPrice;
@BindView(R.id.textView32)
TextView textView32;
private Unbinder unbinder;
private ProductCategoryBean categoryBean;
private ProductCategoryAdapter categoryAdapter;
private GoodsModel model;
private OperateListener operateListener;
private int stock = 0;
private int buyNum = 1;
private int productId;
protected LoadService mLoadService;
private LifecycleTransformer lifecycleTransformer;
private Activity activity;
private int selectIndex;
public ProductCategoryDialog(@NonNull Activity context, LifecycleTransformer lifecycleTransformer, int productId,int selectIndex) {
super(context);
this.activity = context;
this.lifecycleTransformer = lifecycleTransformer;
this.productId = productId;
this.selectIndex = selectIndex;
model = new GoodsModel();
View view = View.inflate(context, R.layout.dialog_product_category, null);
setContentView(view);
unbinder = ButterKnife.bind(this, view);
//xml配置透明无效,要获取sheet控件,直接背景设置透明
findViewById(R.id.design_bottom_sheet).setBackgroundColor(Color.TRANSPARENT);
//contentView是自定义的显示在BottomSheetDialog上的view
view.post(() -> {
//R.id.design_bottom_sheet基本是固定的,不用担心后面API的更改
BottomSheetBehavior behavior = BottomSheetBehavior.from(findViewById(R.id.design_bottom_sheet));
//此处设置表示禁止BottomSheetBehavior的执行
behavior.setHideable(false);
});
this.setCanceledOnTouchOutside(true);
//setLoadSir(content);
getCategory(productId);
}
public MaterialButton getMbAddCar() {
return mbAddCar;
}
public void setMbAddCar(MaterialButton mbAddCar) {
this.mbAddCar = mbAddCar;
}
private void initView() {
if (rvType != null) {
initRecyclerView();
}
if (categoryBean.getGoodsSpecsList().size() != 0 && categoryAdapter != null) {
categoryAdapter.setList(categoryBean.getGoodsSpecsList());
categoryAdapter.setSelectPosition(selectIndex);
categoryAdapter.notifyDataSetChanged();
seData(categoryBean.getGoodsSpecsList().get(0));
}
}
private void initRecyclerView() {
LinearLayoutManager manager = new LinearLayoutManager(getContext());
manager.setOrientation(RecyclerView.HORIZONTAL);
rvType.setLayoutManager(manager);
rvType.setAdapter(categoryAdapter = new ProductCategoryAdapter(R.layout.classify_item_top_tab));
categoryAdapter.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
ProductSpecsBean specsBean = (ProductSpecsBean) adapter.getData().get(position);
categoryAdapter.setSelectPosition(position);
categoryAdapter.notifyDataSetChanged();
seData(specsBean);
operateListener.selected(position,specsBean.getId());
}
});
}
private void seData(ProductSpecsBean productSpecsBean) {
Glide.with(rivImage.getContext()).load(categoryBean.getGoodsDetails().getImage()).into(rivImage);
tvProductName.setText(categoryBean.getGoodsDetails().getTitle());
double price = productSpecsBean.getDiscountPrice();
String integer = String.valueOf((int) price);
int dec = (int) (price * 100) % 100;
String decimal = dec == 0 ? "00" : String.valueOf(dec);
SpanUtils.with(tvProductPrice)
.append("¥")
.setForegroundColor(Color.parseColor("#F86F57")).setFontSize(18, true)
.append(integer)
.setFontSize(30, true)
.append("." + decimal)
.setFontSize(18, true)
// .append("/" + "箱")
// .setForegroundColor(Color.parseColor("#999999")).setFontSize(14, true)
.create();
tvRemainingAmount.setText("剩余" + productSpecsBean.getAllStock());
stock = productSpecsBean.getAllStock();
// TODO: 2020/12/8 规格名
tvSpecification.setText(productSpecsBean.getUnit());
}
@OnClick({R.id.iv_close, R.id.mb_addCar, R.id.iv_reduce, R.id.iv_add})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.iv_close:
dismiss();
break;
case R.id.mb_addCar:
if (categoryBean.getGoodsSpecsList().size() != 0) {
operateListener.addCar(categoryAdapter.getSelectPosition(), categoryBean.getGoodsDetails().getId()
, categoryBean.getGoodsSpecsList().get(categoryAdapter.getSelectPosition()).getId()
, buyNum);
} else {
ToastUtils.showShort("没有商品类别");
}
dismiss();
break;
case R.id.iv_reduce:
if (buyNum <= 1) {
ToastUtils.showShort("不能再减了");
return;
} else {
buyNum--;
tvBuyNum.setText(buyNum + "");
}
break;
case R.id.iv_add:
if (buyNum >= stock) {
ToastUtils.showShort("没有更多库存");
return;
} else {
buyNum++;
tvBuyNum.setText(buyNum + "");
}
break;
}
}
private void getCategory(int id) {
setLoadSir(content);
HashMap hashMap = new HashMap();
hashMap.put("goodsId", id);
model.getGoodsSpecList(activity, hashMap, false, true, lifecycleTransformer, new ObserverResponseListener() {
@Override
public void onSuccess(Object o) {
BaseResponse<ProductCategoryBean> response = (BaseResponse<ProductCategoryBean>) o;
categoryBean = response.getData();
initView();
mLoadService.showSuccess();
}
@Override
public void onError(ExceptionHandle.ResponeThrowable e) {
mLoadService.showCallback(ErrorCallback.class);
}
});
}
/**
* 注册LoadSir
*
* @param view 替换视图
*/
public void setLoadSir(View view) {
if (mLoadService == null) {
mLoadService = LoadSir.getDefault().register(view, new Callback.OnReloadListener() {
@Override
public void onReload(View v) {
getCategory(productId);
}
});
} else {
mLoadService.showCallback(LoadingCallback.class);
}
}
@Override
public void dismiss() {
super.dismiss();
unbinder.unbind();
}
public interface OperateListener {
void addCar(int selectPosition, int productId, int specsId, int buyNum);
void selected(int selectPosition,int specsId);
}
public OperateListener getOperateListener() {
return operateListener;
}
public void setOperateListener(OperateListener operateListener) {
this.operateListener = operateListener;
}
}
dialog_product_category.xml
<?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-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:gravity="bottom"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="20dp">
<ImageView
android:id="@+id/iv_close"
android:layout_width="18dp"
android:layout_height="18dp"
android:background="@drawable/ic_1089"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView30"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="选择规格"
android:textColor="@color/black_33"
android:textSize="16sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.makeramen.roundedimageview.RoundedImageView
android:id="@+id/riv_image"
android:layout_width="80dp"
android:layout_height="70dp"
android:layout_marginTop="30dp"
android:scaleType="centerCrop"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView30" />
<TextView
android:id="@+id/tv_product_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:ellipsize="end"
android:maxWidth="150dp"
android:maxLines="2"
android:text="XXXXXX"
android:textColor="@color/black_33"
android:textSize="14sp"
android:textStyle="bold"
app:layout_constraintLeft_toRightOf="@id/riv_image"
app:layout_constraintTop_toTopOf="@id/riv_image" />
<TextView
android:id="@+id/tv_productPrice"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="¥00.00"
android:textColor="@color/red"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/tv_product_name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/tv_product_name"
app:layout_constraintTop_toTopOf="@+id/tv_product_name" />
<TextView
android:id="@+id/textView32"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:text="已选择:"
app:layout_constraintLeft_toLeftOf="@id/tv_productPrice"
app:layout_constraintStart_toStartOf="@+id/tv_product_name"
app:layout_constraintTop_toBottomOf="@+id/tv_product_name" />
<TextView
android:id="@+id/tv_specification"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="XXXXXXXXXXX"
app:layout_constraintBottom_toBottomOf="@+id/textView32"
app:layout_constraintStart_toEndOf="@+id/textView32"
app:layout_constraintTop_toTopOf="@+id/textView32" />
<TextView
android:id="@+id/tv_remainingAmount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="剩余0"
app:layout_constraintLeft_toLeftOf="@id/tv_productPrice"
app:layout_constraintStart_toStartOf="@+id/textView32"
app:layout_constraintTop_toBottomOf="@+id/textView32" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_type"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
app:layout_constraintTop_toBottomOf="@id/tv_remainingAmount" />
<TextView
android:id="@+id/tv_buyNumTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:text="数量"
android:textColor="@color/black"
android:textSize="14sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/rv_type" />
<LinearLayout
android:id="@+id/ll_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="@id/tv_buyNumTitle"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@id/tv_buyNumTitle">
<ImageView
android:id="@+id/iv_reduce"
android:layout_width="20dp"
android:layout_height="20dp"
android:background="@drawable/ic_1026" />
<TextView
android:id="@+id/tv_buyNum"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:text="1"
android:textColor="#333333"
android:textSize="15sp" />
<ImageView
android:id="@+id/iv_add"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginRight="5dp"
android:background="@drawable/ic_1027" />
</LinearLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/mb_addCar"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="25dp"
android:text="加入购物车"
android:textSize="15sp"
android:theme="@style/Theme.MaterialComponents.Light"
app:backgroundTint="@color/colorPrimary"
app:cornerRadius="20dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/ll_num"
app:rippleColor="@color/white" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
</LinearLayout>
ProductCategoryAdapter.class
public class ProductCategoryAdapter extends BaseQuickAdapter<ProductSpecsBean, BaseViewHolder> {
public int selectPosition=0;
public ProductCategoryAdapter(int layoutResId) {
super(layoutResId);
}
@Override
protected void convert(@NotNull BaseViewHolder baseViewHolder, @Nullable ProductSpecsBean goodsSpecsListBean) {
TextView tv_text=baseViewHolder.getView(R.id.tv_text);
tv_text.setText(goodsSpecsListBean.getUnit());
if(selectPosition==baseViewHolder.getLayoutPosition()){
tv_text.setTextColor(Color.WHITE);
tv_text.setBackgroundResource(R.drawable.shape_primary_radius15);
}else {
tv_text.setTextColor(Color.parseColor("#999999"));
tv_text.setBackgroundResource(R.drawable.shape_stroke_gray_radius20);
}
}
public int getSelectPosition() {
return selectPosition;
}
public void setSelectPosition(int selectPosition) {
this.selectPosition = selectPosition;
}
}
dialog_product_category.xml
就一个TextView,没啥好写
img