上一章节:【分类页面】点击左侧类别,实现右侧对应类别商品的展示
本文是在上一章节基础上开发的,点击【分类】页面商品的加入购物车按钮,实现将商品加入购物车的功能。
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的按钮。
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);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_GOODS_SQL);
Log.i(TAG, "onCreate: 商品列表数据库创建成功");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("drop table if exists goods");
onCreate(db);
}
}
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);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_GOODS_SQL);
Log.i(TAG, "onCreate: 购物车数据库创建成功啦!");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//更新数据库
db.execSQL("drop table if exists shoppingCar");
onCreate(db);
}
}
/*商品类
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;
}
}
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插入数据库,数量是1
Log.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();
//初始化数量为1
int 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)});
}
}
全局获取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;
@Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
}
public static Context getContext(){
return context;
}
}
需要在AndroidManifest.xml指定:
<application
android:name="com.example.networktest.MyApplication"
...>
</application>
分类页面右侧的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() {
@Override
public void onClick(View v) {
int pos = holder.getLayoutPosition();
mOnItemClickListener.ImageButtonClickListener(holder.itemView, pos);
//点击识别当前商品id
int currentId = listId.get(position);
Log.i(TAG, "currentId" + currentId);
car.addCar(currentId);
Log.i(TAG, "新商品加入购物车成功!");
// }
}
});
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;
@Override
public 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() {
@Override
public void ItemClickListener(View view, int position) {
Intent intent = new Intent(getActivity(), GoodsDetails.class);
startActivity(intent);
}
//长摁事件
@Override
public 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() {
@Override
public void onClick(DialogInterface dialog, int which) {
alertDialog.cancel();
Log.i(TAG, "ItemLongClickListener: 点击了否");
}
});
//确定按钮
alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "是",
new DialogInterface.OnClickListener() {
@Override
public 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: 长摁删除");
}
//图片按钮点击事件
@Override
public 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/商品标题/商品价格
//实例化类
//类.方法 调用封装好的okhttp
HttpUtil.sendOkHttpRequest(url, json.toString(), new okhttp3.Callback() {
//异常处理
@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {
e.printStackTrace();//打印异常
httpError(); //对异常情况处理
}
@Override
public 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, "商品信息请求成功");
//继续解析里面内容data
JSONArray 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
@Override
public void onResume() {
super.onResume();
upShoppingCarAdapter();
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
这里主要定义了购物车页面加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()就是调用的全局Context
View 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() {
@Override
public 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() {
@Override
public 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() {
@Override
public void onClick(View v) {
//获取当前点击item的位置pos
int pos = holder.getLayoutPosition();
sOnItemClickListener.ItemClickListener(holder.itemView, pos);
}
});
//长摁删除购物车商品
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if(sOnItemClickListener != null){
//获取当前点击item的位置pos
int pos =holder.getLayoutPosition();
sOnItemClickListener.ItemLongClickListener(holder.itemView,pos);
}
return false;
}
});
}
}
//返回长度
@Override
public 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;
}
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns: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.RecyclerView
android:id="@+id/shoppingCar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="110dp"
tools:ignore="MissingConstraints" />
<LinearLayout
android: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 这块还没实现 -->
<TextView
android:id="@+id/text_all_price"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="4"
android:textColor="#D00000"
android:textSize="25sp"/>
<Button
android:id="@+id/btn_confirm_order"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="wrap_content"
android:text="确认订单" />
</LinearLayout>
</RelativeLayout>
<?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">
<--多选框-->
<CheckBox
android: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.CardView
android: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">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/shoppingCar_checkbox">
<ImageView
android:id="@+id/shoppingCar_icon"
android:layout_width="80dp"
android:layout_height="80dp"
android:scaleType="fitCenter" />
<TextView
android:id="@+id/shoppingCar_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/shoppingCar_icon"
android:paddingLeft="5dp" />
<LinearLayout
android: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">
<TextView
android: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" />
<ImageButton
android: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" />
<TextView
android:id="@+id/shoppingCar_num"
android:layout_width="0dp"
android:layout_height="30dp"
android:layout_weight="0.8"
android:gravity="center" />
<ImageButton
android: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再点回来就正常了,估计是我删除后的刷新页面位置没放对。
代码量有点多,可能会缺少一些配置信息,遇到什么问题可以私我也可以发表评论,看到会回复哒!
码字不易,点个赞吧!快去自己动手试试吧!