博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android:简单实现外卖购物车思路分享
阅读量:279 次
发布时间:2019-03-03

本文共 7387 字,大约阅读时间需要 24 分钟。

思路

要实现以下两个重要模块:

1.在中间大部分处展示所有食物的列表(需要一个RecyclerView)
2.需要一个购物车按钮,点击后从底部弹出购物车,显示选择的餐品列表,和总金额(需要一个实现从底部出现窗口的BottomSheetDiaLog和一个展示已选餐品列表的RecyclerView)

实现

1.所有食物列表

(1)select_food_layout.xml

注意点:

1.刚上手android的可以使用constraintlayout布局,很方便‘;
2.如果是新手一定要记得起id并且要起的详细精炼,因为后面同一个activity中可能要引入多个相似的部件,很可能搞混。

(2)food_item.xml

*注意点:

1.通过在顶层标签中设置背景颜色为透明(@null)和padding建个属性,可以实现列表Item之间有间隔.

(3)SelectFoodActivity.java中该列表的代码

a.首先声明它

private RecyclerView foodsListView;

b.创建对应的Adapter和ViewHolder

private class MyFoodsViewHolder extends RecyclerView.ViewHolder{
private TextView foodName; ... public MyFoodsViewHolder(final View itemView){
super(itemView); //获取行中显示各种数据的控件 foodName = itemView.findViewById(R.id.foodName); ... } } private class MyFoodsAdapter extends RecyclerView.Adapter
{
private List
items; public MyFoodsAdapter(List
items) {
this.items = items; } @NonNull @Override public MyFoodsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.food_item_view, parent, false); MyFoodsViewHolder viewHolder = new MyFoodsViewHolder(view); return viewHolder; } @Override public void onBindViewHolder(@NonNull final MyFoodsViewHolder holder, final int position) {
//获取要绑定数据的行的控件 Food food = items.get(position); holder.foodName.setText(food.getFood_name()); byte[] image = food.getFood_image(); Bitmap bitmap = BitmapFactory.decodeByteArray(image, 0, image.length); } @Override public int getItemCount() {
return items.size(); } }

注意点:

1.ViewHolder的onCreateViewHolder中引入item布局文件;
2.Adapter只负责生成一行的item,通过回调方法来重复生成item,每个item的数据不同是通过position参数来从集合中拿取对应的对象信息,再绑定到该Item上;
3.接收到由byte数组存储的图片后用bitmap来显示到前端。

c.声明并绑定RecyclerView

foodsListView = findViewById(R.id.foods);foodsListView.setLayoutManager(new LinearLayoutManager(getBaseContext()));foodsListView.setAdapter(new MyFoodsAdapter(foods));

2.点击购物车底部弹出购物车页面

(1)弹出界面需要使用到BottomSheetDialog:
a.声明:

private BottomSheetDialog bottomSheetDialog;

b.实现:其中check是购物车按钮(这里使用的是悬浮按钮)

bottomSheetDialog = new BottomSheetDialog(SelectFoodActivity.this);        View view = LayoutInflater.from(this).inflate(R.layout.layout_bottom_sheet, null);        bottomSheetDialog.setContentView(view);        bottomSheetDialog.setCancelable(true);        bottomSheetDialog.setCanceledOnTouchOutside(true);        check = findViewById(R.id.check);        check.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
bottomSheetDialog.show();//点击后显示该bottomSheetDialog } });

注意点:

1.很大的一个坑,不要用BottomSheetLayOut来代替BottomSheetDialog,会导致其中的列表无法显示(救命我搞了一天这个bug);
2.因为弹出的也是个页面,所以要新建个layout文件,布置这个页面,而已选择食物列表就在这个layout上面。

(2)已选择食物列表:

和全部食物列表的实现大同小异,不写了

3.点击食物Item的加减按钮同步更新金额和已选择食物列表

(1)点击加减更新已选食物列表和全部食物列表的数量:

//点击加号,食物数量++            holder.increase.setOnClickListener(new View.OnClickListener() {
@RequiresApi(api = Build.VERSION_CODES.Q) @Override public void onClick(View v) {
int count = Integer.parseInt(holder.foodCount.getText().toString()); holder.foodCount.setText(String.valueOf(count + 1)); Food food = foods.get(position); if(count == 0){
//该行食物数量为1 food.setCount(1); //增加一行已选择食物 selectedFoods.add(food); selectedFoodsListView.getAdapter().notifyDataSetChanged(); Log.e(THIS, "增加了:" + food.getFood_name()); print(selectedFoods); }else {
//不新增,覆盖该位置的原数量值 selectedFoods.remove(food); food.setCount(count + 1); selectedFoods.add(food); selectedFoodsListView.getAdapter().notifyItemChanged(position); Log.e(THIS, "增加了:" + food.getFood_name()); print(selectedFoods); } total = BigDecimal.valueOf(Double.parseDouble(total.toString())).add(food.getFood_price()); refresh(total); } });
//点击减号,食物数量--            holder.decrease.setOnClickListener(new View.OnClickListener() {
@RequiresApi(api = Build.VERSION_CODES.Q) @Override public void onClick(View v) {
int count = Integer.parseInt(holder.foodCount.getText().toString()); Food food = foods.get(position); //不让0有可乘之机,别把重复的抽出放外面! if(count == 1){
Log.e(THIS, "减少了:" + food.getFood_name()); selectedFoods.remove(food); selectedFoodsListView.getAdapter().notifyDataSetChanged(); food.setCount(count - 1); holder.foodCount.setText(String.valueOf(count - 1)); total = BigDecimal.valueOf(Double.parseDouble(total.toString())).subtract(food.getFood_price()); refresh(total); }else if(count > 1){
Log.e(THIS, "减少了:" + food.getFood_name()); selectedFoods.remove(food); food.setCount(count - 1); selectedFoods.add(food); selectedFoodsListView.getAdapter().notifyItemChanged(position); print(selectedFoods); holder.foodCount.setText(String.valueOf(count - 1)); total = BigDecimal.valueOf(Double.parseDouble(total.toString())).subtract(food.getFood_price()); refresh(total); } } });

(2)点击加减同步总金额:通知已选餐品列表的时候通知该列表即可,但是总金额怎么整呢?实时setText?事实证明就算你set了页面是不刷新的等于白set,所以用Handler实现,在onCreate中声明实现该handler:

refreshHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
if (msg.what == 0) {
totalPrice.setText(String.valueOf(total)); //View.ininvalidate() sendEmptyMessageDelayed(0, 1000); } } };

在每次需要更新总金额的时候调用:

refreshHandler.sendEmptyMessageDelayed(0, 1000);

常遇到的BUG

1.试图将值放到一个空部件上:大部分是获取该部件的时候没获取对,要么id没写对,要么view.findViewById的view不是存在这个部件的view。

2.使用了通知RecylcerView更新的方法但是不更新:首先检测数据集是否更新,没问题了再检查其他原因。大部分是因为你把对象列表的引用指向了别处,原本和列表绑定的内存块在角落看着你不敢说话,例如list = newData;不可以这样,需要removeAll(list),addAll(newData)。再不然可能是特殊情况,比如我遇到的bottomSheetLayout遇到RecyclerView打架问题。

建议

如果你和我一样是初学者的话,最好自己多看博客和书自己改编实现各种功能,粘代码的话永远学不到自己肚子里,过程虽然痛苦但是结果开心呀,一步一步来,一点点改bug,慢慢滴用的多了就懂了,页面就不放了,是毕设内容~

转载地址:http://pwcl.baihongyu.com/

你可能感兴趣的文章