Android商城开发----点击加入购物车,购物车商品的增删减

上一章节:【分类页面】点击左侧类别,实现右侧对应类别商品的展示
本文是在上一章节基础上开发的,点击【分类】页面商品的加入购物车按钮,实现将商品加入购物车的功能。

目录

  • Android商城开发----点击加入购物车,购物车商品的增删减
    • 本文主要实现的功能是:
    • 用到的主要知识点:
    • 点击将商品加入购物车的业务流程
    • 源码
      • 1.数据库
        • 1)商品列表数据库GoodsListDatabase.java
        • 2)购物车数据库ShoppingCarDatabase.java
      • 2.封装类
        • 1)Goods.java 类:商品类,用于封装对商品的操作
        • 2)Car.java类,购物车类
        • 3)MyApplication.java 创建全局context
      • 3.分类和购物车
        • 1)CategoryRightAdapter.java
        • 2)购物车页面
        • ShoppingCarFragment.java
        • ShoppingCarAdapter.java
      • 3.购物车布局页面
        • fragment_shoppingcar.xml
        • 购物车RecyclerView的 list ShoppingCar_list.xml

本文主要实现的功能是:

1.点击加入购物车按钮,将商品加入购物车。
2.点击相同的商品加入购物车,修改购物车中该商品数量 +1。
3.点击购物车页面 商品数量调节按钮【+1】按钮,商品数量 +1。
4.点击购物车页面中商品数量调节按钮【-1】按钮,商品数量 -1。
5.长摁删除购物车中该商品。

用到的主要知识点:

1.布局: RecyclerView的使用、对应Adapter的配置
2.数据库的创建: 我用的是SQLite,以及数据库操作:增、删、减、查
这里创建两个数据库:
一是 商品列表数据库(用来存放商品信息:商品Id、Icon、标题、价格)方便加入购物车时,按照Id去查找商品信息;
二是 购物车数据库(保存商品Id以及商品数量),方便对购物车商品进行操作增删减同时退出Activity后再回来商品数量仍然是上次退出时的显示,不会清零。
3.OKHttp网络请求
4.Json数据解析
5.封装类:(把对一类的操作封装进一个类里,方便复用,实现面向对象的操作)
两个类:商品类【 定义字段:商品Id 商品Icon 商品名称 商品价格;定义方法:增 查】和购物车类【定义字段:carId没用到 可以不定义,商品Id 商品数量;定义方法:增 改(加1.减1) 删 查】
6.接口: RecyclerView中Item点击、长摁、Item内部按钮的接口定义与调用,在接口里定义是为了区分出点的是哪个position的按钮。

点击将商品加入购物车的业务流程

源码

1.数据库
1)商品列表数据库GoodsListDatabase.java
package com.domain.mainView.database;
/*
* 商品列表数据库,将网络请求返回来的数据放进来
* */
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.nfc.Tag;
import android.util.Log;
import androidx.annotation.Nullable;public class GoodsListDatabase extends SQLiteOpenHelper {private static final String TAG=GoodsListDatabase.class.getSimpleName();//定义创建数据表dict的SQL语句//创建表时,定义的单个列的约束public static final String CREATE_GOODS_SQL="create table goods(dbId integer ,dbIcon integer," +"dbTitle text," +"dbPrice text,UNIQUE(dbId))";//private Context mContext;//构造函数public GoodsListDatabase(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {super(context, name, factory, version);}@Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL(CREATE_GOODS_SQL);Log.i(TAG, "onCreate: 商品列表数据库创建成功");}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {db.execSQL("drop table if exists goods");onCreate(db);}
}
2)购物车数据库ShoppingCarDatabase.java
package com.domain.mainView.database;import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import androidx.annotation.Nullable;
import java.io.DataOutputStream;
/** 购物车数据库,点击加入购物车图片按钮将该商品id加入购物车* */
public class ShoppingCarDatabase extends SQLiteOpenHelper {private static final String TAG=ShoppingCarDatabase.class.getSimpleName();//定义创建数据表dict的SQL语句final String CREATE_GOODS_SQL="create table shoppingCar(carId Integer primary key autoincrement,dbId Integer,dbNum Integer)";//构造函数public ShoppingCarDatabase(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {super(context, name, factory, version);}@Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL(CREATE_GOODS_SQL);Log.i(TAG, "onCreate: 购物车数据库创建成功啦!");}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {//更新数据库db.execSQL("drop table if exists shoppingCar");onCreate(db);}
}
2.封装类
1)Goods.java 类:商品类,用于封装对商品的操作

/*商品类

  • 字段:商品Id 商品Icon 商品名称 商品价格
  • 方法:增 查
  • 通过网络请求获取商品信息 插入商品列表数据库
  • 包含 对商品列表 加入商品方法和读取商品方法*/
package com.domain.mainView.mClass;import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import com.domain.mainView.MyApplication;
import com.domain.mainView.database.GoodsListDatabase;
/*商品类
* 字段:商品Id 商品Icon 商品名称 商品价格
* 方法:增 查
* 通过网络请求获取商品信息 插入商品列表数据库
* 包含 对商品列表 加入商品方法和读取商品方法*/public class Goods {private int goodsId;private int goodsIcon;private String goodsTitle;private String goodsPrice;private static final String TAG = GoodsListDatabase.class.getSimpleName();public Goods() {}public Goods(int goodsId, int goodsIcon, String goodsTitle, String goodsPrice) {this.goodsId = goodsId;this.goodsIcon = goodsIcon;this.goodsTitle = goodsTitle;this.goodsPrice = goodsPrice;}public int getGoodsId() {return goodsId;}public int getGoodsIcon() {return goodsIcon;}public String getGoodsTitle() {return goodsTitle;}public String getGoodsPrice() {return goodsPrice;}
//插入商品 增public void addGoods(int id, int icon, String title, String price) {GoodsListDatabase goodsListDatabase = new GoodsListDatabase(MyApplication.getContext(), "goods.db", null, 2);SQLiteDatabase db = goodsListDatabase.getReadableDatabase();ContentValues values = new ContentValues();values.put("dbId", id);values.put("dbIcon", icon);values.put("dbTitle", title);values.put("dbPrice", price);//数据库构建中UNIQUE(dbId)与insert ignore into配合解决重复插入数据库的问题  String sql = "insert or ignore into goods(dbId,dbIcon,dbTitle,dbPrice)values('" + id + "','" + icon + "','" + title + "','" + price + "')";db.execSQL(sql);Log.i(TAG, "addGoods: 商品插入商品列表数据库成功拉!");}@SuppressLint("Range")//查找商品 查public Goods findGoods(int goodId) {GoodsListDatabase goodsListDatabase = new GoodsListDatabase(MyApplication.getContext(), "goods.db", null, 2);SQLiteDatabase db = goodsListDatabase.getWritableDatabase();String idNew = String.valueOf(goodId);int id = 0;int icon = 0;String title = "";String price = "";Cursor cursor = db.query("goods", null, "dbId= ?", new String[]{idNew}, null, null, null);if (cursor.moveToFirst()) {do {id = cursor.getInt(cursor.getColumnIndex("dbId"));icon = cursor.getInt(cursor.getColumnIndex("dbIcon"));title = cursor.getString(cursor.getColumnIndex("dbTitle"));price = cursor.getString(cursor.getColumnIndex("dbPrice"));} while (cursor.moveToNext());}Goods goods1 = new Goods(id, icon, title, price);Log.i(TAG, "findGoods: goods1" + goods1);Log.i(TAG, "findGoods: 读取购物车商品成功拉");cursor.close();return goods1;}
}
2)Car.java类,购物车类
package com.domain.mainView.mClass;import static android.service.controls.ControlsProviderService.TAG;
import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;import com.domain.mainView.MyApplication;
import com.domain.mainView.database.ShoppingCarDatabase;
/*
* 购物车类
* 字段:carId没用到 可以不定义,商品Id 商品数量
* 方法:增 改(加1.减1) 删 查
*/public class Car {private int carId;private int goodsId;private int goodsNum;public Car() {//无参构造函数}public Car(int carId, int goodsId, int goodsNum) {//有参构造函数this.carId = carId;this.goodsId = goodsId;this.goodsNum = goodsNum;}public int getCarId() {return carId;}public int getGoodsId() {return goodsId;}public int getGoodsNum() {return goodsNum;}//加入购物车public void addCar(int goodsId) {//创建数据库ShoppingCarDatabase shoppingCarDatabase = new ShoppingCarDatabase(MyApplication.getContext(), "shoppingCar.db", null, 3);SQLiteDatabase db = shoppingCarDatabase.getReadableDatabase();//查询数据库是否已存在该商品Cursor cursor = db.rawQuery("select * from shoppingCar where dbId=? ", new String[]{String.valueOf(goodsId)});while (cursor.moveToNext()) {Log.i(TAG, "isDbIdExist1: 数据已存在");//已存在,更改数量加1,调用下面的addOne方法addOne(goodsId);db.close();return;}//不存在,执行插入,将该goodsId插入数据库,数量是1Log.i(TAG, "isDbIdExist1: 数据不存在");String sql = "insert into shoppingCar(dbId,dbNum)values('" + goodsId + "',1 )";db.execSQL(sql);db.close();Log.i(TAG, "addCar: 加入新商品成功!!!");}//获得购物车中该商品数量 查询操作@SuppressLint("Range")public int getGoodsCarNum(int goodsId) {ShoppingCarDatabase shoppingCarDatabase = new ShoppingCarDatabase(MyApplication.getContext(), "shoppingCar.db", null, 3);SQLiteDatabase db = shoppingCarDatabase.getReadableDatabase();//初始化数量为1int goodsCarNum = 1;Cursor cursor = db.rawQuery("select * from shoppingCar where dbId = ?", new String[]{String.valueOf(goodsId)});if (cursor.moveToFirst()) {do {//遍历cursor对象,取出数据goodsCarNum = cursor.getInt(cursor.getColumnIndex("dbNum"));Log.i(TAG, "dbNum" + goodsCarNum);} while (cursor.moveToNext());cursor.close();Log.i(TAG, "readShoppingCarDatabase: 读取购物车数据库ID成功拉!");}return goodsCarNum;}//商品数量加一 增 public int addOne(int goodsId) {ShoppingCarDatabase shoppingCarDatabase = new ShoppingCarDatabase(MyApplication.getContext(), "shoppingCar.db", null, 3);SQLiteDatabase db = shoppingCarDatabase.getReadableDatabase();ContentValues values = new ContentValues();goodsNum = getGoodsCarNum(goodsId) + 1;values.put("dbNum", goodsNum);db.update("shoppingCar", values, "dbId=?", new String[]{String.valueOf(goodsId)});Log.i(TAG, goodsId + "addCar: 数量加1" + goodsNum);db.close();return goodsNum;}//商品数量减一 减public int reduceOne(int goodsId) {ShoppingCarDatabase shoppingCarDatabase = new ShoppingCarDatabase(MyApplication.getContext(), "shoppingCar.db", null, 3);SQLiteDatabase db = shoppingCarDatabase.getReadableDatabase();ContentValues values = new ContentValues();goodsNum = getGoodsCarNum(goodsId) - 1;values.put("dbNum", goodsNum);db.update("shoppingCar", values, "dbId=?", new String[]{String.valueOf(goodsId)});Log.i(TAG, goodsId + "addCar: 数量-1" + goodsNum);db.close();return goodsNum;}//删除商品public void deleteCar(int goodsId) {ShoppingCarDatabase shoppingCarDatabase = new ShoppingCarDatabase(MyApplication.getContext(), "shoppingCar.db", null, 3);SQLiteDatabase db = shoppingCarDatabase.getReadableDatabase();db.delete("shoppingCar", "dbId=?", new String[]{String.valueOf(goodsId)});}
}
3)MyApplication.java 创建全局context

全局获取Context,查看《第一行Android代码》P457-P460
可以在Activity和Fragment之外的文件调用Context

package com.domain.mainView;import android.app.Application;
import android.content.Context;public class MyApplication extends Application {private static Context context;@Overridepublic void onCreate() {super.onCreate();context = getApplicationContext();}public static Context getContext(){return context;}
}

需要在AndroidManifest.xml指定:

<applicationandroid:name="com.example.networktest.MyApplication"...>
</application>
3.分类和购物车
1)CategoryRightAdapter.java

分类页面右侧的adapter,在里面定义点击事件;主要是识别点击了哪个商品,将对应商品的商品Id加入购物车数据库。

//定义单击事件和长摁事件接口public interface OnItemClickListener {void ItemClickListener(View view, int position);//定义购物车图片按钮,在接口中定义是为了区分点的是哪个商品的按钮void ImageButtonClickListener(View view, int position);}public void setOnClickListener(OnItemClickListener listener) {this.mOnItemClickListener = listener;}//在onBindViewHolder中定义【加入购物车】按钮的单击事件
//设置imagebutton的监听事件
//img_shoppingCar为实例化的图片按钮控件holder.img_shoppingCar.setOnClickListener(new ImageButton.OnClickListener() {@Overridepublic void onClick(View v) {int pos = holder.getLayoutPosition();mOnItemClickListener.ImageButtonClickListener(holder.itemView, pos);//点击识别当前商品idint currentId = listId.get(position);Log.i(TAG, "currentId" + currentId);car.addCar(currentId);Log.i(TAG, "新商品加入购物车成功!");// }}});

位置如图:

2)购物车页面
ShoppingCarFragment.java

1.我是在购物车页面才创建了商品列表的数据库,通过http网络请求,获取商品列表信息,然后进行JSON数据解析,并将数据insert到商品列表的数据库里。(其实这一步应该在分类列表写,在分类里面获取数据并推进分类页面里,我的分类页面是写死的)。
2.读取购物车里的数据,然后根据购物车中的商品Id去商品数据库里匹配商品信息,将其加入购物车的adapter,进行购物车商品的展示。
3.长摁删除商品。

package com.domain.mainView.ui.shoppingcar;import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Looper;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;import com.domain.mainView.mClass.Car;
import com.domain.mainView.mClass.Goods;
import com.domain.mainView.GoodsDetails;
import com.domain.mainView.MyApplication;
import com.domain.mainView.R;
import com.domain.mainView.ShoppingCarAdapter;
import com.domain.mainView.database.GoodsListDatabase;
import com.domain.mainView.database.ShoppingCarDatabase;
import com.domain.mainView.databinding.FragmentShoppingcarBinding;
import com.domain.mainView.okhttp.HttpUtil;import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;import java.io.IOException;
import java.util.ArrayList;
import java.util.List;import okhttp3.Call;
import okhttp3.Response;public class ShoppingCarFragment extends Fragment {private static final String TAG = ShoppingCarFragment.class.getSimpleName();private FragmentShoppingcarBinding binding;private GoodsListDatabase goodsListDatabase;private ShoppingCarAdapter shoppingCarAdapter;private RecyclerView shopRecyclerView;private ShoppingCarDatabase shoppingCarDatabase;private List<Goods> shoppingCar = new ArrayList<>();View root;@Overridepublic void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);try {//发送Http请求sendRequestOkHttp();} catch (JSONException e) {e.printStackTrace();}}//读取购物车数据库的数据(加入的商品id)private void readShoppingCarDatabase() {//创建购物车数据库shoppingCarDatabase = new ShoppingCarDatabase(getActivity(), "shoppingCar.db", null, 3);Cursor cursor = shoppingCarDatabase.getReadableDatabase().query("shoppingCar", null, null, null, null, null, null);if (cursor.moveToFirst()) {do {//遍历cursor对象,取出数据@SuppressLint("Range")int dbId = cursor.getInt(cursor.getColumnIndex("dbId"));Log.i(TAG, "dbId" + dbId);Goods goods = new Goods();shoppingCar.add(goods.findGoods(dbId));} while (cursor.moveToNext());cursor.close();Log.i(TAG, "readShoppingCarDatabase: 读取购物车数据库ID成功拉!");}}//加载布局,当fragment绘制界面组件时回调该方法public View onCreateView(@NonNull LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {binding = FragmentShoppingcarBinding.inflate(inflater, container, false);root = binding.getRoot();initView();readShoppingCarDatabase();//设置适配器upShoppingCarAdapter();return root;}//创建更新adapter方法private void upShoppingCarAdapter() {shoppingCarAdapter = new ShoppingCarAdapter(shoppingCar);shopRecyclerView.setAdapter(shoppingCarAdapter);shoppingCarAdapter.setOnClickListener(new ShoppingCarAdapter.OnItemClickListener() {@Overridepublic void ItemClickListener(View view, int position) {Intent intent = new Intent(getActivity(), GoodsDetails.class);startActivity(intent);}//长摁事件@Overridepublic void ItemLongClickListener(View view, int position) {//没实现AlertDialog alertDialog = new AlertDialog.Builder(getActivity()).create();alertDialog.setTitle("提示");alertDialog.setMessage("确定要删除该商品吗?");//取消按钮alertDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "否",new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {alertDialog.cancel();Log.i(TAG, "ItemLongClickListener: 点击了否");}});//确定按钮alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "是",new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {Car car = new Car();Goods goods = shoppingCar.get(position);car.deleteCar(goods.getGoodsId());readShoppingCarDatabase();initView();upShoppingCarAdapter();Log.i(TAG, "ItemLongClickListener: 点击了是");}});alertDialog.show();Log.i(TAG, "ItemLongClickListener: 长摁删除");}//图片按钮点击事件@Overridepublic void ImageButtonClickListener(View view, int position) {}});}//定义初始化private void initView() {shopRecyclerView = root.findViewById(R.id.shoppingCar);LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());shopRecyclerView.setLayoutManager(layoutManager);}//进行网络请求private void sendRequestOkHttp() throws JSONException {//构建post参数json格式JSONObject json = new JSONObject();json.put("category", "");//url 我把商品列表写在接口里面,通过http请求获取商品信息String url = "http://rap2api.taobao.org/app/mock/307955/example/goodsList";//这个url你们自己定义吧,里面包含商品Icon名字/商品Id/商品标题/商品价格//实例化类//类.方法 调用封装好的okhttpHttpUtil.sendOkHttpRequest(url, json.toString(), new okhttp3.Callback() {//异常处理@Overridepublic void onFailure(@NonNull Call call, @NonNull IOException e) {e.printStackTrace();//打印异常httpError();                 //对异常情况处理}@Overridepublic void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {String responseData = response.body().string();//解析json文件parseJson(responseData);}});}//对异常进行处理private void httpError() {//此处进行UI操作 异常弹窗//Looper用来做子线程弹窗。网络请求是开辟子线程Looper.prepare();Toast.makeText(getActivity(), "网络请求发生异常", Toast.LENGTH_SHORT).show();Looper.loop();}//处理请求回来的数据 解析json数据private void parseJson(final String jsonData) {//解析对象JSONObject jsonObject;try {jsonObject = new JSONObject(jsonData);String resultCode = jsonObject.optString("resultCode");Log.i(TAG, "resultCode" + resultCode);String message = jsonObject.optString("message");Log.i(TAG, "message" + message);//当返回码为0时,再进行后面的操作if (resultCode.equals("0")) {Log.i(TAG, "商品信息请求成功");//继续解析里面内容dataJSONArray jsonArray = jsonObject.getJSONArray("data");for (int i = 0; i < jsonArray.length(); i++) {// JSON数组里面的具体-JSON对象JSONObject goodsObject = jsonArray.getJSONObject(i);int goodsId = goodsObject.optInt("goodsId");int goodsIcon = goodsObject.optInt("goodsIcon");String goodsTitle = goodsObject.optString("goodsTitle");String goodsPrice = goodsObject.optString("goodsPrice");//把解析的数据赋给变量,插入数据库int id = goodsId;int icon = goodsIcon;String title = goodsTitle;String price = goodsPrice;//实例化Goods类,调用Goods的addGoods方法,将数据插入数据库Goods goods = new Goods();goods.addGoods(id, icon, title, price);}}} catch (JSONException e) {e.printStackTrace();}}//onResume方法是Activity第一次创建时 重新加载实例时调用 例如 我打开App第一个界面OnCreate完 就调用onResume 然后切换到下一个界面 第一个界面不finish 按Back键回来时 就调onResume//不调onCreate, 还有就是 App用到一半 有事Home键切出去了 在回来时调onResume@Overridepublic void onResume() {super.onResume();upShoppingCarAdapter();}@Overridepublic void onDestroyView() {super.onDestroyView();binding = null;}@Overridepublic void onDestroy() {super.onDestroy();}
}
ShoppingCarAdapter.java

这里主要定义了购物车页面加1减1按钮的单击事件(Bug是我没有判断数量是否小于0,你们可以自行判断一下)

package com.domain.mainView;import android.annotation.SuppressLint;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.domain.mainView.database.ShoppingCarDatabase;
import com.domain.mainView.mClass.Car;
import com.domain.mainView.mClass.Goods;
import java.util.ArrayList;
import java.util.List;public class ShoppingCarAdapter extends RecyclerView.Adapter<ShoppingCarAdapter.ViewHolder> {private OnItemClickListener sOnItemClickListener;ShoppingCarDatabase shoppingCarDatabase;private static final String TAG = ShoppingCarAdapter.class.getSimpleName();private List<Goods> mGoodsList;@NonNull@Override//页面创建的时候public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {//绑定布局文件 这里的MyApplication.getContext()就是调用的全局ContextView view = LayoutInflater.from(MyApplication.getContext()).inflate(R.layout.shoppingcar_list, parent, false);ViewHolder holder = new ViewHolder(view);return holder;}@Override//滑动到子项的时候public void onBindViewHolder(@NonNull ViewHolder holder, @SuppressLint("RecyclerView") int position) {shoppingCarDatabase = new ShoppingCarDatabase(MyApplication.getContext(), "shoppingCar.db", null, 3);//为控件绑定内容Goods goods = mGoodsList.get(position);String intIcon = "icon" + goods.getGoodsIcon();int goodsIcon = MyApplication.getContext().getResources().getIdentifier(intIcon, "drawable", "com.domain.mainView");holder.img_icon.setBackgroundResource(goodsIcon);holder.text_title.setText(goods.getGoodsTitle());holder.text_price.setText(goods.getGoodsPrice());//第一个参数0代表直接获取值Car car = new Car();holder.text_num.setText(String.valueOf(car.getGoodsCarNum(goods.getGoodsId())));Log.i(TAG, "onBindViewHolder: goodsId" + goods.getGoodsId());Log.i(TAG, "onBindViewHolder: goodsId" + goods.getGoodsTitle());holder.btn_numAdd.setOnClickListener(new ImageButton.OnClickListener() {@Overridepublic void onClick(View v) {int pos = holder.getLayoutPosition();sOnItemClickListener.ImageButtonClickListener(holder.itemView, pos);//更新购物车数据库数量加1,然后重新获取购物车数量holder.text_num.setText(String.valueOf(car.addOne(goods.getGoodsId())));}});holder.btn_numReduce.setOnClickListener(new ImageButton.OnClickListener() {@Overridepublic void onClick(View v) {int pos = holder.getLayoutPosition();sOnItemClickListener.ImageButtonClickListener(holder.itemView, pos);//更新购物车数据库数量加1,然后重新获取购物车数量holder.text_num.setText(String.valueOf(car.reduceOne(goods.getGoodsId())));}});//如果监听事件不为空,回调相应的方法if (sOnItemClickListener != null) {holder.itemView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//获取当前点击item的位置posint pos = holder.getLayoutPosition();sOnItemClickListener.ItemClickListener(holder.itemView, pos);}});//长摁删除购物车商品holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {@Overridepublic boolean onLongClick(View v) {if(sOnItemClickListener != null){//获取当前点击item的位置posint pos =holder.getLayoutPosition();sOnItemClickListener.ItemLongClickListener(holder.itemView,pos);}return false;}});}}//返回长度@Overridepublic int getItemCount() {return mGoodsList.size();}public class ViewHolder extends RecyclerView.ViewHolder {//获取控件public ImageView img_icon;public TextView text_title, text_price, text_num;public ImageButton btn_numReduce, btn_numAdd;public ViewHolder(@NonNull View itemView) {super(itemView);img_icon = itemView.findViewById(R.id.shoppingCar_icon);text_title = itemView.findViewById(R.id.shoppingCar_title);text_price = itemView.findViewById(R.id.shoppingCar_price);text_num = itemView.findViewById(R.id.shoppingCar_num);btn_numReduce = itemView.findViewById(R.id.btn_numReduce);btn_numAdd = itemView.findViewById(R.id.btn_numAdd);}}//构造函数 读取购物车数据库里的东西,add进去。public ShoppingCarAdapter(List<Goods> list) {mGoodsList = list;Log.i(TAG, "AdapterList" + list);}//定义单击事件和长摁事件接口public interface OnItemClickListener {void ItemClickListener(View view, int position);void ItemLongClickListener(View view, int position);//这里的ImageButton 为购物车页面的商品数量加减 两个图片按钮void ImageButtonClickListener(View view, int position);}public void setOnClickListener(ShoppingCarAdapter.OnItemClickListener listener) {this.sOnItemClickListener = listener;}
}
3.购物车布局页面
fragment_shoppingcar.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayoutxmlns: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"tools:context=".ui.shoppingcar.ShoppingCarFragment">
<-- 存放购物车商品的RecyclerView --><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/shoppingCar"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_marginBottom="110dp"tools:ignore="MissingConstraints" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginRight="20dp"android:layout_marginLeft="20dp"android:layout_marginBottom="60dp"android:layout_alignParentBottom="true"><-- 总价格的TextView 这块还没实现 --><TextViewandroid:id="@+id/text_all_price"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="4"android:textColor="#D00000"android:textSize="25sp"/><Buttonandroid:id="@+id/btn_confirm_order"android:layout_width="0dp"android:layout_weight="2"android:layout_height="wrap_content"android:text="确认订单" /></LinearLayout>
</RelativeLayout>
购物车RecyclerView的 list ShoppingCar_list.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"xmlns:app="http://schemas.android.com/apk/res-auto">
<--多选框--><CheckBoxandroid:id="@+id/shoppingCar_checkbox"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:layout_marginLeft="5dp"android:layout_marginTop="37dp"android:theme="@style/MyCheckBox"/>
<--卡片式布局--><androidx.cardview.widget.CardViewandroid:layout_width="340dp"android:layout_height="wrap_content"android:layout_marginStart="5dp"android:layout_marginTop="5dp"android:layout_marginEnd="5dp"android:layout_marginBottom="5dp"app:cardBackgroundColor="@color/white"android:layout_toRightOf="@+id/shoppingCar_checkbox"app:cardCornerRadius="20dp"app:contentPadding="15dp"><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_toRightOf="@+id/shoppingCar_checkbox"><ImageViewandroid:id="@+id/shoppingCar_icon"android:layout_width="80dp"android:layout_height="80dp"android:scaleType="fitCenter" /><TextViewandroid:id="@+id/shoppingCar_title"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_toRightOf="@+id/shoppingCar_icon"android:paddingLeft="5dp" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_below="@+id/shoppingCar_title"android:layout_alignBottom="@+id/shoppingCar_icon"android:layout_centerInParent="true"android:layout_marginRight="10dp"android:layout_toRightOf="@+id/shoppingCar_icon"android:gravity="bottom"android:paddingLeft="5dp"><TextViewandroid:id="@+id/shoppingCar_price"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_below="@+id/shoppingCar_title"android:layout_toRightOf="@+id/shoppingCar_icon"android:layout_weight="4"android:textSize="16sp" /><ImageButtonandroid:id="@+id/btn_numReduce"android:layout_width="0dp"android:layout_height="30dp"android:layout_weight="0.8"android:background="#FFFFFFFF"android:padding="0dp"android:scaleType="fitCenter"android:src="@drawable/shoppingcar_reduce_48" /><TextViewandroid:id="@+id/shoppingCar_num"android:layout_width="0dp"android:layout_height="30dp"android:layout_weight="0.8"android:gravity="center" /><ImageButtonandroid:id="@+id/btn_numAdd"android:layout_width="0dp"android:layout_height="30dp"android:layout_weight="0.8"android:background="#FFFFFFFF"android:padding="0dp"android:scaleType="fitCenter"android:src="@drawable/shoppingcar_add_48" /></LinearLayout></RelativeLayout></androidx.cardview.widget.CardView>
</RelativeLayout>

还存在一些问题:
Bug1:数量加减那块,没有判断是否小于0
Bug2:长摁删除商品,后,页面会在下面加载一列商品列表,点击其他的Fragment再点回来就正常了,估计是我删除后的刷新页面位置没放对。

代码量有点多,可能会缺少一些配置信息,遇到什么问题可以私我也可以发表评论,看到会回复哒!
码字不易,点个赞吧!快去自己动手试试吧!

Android商城开发----点击加入购物车,购物车商品的增删减相关推荐

  1. Android商城开发----点击左侧分类列表右侧更新对应列表内容

    Android商城开发----点击左侧分类列表右侧更新对应列表内容 目录 Android商城开发----点击左侧分类列表右侧更新对应列表内容 一.首先说布局: 二.主要说一下,布局完成后实现点击左侧类 ...

  2. Android商城开发----viewPager实现广告轮播(在首页Fragment中实现)

    Android商城开发----在商城首页Fragment使用viewPager实现广告轮播 写在前面:本篇文章建立在创建底部导航栏之后,对商城首页进行开发.创建底部导航栏的内容请查看:Android开 ...

  3. Android商城开发系列

    Android商城开发系列(一)--开篇 Android商城开发系列(二)--App启动欢迎页面制作 Android商城开发系列(三)--使用Fragment+RadioButton实现商城底部导航栏 ...

  4. Android商城开发系列(一)——开篇

    最近在看尚硅谷的硅谷商城视频,想系统学习一下Android的商城开发流程,打算跟着视频的一步步做出一个商城,然后写博客总结记录一下整个商城的开发过程以及使用到的技术知识点,这个商城的最终效果如下图所示 ...

  5. Android商城开发--实现商城底部导航栏

    让我们先看效果图: 图一是默认效果图,图二是点击首页的效果图(图标和字体颜色会变化)            接下来是实现方法 1.先写布局. 我新建了一个ShoppingActivity,在activ ...

  6. Android商城开发系列(二)——App启动欢迎页面制作

    商城APP一般都会在应用启动时有一个欢迎界面,下面我们来实现一个最简单的欢迎页开发:就是打开商城App,先出现欢迎界面,停留几秒钟,自动进入应用程序的主界面. 首先先定义WelcomeActivity ...

  7. Android商城开发系列(六)——使用 OkHttpUtils 请求网络 + 使用 fastjson解析数据...

    OkHttp是Google推荐使用的一个开源的网络请求框架,Android开发中涉及到网络请求和接口调用现在大部分都是使用OkHttp,网上已经有不少人针对OkHttp进行了封装,这里推荐一下鸿洋大神 ...

  8. Android商城开发(一)——一次活动页需求引发的危机感

    本文出自:https://blog.csdn.net/DT235201314/article/details/81027990 一丶概述 本文讲述商城活动页需求解决过程,及一些个人想法(危机感),提供 ...

  9. Android商城开发系列(十)—— 首页活动广告布局实现

    在上一篇博客当中,我们讲了频道布局的实现,接下来我们讲解一下活动广告布局的实现,效果如下图: 这个是用viewpager去实现的,新建一个act_item.xml,代码如下所示: 1 <?xml ...

最新文章

  1. python安装pyqt5 qml_PyQt5:PyQt5程序打包2
  2. 【GOTC 预告】王思宇:从 OpenKruise 看云原生应用负载发展趋势
  3. HTTP系列学习(笔记二):HTTPS与HTTP的区别在哪?
  4. mysql workbench安装出错_MYSQL及MySQL WORKBENCH安装过程遇到的问题及处理方法
  5. mysql修改密码5.7_mysql数据库5.7版修改密码详细(centos7)
  6. 为Python IDLE 添加清屏(Ctrl + L )快捷工具(附带解决错误的方法)
  7. Android 自定义字体(otf,ttf等等)
  8. Leetcode力扣 MySQL数据库 1132 报告的记录II
  9. 【数据结构】 树与二叉树的基本概念、结构特点及性质
  10. 借助云开发实现小程序朋友圈的发布与展示
  11. Centos系统各种日志存详解
  12. 前端,java后端开发,数据分析师应该掌握的技术,不要盲目跟风
  13. 数睿数据深度 | 关于软件自主可控,源代码向左,无代码向右
  14. 深入理解feature_column
  15. 安诺伦代理iduron品牌——为学术研究和制药行业提供独特的糖胺聚糖产品系列
  16. 从0配置halo博客并配置SSL
  17. “熊猫烧香”变本加厉 当心“金猪报喜”
  18. ar crypt下载_下载我们的新2D示例项目:Lost Crypt
  19. kylin OS 软件源
  20. 【Unity项目实战】主程进阶之路文章整理

热门文章

  1. 数据库-订单商品表(单表-商品销量表)
  2. Checkmarx CxEnterprise代码审查
  3. 量化投资数据分析之常用的python包(附代码)
  4. iPhone定义自己的个性手机铃声
  5. 经济学考研笔记3:效用理论(消费者行为理论)
  6. 奥的斯3100电气图纸_奥的斯otis 3200电气原理图及序号与符号说明
  7. C# TSF 输入法的获取
  8. window10安装cloc
  9. Python计时工具
  10. 什么是黑苹果(Hackintosh)