赞
踩
第一次进入购物车页面,购物车里面是空的,同时提示去逛手机商场, 如 首次进入的页面 图所示。接着去商场页面选购手机,随便挑了几部手机加入购物车,再返回购物车页面,即可看 到购物车的商品列表,如 购物车已选列表图 所示,有商品图片、名称、数量、单价、总价等等信息。当然购物车并 不仅仅只是展示待购买的商品,还要支持最终购买的结算操作、支持清空购物车,长按删除单项订单等功能。
购物车的存在感很强,不仅仅在购物车页面才能看到购物车。往往在商场页面,甚至商品详情页面,都 会看到某个角落冒出购物车图标。一旦有新商品加入购物车,购物车图标上的商品数量立马加一。当然,用户也能点击购物车图标直接跳到购物车页面。商场页面除了商品列表之外,页面右上角还有一个购物车图标,用户把商品加购物车,那么图标上的数字也会加一。
购物车存放着用户准备购买的商品,一开始是空的,随着商品被加入购物车,购物车中就会显示已添加的商品列表。
除了购物车页面,其它页面(如商场频道页面、商品详情页面),都可能在右上角或者右 下角找到购物车图标。购物车图标上会显示已添加的商品数量,且商品数量是实时更新的。
购物车页面、商场频道页面、商品详情页面多处都会显示商品的小图或者大图
线性布局LinearLayout:购物车界面从上往下排列,垂直方向的线性布局
网格布局GridLayout:商场页面的陈列橱柜,允许分行分列展示商品
相对布局RelativeLayout:页面右上角的购物车图标,图标右上角又有数字标记,按照指定方位排列控件
其他常见控件尚有文本视图TextView、图像视图ImageView,按钮控件Button等
数据库SQLite:最直观的是数据库,购物车里的商品列表一定放在SQLite中,增删改查
全局内存:购物车图标右上角的数字表示购物车中的商品数量,该数值建议保存在全局内存中,这样不必每次都到数据库中执行count操作。
存储卡文件:App把下载的商品图片保存在存储卡中,这样下次就能直接从存储卡获取商品图片,加快浏览速度。
共享参数SharedPreferences:是否首次访问网络图片,这个标志位推荐放在共享参数中, 需要持久化存储,并且只有一个参数信息
首次进入的页面图
商品展示列表图
购物车已选列表图
手机详情页面图
长按删除订单图
ShoppingChannelActivity.java
- package com.kcs.shoppingcart;
-
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.widget.GridView;
- import android.widget.TextView;
-
- import androidx.appcompat.app.AppCompatActivity;
-
- import com.kcs.shoppingcart.adapter.GoodsAdapter;
- import com.kcs.shoppingcart.datebase.ShoppingDBHelper;
- import com.kcs.shoppingcart.entity.GoodsInfo;
- import com.kcs.shoppingcart.utils.ToastUtil;
-
- import java.util.List;
-
- public class ShoppingChannelActivity extends AppCompatActivity implements View.OnClickListener, GoodsAdapter.AddCartListener {
-
- /**
- * 声明一个商品数据库的帮助器对象
- */
- private ShoppingDBHelper mDBHelper;
- private TextView tv_count;
- private GridView gv_channel;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_shopping_channel);
- TextView tv_title = findViewById(R.id.tv_title);
- tv_title.setText("手机商场");
-
- tv_count = findViewById(R.id.tv_count);
- gv_channel = findViewById(R.id.gv_channel);
- findViewById(R.id.iv_back).setOnClickListener(this);
- findViewById(R.id.iv_cart).setOnClickListener(this);
-
- mDBHelper = ShoppingDBHelper.getInstance(this);
- mDBHelper.openReadLink();
- mDBHelper.openWriteLink();
-
- // 从数据库查询出商品信息,并展示
- showGoods();
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- // 查询购物车商品总数,并展示
- showCartInfoTotal();
- }
-
- /**
- * 查询购物车商品总数,并展示
- */
- private void showCartInfoTotal() {
- int count = mDBHelper.countCartInfo();
- MyApplication.getInstance().goodsCount = count;
- tv_count.setText(String.valueOf(count));
- }
-
- private void showGoods() {
- // 查询商品数据库中的所有商品记录
- List<GoodsInfo> list = mDBHelper.queryAllGoodsInfo();
- GoodsAdapter adapter = new GoodsAdapter(this, list,this);
- gv_channel.setAdapter(adapter);
- }
-
- /**
- * 把指定编号的商品添加到购物车
- * @param goodsId
- * @param goodsName
- */
-
- @Override
- public void addToCart(int goodsId, String goodsName) {
- // 购物车商品数量+1
- int count = ++MyApplication.getInstance().goodsCount;
- tv_count.setText(String.valueOf(count));
- mDBHelper.insertCartInfo(goodsId);
- ToastUtil.show(this, "已添加一部" + goodsName + "到购物车");
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mDBHelper.closeLink();
- }
-
- @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);
- // 设置启动标志,避免多次返回同一页面的
- intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- startActivity(intent);
- break;
- default:
- break;
- }
- }
- }
ShoppingDetailActivity.java
- 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.dongnaoedu.chapter06.database.ShoppingDBHelper;
- import com.dongnaoedu.chapter06.enity.GoodsInfo;
- import com.dongnaoedu.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 goodsId) {
- // 购物车商品数量+1
- int count = ++MyApplication.getInstance().goodsCount;
- tv_count.setText(String.valueOf(count));
- mDBHelper.insertCartInfo(goodsId);
- ToastUtil.show(this, "成功添加至购物车");
- }
- }
ShoppingCartActivity.java
- package com.kcs.shoppingcart;
-
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.widget.AdapterView;
- import android.widget.LinearLayout;
- import android.widget.ListView;
- import android.widget.TextView;
-
- import androidx.appcompat.app.AlertDialog;
- import androidx.appcompat.app.AppCompatActivity;
-
- import com.kcs.shoppingcart.adapter.CartAdapter;
- import com.kcs.shoppingcart.datebase.ShoppingDBHelper;
- import com.kcs.shoppingcart.entity.CartInfo;
- import com.kcs.shoppingcart.entity.GoodsInfo;
- import com.kcs.shoppingcart.utils.ToastUtil;
-
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
-
- public class ShoppingCartActivity extends AppCompatActivity implements View.OnClickListener, AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener {
-
- private TextView tv_count;
- private ListView lv_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;
- private CartAdapter mCartAdapter;
-
- @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("购物车");
- lv_cart = findViewById(R.id.lv_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() {
- // 查询购物车数据库中所有的商品记录
- mCartList = mDBHelper.queryAllCartInfo();
- if (mCartList.size() == 0) {
- return;
- }
- for (CartInfo info : mCartList) {
- // 根据商品编号查询商品数据库中的商品记录
- GoodsInfo goods = mDBHelper.queryGoodsInfoById(info.goodsId);
- mGoodsMap.put(info.goodsId, goods);
- info.goods = goods;
- }
- mCartAdapter = new CartAdapter(this, mCartList);
- lv_cart.setAdapter(mCartAdapter);
- // 给商品行添加点击事件。点击商品行跳到商品的详情页
- lv_cart.setOnItemClickListener(this);
- // 给商品行添加长按事件。长按商品行就删除该商品
- lv_cart.setOnItemLongClickListener(this);
-
- // 重新计算购物车中的商品总金额
- 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);
- // 通知适配器发生了数据变化
- mCartAdapter.notifyDataSetChanged();
- } 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, com.kcs.shoppingcart.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;
- default:
- break;
- }
- }
-
- /**
- * 给商品行添加点击事件。点击商品行跳到商品的详情页
- */
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- Intent intent = new Intent(ShoppingCartActivity.this, com.kcs.shoppingcart.ShoppingDetailActivity.class);
- intent.putExtra("goods_id", mCartList.get(position).goodsId);
- startActivity(intent);
- }
-
- /**
- *给商品行添加长按事件。长按商品行就删除该商品
- */
- @Override
- public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
- CartInfo info = mCartList.get(position);
- AlertDialog.Builder builder = new AlertDialog.Builder(ShoppingCartActivity.this);
- builder.setMessage("是否从购物车删除" + info.goods.name + "?");
- builder.setPositiveButton("是", (dialog, which) -> {
- // 从集合中移除数据
- mCartList.remove(position);
- // 通知适配器发生了数据变化
- mCartAdapter.notifyDataSetChanged();
- // 删除该商品
- deleteGoods(info);
- });
- builder.setNegativeButton("否", null);
- builder.create().show();
- return true;
- }
- }
MyApplication.java
- package com.dongnaoedu.chapter06;
-
- import android.app.Application;
- import android.content.res.Configuration;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.os.Environment;
- import android.util.Log;
-
-
- import androidx.annotation.NonNull;
- import androidx.room.Room;
-
- import com.dongnaoedu.chapter06.database.ShoppingDBHelper;
- import com.dongnaoedu.chapter06.enity.GoodsInfo;
- import com.dongnaoedu.chapter06.util.FileUtil;
- import com.dongnaoedu.chapter06.util.SharedUtil;
-
- import java.io.File;
- import java.util.HashMap;
- import java.util.List;
-
- public class MyApplication extends Application {
-
- // 购物车中的商品总数量
- public int goodsCount;
-
- public static MyApplication getInstance() {
- return mApp;
- }
-
-
- //在App启动时调用
- @Override
- public void onCreate() {
- super.onCreate();
- mApp = this;
- Log.d("ning", "MyApplication onCreate");
-
- // 初始化商品信息
- initGoodsInfo();
- }
-
- private void initGoodsInfo() {
- // 获取共享参数保存的是否首次打开参数
- boolean isFirst = SharedUtil.getInstance(this).readBoolean("first", true);
- // 获取当前App的私有下载路径
- String directory = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString() + File.separatorChar;
- if (isFirst) {
- // 模拟网络图片下载
- List<GoodsInfo> list = GoodsInfo.getDefaultList();
- for (GoodsInfo info : list) {
- Bitmap bitmap = BitmapFactory.decodeResource(getResources(), info.pic);
- String path = directory + info.id + ".jpg";
- // 往存储卡保存商品图片
- FileUtil.saveImage(path, bitmap);
- // 回收位图对象
- bitmap.recycle();
- info.picPath = path;
- }
- // 打开数据库,把商品信息插入到表中
- ShoppingDBHelper dbHelper = ShoppingDBHelper.getInstance(this);
- dbHelper.openWriteLink();
- dbHelper.insertGoodsInfos(list);
- dbHelper.closeLink();
- // 把是否首次打开写入共享参数
- SharedUtil.getInstance(this).writeBoolean("first", false);
- }
- }
-
- }
package:adapter
CartAdapter.java
- package com.kcs.shoppingcart.adapter;
-
- import android.content.Context;
- import android.net.Uri;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.BaseAdapter;
- import android.widget.ImageView;
- import android.widget.TextView;
-
-
- import com.kcs.shoppingcart.R;
- import com.kcs.shoppingcart.entity.CartInfo;
-
- import java.util.List;
-
- public class CartAdapter extends BaseAdapter {
-
- private Context mContext;
- private List<CartInfo> mCartList;
-
- public CartAdapter(Context mContext, List<CartInfo> mCartList) {
- this.mContext = mContext;
- this.mCartList = mCartList;
- }
-
- @Override
- public int getCount() {
- return mCartList.size();
- }
-
- @Override
- public Object getItem(int position) {
- return mCartList.get(position);
- }
-
- @Override
- public long getItemId(int position) {
- return position;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- ViewHolder holder;
- if (convertView == null) {
- holder = new ViewHolder();
- // 获取布局文件item_cart.xml的根视图
- convertView = LayoutInflater.from(mContext).inflate(R.layout.item_cart, null);
- holder.iv_thumb = convertView.findViewById(R.id.iv_thumb);
- holder.tv_name = convertView.findViewById(R.id.tv_name);
- holder.tv_desc = convertView.findViewById(R.id.tv_desc);
- holder.tv_count = convertView.findViewById(R.id.tv_count);
- holder.tv_price = convertView.findViewById(R.id.tv_price);
- holder.tv_sum = convertView.findViewById(R.id.tv_sum);
- convertView.setTag(holder);
- } else {
- holder = (ViewHolder) convertView.getTag();
- }
-
- CartInfo info = mCartList.get(position);
- holder.iv_thumb.setImageURI(Uri.parse(info.goods.picPath));
- holder.tv_name.setText(info.goods.name);
- holder.tv_desc.setText(info.goods.description);
- holder.tv_count.setText(String.valueOf(info.count));
- holder.tv_price.setText(String.valueOf((int) info.goods.price));
- // 设置商品总价
- holder.tv_sum.setText(String.valueOf((int) (info.count * info.goods.price)));
- return convertView;
- }
-
- public final class ViewHolder {
- public ImageView iv_thumb;
- public TextView tv_name;
- public TextView tv_desc;
- public TextView tv_count;
- public TextView tv_price;
- public TextView tv_sum;
-
- }
- }
GoodsAdapter.java
- package com.kcs.shoppingcart.adapter;
-
- import android.content.Context;
- import android.content.Intent;
- import android.net.Uri;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.BaseAdapter;
- import android.widget.Button;
- import android.widget.ImageView;
- import android.widget.TextView;
-
- import com.kcs.shoppingcart.R;
- import com.kcs.shoppingcart.ShoppingDetailActivity;
- import com.kcs.shoppingcart.entity.GoodsInfo;
-
- import java.util.List;
-
- public class GoodsAdapter extends BaseAdapter {
-
- private Context mContext;
- private List<GoodsInfo> mGoodsInfo;
-
- public GoodsAdapter(Context mContext, List<GoodsInfo> mGoodsInfo, AddCartListener mAddCartListener) {
- this.mContext = mContext;
- this.mGoodsInfo = mGoodsInfo;
- this.mAddCartListener = mAddCartListener;
- }
-
- @Override
- public int getCount() {
- return mGoodsInfo.size();
- }
-
- @Override
- public Object getItem(int position) {
- return position;
- }
-
- @Override
- public long getItemId(int position) {
- return position;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- GoodsInfo info = mGoodsInfo.get(position);
- ViewHolder holder;
- if (convertView == null) {
- convertView = LayoutInflater.from(mContext).inflate(R.layout.item_goods, null);
- holder = new ViewHolder();
- holder.iv_thumb = convertView.findViewById(R.id.iv_thumb);
- holder.tv_name = convertView.findViewById(R.id.tv_name);
- holder.tv_price = convertView.findViewById(R.id.tv_price);
- holder.btn_add = convertView.findViewById(R.id.btn_add);
- convertView.setTag(holder);
- } else {
- holder = (ViewHolder) convertView.getTag();
- }
-
-
- // 给控件设置值
- holder.iv_thumb.setImageURI(Uri.parse(info.picPath));
- holder.tv_name.setText(info.name);
- holder.tv_price.setText(String.valueOf((int) info.price));
-
- // 添加到购物车
- holder.btn_add.setOnClickListener(v -> {
- mAddCartListener.addToCart(info.id, info.name);
- });
-
- //点击商品图片,跳转到商品详情页面
-
- holder.iv_thumb.setOnClickListener(v -> {
- Intent intent = new Intent(mContext, ShoppingDetailActivity.class);
- intent.putExtra("goods_id", info.id);
- mContext.startActivity(intent);
- });
-
- return convertView;
- }
-
- public final class ViewHolder {
- public ImageView iv_thumb;
- public TextView tv_name;
- public TextView tv_price;
- public Button btn_add;
- }
-
- /**
- * 声明一个加入购物车的监听器对象
- */
- private AddCartListener mAddCartListener;
-
- /**
- * 定义一个加入购物车的监听器接口
- */
- public interface AddCartListener {
- void addToCart(int goodsId, String goodsName);
- }
- }
package util:
ToastUitl.java
- package com.dongnaoedu.chapter06.util;
-
- import android.content.Context;
- import android.widget.Toast;
-
- public class ToastUtil {
-
- public static void show(Context ctx, String desc) {
- Toast.makeText(ctx, desc, Toast.LENGTH_SHORT).show();
- }
-
- }
SharedUtil.java
- import android.content.Context;
- import android.content.SharedPreferences;
-
- public class SharedUtil {
-
- private static SharedUtil mUtil;
- private SharedPreferences preferences;
-
- public static SharedUtil getInstance(Context ctx) {
- if (mUtil == null) {
- mUtil = new SharedUtil();
- mUtil.preferences = ctx.getSharedPreferences("shopping", Context.MODE_PRIVATE);
- }
- return mUtil;
- }
-
- public void writeBoolean(String key, boolean value) {
- SharedPreferences.Editor editor = preferences.edit();
- editor.putBoolean(key, value);
- editor.commit();
- }
-
- public boolean readBoolean(String key, boolean defaultValue) {
- return preferences.getBoolean(key, defaultValue);
- }
-
- }
FileUtil.java
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
-
- import java.io.BufferedReader;
- import java.io.BufferedWriter;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.FileReader;
- import java.io.FileWriter;
- import java.io.IOException;
-
- public class FileUtil {
-
- // 把位图数据保存到指定路径的图片文件
- public static void saveImage(String path, Bitmap bitmap) {
- FileOutputStream fos = null;
- try {
- fos = new FileOutputStream(path);
- // 把位图数据压缩到文件输出流中
- bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (fos != null) {
- try {
- fos.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
-
- // 从指定路径的图片文件中读取位图数据
- public static Bitmap openImage(String path) {
- Bitmap bitmap = null;
- FileInputStream fis = null;
- try {
- fis = new FileInputStream(path);
- bitmap = BitmapFactory.decodeStream(fis);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (fis != null) {
- try {
- fis.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- return bitmap;
- }
- }
package pojo:
CarInfo.java
- package com.kcs.shoppingcart.entity;
-
- //购物车信息
- public class CartInfo {
- public int id;
- /**
- * 商品编号
- */
- public int goodsId;
- /**
- * 商品数量
- */
- public int count;
- /**
- * 商品信息
- */
- public GoodsInfo goods;
-
- public CartInfo() {
- }
-
- public CartInfo(int id, int goodsId, int count) {
- this.id = id;
- this.goodsId = goodsId;
- this.count = count;
- this.goods = new GoodsInfo();
- }
- }
GoodsInfo.java
- import com.dongnaoedu.chapter06.R;
-
- import java.util.ArrayList;
-
- public class GoodsInfo {
-
- public int id;
- // 名称
- public String name;
- // 描述
- public String description;
- // 价格
- public float price;
- // 大图的保存路径
- public String picPath;
- // 大图的资源编号
- public int pic;
-
- // 声明一个手机商品的名称数组
- private static String[] mNameArray = {
- "iPhone11", "Mate30", "小米10", "OPPO Reno3", "vivo X30", "荣耀30S"
- };
- // 声明一个手机商品的描述数组
- private static String[] mDescArray = {
- "Apple iPhone11 256GB 绿色 4G全网通手机",
- "华为 HUAWEI Mate30 8GB+256GB 丹霞橙 5G全网通 全面屏手机",
- "小米 MI10 8GB+128GB 钛银黑 5G手机 游戏拍照手机",
- "OPPO Reno3 8GB+128GB 蓝色星夜 双模5G 拍照游戏智能手机",
- "vivo X30 8GB+128GB 绯云 5G全网通 美颜拍照手机",
- "荣耀30S 8GB+128GB 蝶羽红 5G芯片 自拍全面屏手机"
- };
- // 声明一个手机商品的价格数组
- private static float[] mPriceArray = {6299, 4999, 3999, 2999, 2998, 2399};
- // 声明一个手机商品的大图数组
- private static int[] mPicArray = {
- R.drawable.iphone, R.drawable.huawei, R.drawable.xiaomi,
- R.drawable.oppo, R.drawable.vivo, R.drawable.rongyao
- };
-
- // 获取默认的手机信息列表
- public static ArrayList<GoodsInfo> getDefaultList() {
- ArrayList<GoodsInfo> goodsList = new ArrayList<GoodsInfo>();
- for (int i = 0; i < mNameArray.length; i++) {
- GoodsInfo info = new GoodsInfo();
- info.id = i;
- info.name = mNameArray[i];
- info.description = mDescArray[i];
- info.price = mPriceArray[i];
- info.pic = mPicArray[i];
- goodsList.add(info);
- }
- return goodsList;
- }
- }
package 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.dongnaoedu.chapter06.enity.CartInfo;
- import com.dongnaoedu.chapter06.enity.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 static ShoppingDBHelper getInstance(Context context) {
- if (mHelper == null) {
- mHelper = new ShoppingDBHelper(context);
- }
- return mHelper;
- }
-
- // 打开数据库的读连接
- 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;
- }
- }
-
- // 创建数据库,执行建表语句
- @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);
- }
- cursor.close();
- 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)});
- }
- }
-
- // 根据商品信息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> queryAllCartInfo() {
- 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);
- }
- }
activity_shopping_channel.xml
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@color/orange"
- android:orientation="vertical" >
-
- <include layout="@layout/title_shopping" />
-
- <GridView
- android:id="@+id/gv_channel"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:numColumns="2" />
-
- </LinearLayout>
activity_shopping_detail.xml
- <LinearLayout 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"
- 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>
activity_shopping_car.xml
- <LinearLayout 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"
- android:background="@color/orange"
- android:orientation="vertical">
-
- <include layout="@layout/title_shopping" />
-
- <ScrollView
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
-
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
-
- <LinearLayout
- android:id="@+id/ll_content"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:visibility="visible">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
-
- <TextView
- android:layout_width="85dp"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:text="图片"
- android:textColor="@color/black"
- android:textSize="15sp" />
-
- <TextView
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="3"
- android:gravity="center"
- android:text="名称"
- android:textColor="@color/black"
- android:textSize="15sp" />
-
- <TextView
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:gravity="center"
- android:text="数量"
- android:textColor="@color/black"
- android:textSize="15sp" />
-
- <TextView
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:gravity="center"
- android:text="单价"
- android:textColor="@color/black"
- android:textSize="15sp" />
-
- <TextView
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:gravity="center"
- android:text="总价"
- android:textColor="@color/black"
- android:textSize="15sp" />
-
- </LinearLayout>
-
- <LinearLayout
- android:id="@+id/ll_cart"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical" />
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:padding="0dp">
-
- <Button
- android:id="@+id/btn_clear"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:text="清空"
- android:textColor="@color/black"
- android:textSize="17sp" />
-
- <TextView
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:gravity="center|right"
- android:text="总金额:"
- android:textColor="@color/black"
- android:textSize="17sp" />
-
- <TextView
- android:id="@+id/tv_total_price"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginRight="10dp"
- android:gravity="center|left"
- android:textColor="@color/red"
- android:textSize="25sp" />
-
- <Button
- android:id="@+id/btn_settle"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:text="结算"
- android:textColor="@color/black"
- android:textSize="17sp" />
- </LinearLayout>
-
- </LinearLayout>
-
- <LinearLayout
- android:id="@+id/ll_empty"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:visibility="gone"
- tools:visibility="visible">
-
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="100dp"
- android:layout_marginBottom="100dp"
- android:gravity="center"
- android:text="哎呀,购物车空空如也,快去选购商品吧"
- android:textColor="@color/black"
- android:textSize="17sp" />
-
- <Button
- android:id="@+id/btn_shopping_channel"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:text="逛逛手机商场"
- android:textColor="@color/black"
- android:textSize="17sp" />
- </LinearLayout>
- </RelativeLayout>
- </ScrollView>
-
- </LinearLayout>
item_cart.xml
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@color/white"
- android:orientation="horizontal">
-
- <ImageView
- android:id="@+id/iv_thumb"
- android:layout_width="85dp"
- android:layout_height="85dp"
- android:scaleType="fitCenter"
- tools:src="@drawable/xiaomi"/>
-
- <LinearLayout
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="3"
- android:orientation="vertical">
-
- <TextView
- android:id="@+id/tv_name"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="2"
- android:gravity="left|center"
- android:textColor="@color/black"
- android:textSize="17sp"
- tools:text="小米手机"/>
-
- <TextView
- android:id="@+id/tv_desc"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="3"
- android:gravity="left|center"
- android:textColor="@color/black"
- android:textSize="12sp"
- tools:text="小米 MI10 8GB+128GB 钛银黑 5G手机 游戏拍照手机"/>
- </LinearLayout>
-
- <TextView
- android:id="@+id/tv_count"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:gravity="center"
- android:textColor="@color/black"
- android:textSize="17sp"
- tools:text="2"/>
-
- <TextView
- android:id="@+id/tv_price"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:gravity="right|center"
- android:textColor="@color/black"
- android:textSize="15sp"
- tools:text="1000"/>
-
- <TextView
- android:id="@+id/tv_sum"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1.2"
- android:gravity="right|center"
- android:textColor="@color/red"
- android:textSize="17sp"
- tools:text="2000"/>
-
- </LinearLayout>
item_goods.xml
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:id="@+id/ll_item"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:background="@color/white"
- android:gravity="center"
- android:orientation="vertical">
-
- <TextView
- android:id="@+id/tv_name"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:textColor="@color/black"
- android:textSize="17sp"
- tools:text="小米手机" />
-
- <ImageView
- android:id="@+id/iv_thumb"
- android:layout_width="180dp"
- android:layout_height="150dp"
- android:scaleType="fitCenter"
- tools:src="@drawable/xiaomi" />
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="45dp"
- android:orientation="horizontal">
-
- <TextView
- android:id="@+id/tv_price"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="2"
- android:gravity="center"
- android:textColor="@color/red"
- android:textSize="15sp"
- tools:text="20" />
-
- <Button
- android:id="@+id/btn_add"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="3"
- android:gravity="center"
- android:text="加入购物车"
- android:textColor="@color/black"
- android:textSize="15sp" />
- </LinearLayout>
-
- </LinearLayout>
title_shopping.xml
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="50dp"
- android:background="#aaaaff" >
-
- <ImageView
- android:id="@+id/iv_back"
- android:layout_width="50dp"
- android:layout_height="match_parent"
- android:layout_alignParentLeft="true"
- android:padding="10dp"
- android:scaleType="fitCenter"
- android:src="@drawable/ic_back" />
-
- <TextView
- android:id="@+id/tv_title"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_centerInParent="true"
- android:gravity="center"
- android:textColor="@color/black"
- android:textSize="20sp" />
-
- <ImageView
- android:id="@+id/iv_cart"
- android:layout_width="50dp"
- android:layout_height="match_parent"
- android:layout_alignParentRight="true"
- android:scaleType="fitCenter"
- android:src="@drawable/cart" />
-
- <TextView
- android:id="@+id/tv_count"
- android:layout_width="20dp"
- android:layout_height="20dp"
- android:layout_alignParentTop="true"
- android:layout_toRightOf="@+id/iv_cart"
- android:layout_marginLeft="-20dp"
- android:gravity="center"
- android:background="@drawable/shape_oval_red"
- android:text="0"
- android:textColor="@color/white"
- android:textSize="15sp" />
-
- </RelativeLayout>
shape_oval_red.xml
- <?xml version="1.0" encoding="utf-8"?>
- <shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="oval">
-
- <solid android:color="#ff6666" />
-
- </shape>
colors.xml
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <color name="purple_200">#FFBB86FC</color>
- <color name="purple_500">#FF6200EE</color>
- <color name="purple_700">#FF3700B3</color>
- <color name="teal_200">#FF03DAC5</color>
- <color name="teal_700">#FF018786</color>
- <color name="black">#FF000000</color>
- <color name="white">#FFFFFFFF</color>
- <color name="grey">#cccccc</color>
- <color name="orange">#ffffdd</color>
- <color name="red">#ff0000</color>
- </resources>
AndroidManifest.xml
把自己写的MyApplication配置上
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.kcs.shoppingcart">
-
- <application
- android:name=".MyApplication"
- android:allowBackup="true"
- android:icon="@mipmap/ic_launcher"
- android:label="@string/app_name"
- android:roundIcon="@mipmap/ic_launcher_round"
- android:supportsRtl="true"
- android:theme="@style/Theme.ShoppingCart">
-
- <activity
- android:name=".ShoppingCartActivity"
- android:exported="true" />
- <activity
- android:name=".ShoppingDetailActivity"
- android:exported="true" />
- <activity
- android:name=".ShoppingChannelActivity"
- android:exported="true">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
-
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
-
- </manifest>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。