2022-11-18学习内容
1.案例-购物车-清空购物车
1.1ShoppingCartActivity.java
package com.example.chapter06; import androidx.appcompat.app.AppCompatActivity; import android.app.AlertDialog; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import com.example.chapter06.database.ShoppingDBHelper; import com.example.chapter06.entity.CartInfo; import com.example.chapter06.entity.GoodsInfo; import com.example.chapter06.util.ToastUtil; import java.util.HashMap; import java.util.List; import java.util.Map; public class ShoppingCartActivity extends AppCompatActivity implements View.OnClickListener { private TextView tv_count; private LinearLayout ll_cart; private ShoppingDBHelper mDBHelper; // 声明一个购物车中的商品信息列表 private List<CartInfo> mCartList; // 声明一个根据商品编号查找商品信息的映射,把商品信息缓存起来,这样不用每一次都查询数据库 private Map<Integer, GoodsInfo> mGoodsMap = new HashMap<>(); private TextView tv_total_price; private LinearLayout ll_empty; private LinearLayout ll_content; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_shopping_cart); TextView tv_title = findViewById(R.id.tv_title); tv_title.setText("购物车"); ll_cart = findViewById(R.id.ll_cart); tv_total_price = findViewById(R.id.tv_total_price); tv_count = findViewById(R.id.tv_count); tv_count.setText(String.valueOf(MyApplication.getInstance().goodsCount)); mDBHelper = ShoppingDBHelper.getInstance(this); findViewById(R.id.iv_back).setOnClickListener(this); findViewById(R.id.btn_shopping_channel).setOnClickListener(this); findViewById(R.id.btn_clear).setOnClickListener(this); findViewById(R.id.btn_settle).setOnClickListener(this); ll_empty = findViewById(R.id.ll_empty); ll_content = findViewById(R.id.ll_content); } @Override protected void onResume() { super.onResume(); showCart(); } // 展示购物车中的商品列表 private void showCart() { // 移除下面的所有子视图 ll_cart.removeAllViews(); // 查询购物车数据库中所有的商品记录 mCartList = mDBHelper.queryAllCartsInfo(); if (mCartList.size() == 0) { return; } for (CartInfo info : mCartList) { // 根据商品编号查询商品数据库中的商品记录 GoodsInfo goods = mDBHelper.queryGoodsInfoById(info.goodsId); mGoodsMap.put(info.goodsId, goods); // 获取布局文件item_cart.xml的根视图 View view = LayoutInflater.from(this).inflate(R.layout.item_cart, null); ImageView iv_thumb = view.findViewById(R.id.iv_thumb); TextView tv_name = view.findViewById(R.id.tv_name); TextView tv_desc = view.findViewById(R.id.tv_desc); TextView tv_count = view.findViewById(R.id.tv_count); TextView tv_price = view.findViewById(R.id.tv_price); TextView tv_sum = view.findViewById(R.id.tv_sum); iv_thumb.setImageURI(Uri.parse(goods.picPath)); tv_name.setText(goods.name); tv_desc.setText(goods.description); tv_count.setText(String.valueOf(info.count)); tv_price.setText(String.valueOf((int)goods.price)); // 设置商品总价 tv_sum.setText(String.valueOf((int)info.count * goods.price)); // 向商品行添加长按事件,长按商品行就删除该商品 view.setOnLongClickListener(v -> { AlertDialog.Builder builder = new AlertDialog.Builder(ShoppingCartActivity.this); builder.setMessage("是否从购物车删除" + goods.name + "?"); builder.setPositiveButton("是", (dialog, which) -> { // 移除当前视图 ll_cart.removeView(v); // 删除该商品 deleteGoods(info); }); builder.setNegativeButton("否", null); builder.create().show(); return true; }); // 往购物车列表添加该商品行 ll_cart.addView(view); } // 重新计算购物车中的商品总金额 refreshTotalPrice(); } private void deleteGoods(CartInfo info) { MyApplication.getInstance().goodsCount -= info.count; // 从购物车的数据库中删除商品 mDBHelper.deleteCartInfoByGoodsId(info.goodsId); // 从购物车的列表中删除商品 CartInfo removed = null; for (CartInfo cartInfo : mCartList) { if (cartInfo.goodsId == info.goodsId) { removed = cartInfo; break; } } mCartList.remove(removed); // 显示最新的商品数量 showCount(); ToastUtil.show(this, "已从购物车删除" + mGoodsMap.get(info.goodsId).name); mGoodsMap.remove(info.goodsId); // 刷新购物车中所有商品的总金额 refreshTotalPrice(); } // 显示购物车图标中的商品数量 private void showCount() { tv_count.setText(String.valueOf(MyApplication.getInstance().goodsCount)); // 购物车中没有商品,显示”空空如也“ if (MyApplication.getInstance().goodsCount == 0) { ll_empty.setVisibility(View.VISIBLE); ll_content.setVisibility(View.GONE); ll_cart.removeAllViews(); } else { ll_content.setVisibility(View.VISIBLE); ll_empty.setVisibility(View.GONE); } } // 重新计算购物车中的商品总金额 private void refreshTotalPrice() { int totalPrice = 0; for (CartInfo info : mCartList) { GoodsInfo goods = mGoodsMap.get(info.goodsId); totalPrice += goods.price * info.count; } tv_total_price.setText(String.valueOf(totalPrice)); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.iv_back: // 点击了返回图标 // 关闭当前页面 finish(); break; case R.id.btn_shopping_channel: // 从购物车页面跳转到商场页面 Intent intent = new Intent(this, ShoppingChannelActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); break; case R.id.btn_clear: // 清空购物车数据库 mDBHelper.deleteAllCartInfo(); MyApplication.getInstance().goodsCount = 0; // 显示最新的商品数量 showCount(); ToastUtil.show(this, "购物车已清空"); break; case R.id.btn_settle: // 点击了“结算”按钮 AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("结算商品"); builder.setMessage("客观抱歉,支付功能尚未开通,请下次再来"); builder.setPositiveButton("我知道了", null); builder.create().show(); break; } } }
1.2ShoppingDBHelper.java
package com.example.chapter06.database; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import com.example.chapter06.entity.CartInfo; import com.example.chapter06.entity.GoodsInfo; import java.util.ArrayList; import java.util.List; public class ShoppingDBHelper extends SQLiteOpenHelper { private static final String DB_NAME = "shopping.db"; // 商品信息表 private static final String TABLE_GOODS_INFO = "GOODS_INFO"; // 购物车信息表 private static final String TABLE_CART_INFO = "CART_INFO"; private static final int DB_VERSION = 1; private static ShoppingDBHelper mHelper = null; private SQLiteDatabase mRDB = null; private SQLiteDatabase mWDB = null; private ShoppingDBHelper(Context context) { super(context, DB_NAME, null, DB_VERSION); } // 打开数据库的读连接 public SQLiteDatabase openReadLink() { if (mRDB == null || !mRDB.isOpen()) { mRDB = mHelper.getReadableDatabase(); } return mRDB; } // 打开数据库的写连接 public SQLiteDatabase openWriteLink() { if (mWDB == null || !mWDB.isOpen()) { mWDB = mHelper.getWritableDatabase(); } return mWDB; } // 关闭数据库连接 public void closeLink() { if (mRDB != null && mRDB.isOpen()) { mRDB.close(); mRDB = null; } if (mWDB != null && mWDB.isOpen()) { mWDB.close(); mWDB = null; } } // 利用单例模式获取数据库帮助器的唯一实例 public static ShoppingDBHelper getInstance(Context context) { if (mHelper == null) { mHelper = new ShoppingDBHelper(context); } return mHelper; } // 创建数据库,执行建表语句 @Override public void onCreate(SQLiteDatabase db) { // 创建商品信息表 String sql = "CREATE TABLE IF NOT EXISTS " + TABLE_GOODS_INFO + "(_ID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," + " NAME VARCHAR NOT NULL," + " DESCRIPTION VARCHAR NOT NULL," + " PRICE FLOAT NOT NULL," + " PIC_PATH VARCHAR NOT NULL);"; db.execSQL(sql); // 创建购物车信息表 sql = "CREATE TABLE IF NOT EXISTS " + TABLE_CART_INFO + "(_ID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," + " GOODS_ID INTEGER NOT NULL," + " COUNT INTEGER NOT NULL);"; db.execSQL(sql); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } // 添加多条商品信息 public void insertGoodsInfos(List<GoodsInfo> list) { // 插入多条记录,要么全部成功,要么全部失败 try { mWDB.beginTransaction(); for (GoodsInfo info : list) { ContentValues values = new ContentValues(); values.put("name", info.name); values.put("description", info.description); values.put("price", info.price); values.put("pic_path", info.picPath); mWDB.insert(TABLE_GOODS_INFO, null, values); } mWDB.setTransactionSuccessful(); } catch (Exception e) { e.printStackTrace(); } finally { mWDB.endTransaction(); } } // 查询所有的商品信息 public List<GoodsInfo> queryAllGoodsInfo() { String sql = "select * from " + TABLE_GOODS_INFO; List<GoodsInfo> list = new ArrayList<>(); Cursor cursor = mRDB.rawQuery(sql, null); while (cursor.moveToNext()) { GoodsInfo info = new GoodsInfo(); info.id = cursor.getInt(0); info.name = cursor.getString(1); info.description = cursor.getString(2); info.price = cursor.getFloat(3); info.picPath = cursor.getString(4); list.add(info); } return list; } // 添加商品到购物车 public void insertCartInfo(int goodsId) { // 如果购物车中不存在该商品,添加一条信息 CartInfo cartInfo = queryCartInfoByGoodsId(goodsId); ContentValues values = new ContentValues(); values.put("goods_id", goodsId); if (cartInfo == null) { values.put("count", 1); mWDB.insert(TABLE_CART_INFO,null,values); } else { // 如果购物车中已经存在该商品,更新商品数量 values.put("_id", cartInfo.id); values.put("count", ++cartInfo.count); mWDB.update(TABLE_CART_INFO,values,"_id=?",new String[]{String.valueOf(cartInfo.id)}); } } private CartInfo queryCartInfoByGoodsId(int goodsId) { Cursor cursor = mRDB.query(TABLE_CART_INFO, null, "goods_id=?", new String[]{String.valueOf(goodsId)}, null, null, null); CartInfo info = null; if (cursor.moveToNext()) { info = new CartInfo(); info.id = cursor.getInt(0); info.goodsId = cursor.getInt(1); info.count = cursor.getInt(2); } return info; } // 统计购物车中商品的总数量 public int countCartInfo() { int count = 0; String sql = "select sum(count) from " + TABLE_CART_INFO; Cursor cursor = mRDB.rawQuery(sql, null); if (cursor.moveToNext()) { count = cursor.getInt(0); } return count; } // 查询购物车中所有的信息列表 public List<CartInfo> queryAllCartsInfo() { List<CartInfo> list = new ArrayList<>(); Cursor cursor = mRDB.query(TABLE_CART_INFO, null, null, null, null, null, null); while (cursor.moveToNext()) { CartInfo info = new CartInfo(); info.id = cursor.getInt(0); info.goodsId = cursor.getInt(1); info.count = cursor.getInt(2); list.add(info); } return list; } // 根据商品ID查询商品信息 public GoodsInfo queryGoodsInfoById(int goodsId) { GoodsInfo info = null; Cursor cursor = mRDB.query(TABLE_GOODS_INFO, null, "_id=?", new String[]{String.valueOf(goodsId)}, null, null, null); if (cursor.moveToNext()) { info = new GoodsInfo(); info.id = cursor.getInt(0); info.name = cursor.getString(1); info.description = cursor.getString(2); info.price = cursor.getFloat(3); info.picPath = cursor.getString(4); } return info; } // 根据商品ID删除购物车信息 public void deleteCartInfoByGoodsId(int goodsId) { mWDB.delete(TABLE_CART_INFO,"goods_id=?",new String[]{String.valueOf(goodsId)}); } // 删除所有购物车信息 public void deleteAllCartInfo() { mWDB.delete(TABLE_CART_INFO,"1=1",null); } }
1.3效果:
1.3.1长按购物车某一商品行,删除商品:
点“是”,删除商品:
1.3.2点“结算”:
1.3.3点“清空”按钮:
1.3.4点“逛逛手机商场”:
效果(返回了商场列表页):
2.案例-购物车-商品详情
2.1activity_shopping_detail.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:tools="http://schemas.android.com/tools" android:background="@color/orange" android:orientation="vertical"> <include layout="@layout/title_shopping" /> <ScrollView android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <ImageView android:id="@+id/iv_goods_pic" android:layout_width="match_parent" android:layout_height="350dp" android:scaleType="fitCenter" tools:src="@drawable/xiaomi" /> <TextView android:id="@+id/tv_goods_price" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingLeft="5dp" android:textColor="@color/red" android:textSize="22sp" tools:text="1990" /> <TextView android:id="@+id/tv_goods_desc" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingLeft="5dp" android:textColor="@color/black" android:textSize="15sp" tools:text="小米 MI10 8GB+128GB 钛银黑 5G手机 游戏拍照手机" /> <Button android:id="@+id/btn_add_cart" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="加入购物车" android:textColor="@color/black" android:textSize="17sp" /> </LinearLayout> </ScrollView> </LinearLayout>
2.2ShoppingDetailActivity.java
package com.example.chapter06; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.widget.ImageView; import android.widget.TextView; import com.example.chapter06.database.ShoppingDBHelper; import com.example.chapter06.entity.GoodsInfo; import com.example.chapter06.util.ToastUtil; public class ShoppingDetailActivity extends AppCompatActivity implements View.OnClickListener { private TextView tv_title; private TextView tv_count; private TextView tv_goods_price; private TextView tv_goods_desc; private ImageView iv_goods_pic; private ShoppingDBHelper mDBHelper; private int mGoodsId; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_shopping_detail); tv_title = findViewById(R.id.tv_title); tv_count = findViewById(R.id.tv_count); tv_goods_price = findViewById(R.id.tv_goods_price); tv_goods_desc = findViewById(R.id.tv_goods_desc); iv_goods_pic = findViewById(R.id.iv_goods_pic); findViewById(R.id.iv_back).setOnClickListener(this); findViewById(R.id.iv_cart).setOnClickListener(this); findViewById(R.id.btn_add_cart).setOnClickListener(this); tv_count.setText(String.valueOf(MyApplication.getInstance().goodsCount)); mDBHelper = ShoppingDBHelper.getInstance(this); } @Override protected void onResume() { super.onResume(); showDetail(); } private void showDetail() { // 获取上一个页面传来的商品编号 mGoodsId = getIntent().getIntExtra("goods_id", 0); if (mGoodsId > 0) { // 根据商品编号查询商品数据库中的商品记录 GoodsInfo info = mDBHelper.queryGoodsInfoById(mGoodsId); tv_title.setText(info.name); tv_goods_desc.setText(info.description); tv_goods_price.setText(String.valueOf((int)info.price)); iv_goods_pic.setImageURI(Uri.parse(info.picPath)); } } @Override public void onClick(View v) { switch (v.getId()) { case R.id.iv_back: finish(); break; case R.id.iv_cart: Intent intent = new Intent(this, ShoppingCartActivity.class); startActivity(intent); break; case R.id.btn_add_cart: addToCart(mGoodsId); break; } } private void addToCart(int mGoodsId) { // 购物车商品数量+1 int count = ++MyApplication.getInstance().goodsCount; tv_count.setText(String.valueOf(count)); mDBHelper.insertCartInfo(mGoodsId); ToastUtil.show(this, "成功添加至购物车"); } }
2.3ShoppingCartActivity.java新增内容:
// 展示购物车中的商品列表 private void showCart() { // 移除下面的所有子视图 ll_cart.removeAllViews(); // 查询购物车数据库中所有的商品记录 mCartList = mDBHelper.queryAllCartsInfo(); if (mCartList.size() == 0) { return; } for (CartInfo info : mCartList) { // 根据商品编号查询商品数据库中的商品记录 GoodsInfo goods = mDBHelper.queryGoodsInfoById(info.goodsId); mGoodsMap.put(info.goodsId, goods); // 获取布局文件item_cart.xml的根视图 View view = LayoutInflater.from(this).inflate(R.layout.item_cart, null); ImageView iv_thumb = view.findViewById(R.id.iv_thumb); TextView tv_name = view.findViewById(R.id.tv_name); TextView tv_desc = view.findViewById(R.id.tv_desc); TextView tv_count = view.findViewById(R.id.tv_count); TextView tv_price = view.findViewById(R.id.tv_price); TextView tv_sum = view.findViewById(R.id.tv_sum); iv_thumb.setImageURI(Uri.parse(goods.picPath)); tv_name.setText(goods.name); tv_desc.setText(goods.description); tv_count.setText(String.valueOf(info.count)); tv_price.setText(String.valueOf((int)goods.price)); // 设置商品总价 tv_sum.setText(String.valueOf((int)info.count * goods.price)); // 向商品行添加长按事件,长按商品行就删除该商品 view.setOnLongClickListener(v -> { AlertDialog.Builder builder = new AlertDialog.Builder(ShoppingCartActivity.this); builder.setMessage("是否从购物车删除" + goods.name + "?"); builder.setPositiveButton("是", (dialog, which) -> { // 移除当前视图 ll_cart.removeView(v); // 删除该商品 deleteGoods(info); }); builder.setNegativeButton("否", null); builder.create().show(); return true; }); // 给商品行添加点击事件。点击商品行跳到商品的详情页 view.setOnClickListener(v -> { Intent intent = new Intent(ShoppingCartActivity.this, ShoppingDetailActivity.class); intent.putExtra("goods_id", goods.id); startActivity(intent); }); // 往购物车列表添加该商品行 ll_cart.addView(view); } // 重新计算购物车中的商品总金额 refreshTotalPrice(); }
2.4ShoppingChannelActivity.java新增内容:
private void showGoods() { // 商品条目是一个线性布局,设置布局的宽度为屏幕的一半 int screenWidth = getResources().getDisplayMetrics().widthPixels; LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(screenWidth / 2, LinearLayout.LayoutParams.WRAP_CONTENT); // 查询商品数据库中的所有商品记录 List<GoodsInfo> list = mDBHelper.queryAllGoodsInfo(); // 移除下面的所有子视图 gl_channel.removeAllViews(); for (GoodsInfo info : list) { // 获取布局文件item_goods.xml的根视图 View view = LayoutInflater.from(this).inflate(R.layout.item_goods, null); ImageView iv_thumb = view.findViewById(R.id.iv_thumb); TextView tv_name = view.findViewById(R.id.tv_name); TextView tv_price = view.findViewById(R.id.tv_price); Button btn_add = view.findViewById(R.id.btn_add); // 给控件设置值 iv_thumb.setImageURI(Uri.parse(info.picPath)); tv_name.setText(info.name); tv_price.setText(String.valueOf((int)info.price)); // 添加到购物车 btn_add.setOnClickListener(v -> { addToCart(info.id, info.name); }); // 点击商品图片,跳转到商品详情页面 iv_thumb.setOnClickListener(v -> { Intent intent = new Intent(ShoppingChannelActivity.this, ShoppingDetailActivity.class); intent.putExtra("goods_id", info.id); startActivity(intent); }); // 把商品视图添加到网格布局 gl_channel.addView(view, params); } }
2.5效果:
商城页点击某一手机:
进入详情页:
从购物车点击某一商品:
进入详情页: