(1)购物车存放着用户准备购买的商品,一开始是空的,随着商品被加入购物车,购物车中就会显示已添加的商品列表。
(2)除了购物车页面,其它页面(如商场频道页面、商品详情页面),都可能在右上角或者右下角找到购物车图标。购物车图标上会显示已添加的商品数量,且商品数量是实时更新的。
(3)购物车页面、商场频道页面、商品详情页面多处都会显示商品的小图或者大图,如何迅速且高效地加载图片是个需要研究的课题。
线性布局LinearLayout:购物车界面从上往下排列,用到了垂直方向的线性布局。
网格布局GridLayout:商场页面的陈列橱柜,允许分行分列展示商品。
相对布局RelativeLayout:页面右上角的购物车图标,图标右上角又有数字标记,按照指定方位排列控件正是相对布局的拿手好戏。
其他常见控件尚有文本视图TextView、图像视图ImageView,按钮控件Button等。
购物车用到的存储技术
数据库SQLite:最直观的是数据库,购物车里的商品列表一定放在SQLite中,增删改查都少不了它。
全局内存:购物车图标右上角的数字表示购物车中的商品数量,该数值建议保存在全局内存中,这样不必每次都到数据库中执行count操作。
存储卡文件:App把下载的商品图片保存在存储卡中,这样下次就能直接从存储卡获取商品图片,加快浏览速度。
共享参数SharedPreferences:是否首次访问网络图片,这个标志位推荐放在共享参数中,因为它需要持久化存储,并且只有一个参数信息。
===============================================================================================================
ShoppingCartActivity 布局:
<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" /> <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" > <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="100dp" android:layout_marginTop="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>
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>
代码:
package com.example.myapplication; import android.annotation.SuppressLint; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; import com.example.myapplication.bean.CartInfo; import com.example.myapplication.bean.GoodsInfo; import com.example.myapplication.database.CartDBHelper; import com.example.myapplication.database.GoodsDBHelper; import com.example.myapplication.util.SharedUtil; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @SuppressLint("SetTextI18n") public class ShoppingCartActivity extends AppCompatActivity implements View.OnClickListener { private final static String TAG = "ShoppingCartActivity"; private TextView tv_count; private TextView tv_total_price; private LinearLayout ll_content; private LinearLayout ll_cart; // 声明一个购物车列表的线性布局对象 private LinearLayout ll_empty; private GoodsDBHelper mGoodsHelper; // 声明一个商品数据库的帮助器对象 private CartDBHelper mCartHelper; // 声明一个购物车数据库的帮助器对象 @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("购物车"); tv_count = findViewById(R.id.tv_count); tv_total_price = findViewById(R.id.tv_total_price); ll_content = findViewById(R.id.ll_content); ll_cart = findViewById(R.id.ll_cart); ll_empty = findViewById(R.id.ll_empty); 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); } // 显示购物车图标中的商品数量 private void showCount() { tv_count.setText("" + MainApplication.goodsCount); if (MainApplication.goodsCount == 0) { ll_content.setVisibility(View.GONE); ll_cart.removeAllViews(); // 移除下面的所有子视图 mGoodsMap.clear(); ll_empty.setVisibility(View.VISIBLE); } else { ll_content.setVisibility(View.VISIBLE); ll_empty.setVisibility(View.GONE); } } @Override public void onClick(View v) { if (v.getId() == R.id.iv_back) { // 点击了返回图标 finish(); // 关闭当前页面 } else if (v.getId() == R.id.btn_shopping_channel) { // 点击了“商场”按钮 // 从购物车页面跳到商场页面 Intent intent = new Intent(this, ShoppingChannelActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // 设置启动标志 startActivity(intent); // 跳转到手机商场页面 } else if (v.getId() == R.id.btn_clear) { // 点击了“清空”按钮 mCartHelper.deleteAll(); // 清空购物车数据库 MainApplication.goodsCount = 0; showCount(); // 显示最新的商品数量 ToastUtil.show(this, "购物车已清空"); } else if (v.getId() == R.id.btn_settle) { // 点击了“结算”按钮 AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("结算商品"); builder.setMessage("客官抱歉,支付功能尚未开通,请下次再来"); builder.setPositiveButton("我知道了", null); builder.create().show(); // 显示提醒对话框 } } @Override protected void onResume() { super.onResume(); showCount(); // 显示购物车的商品数量 // 获取商品数据库的帮助器对象 mGoodsHelper = GoodsDBHelper.getInstance(this, 1); mGoodsHelper.openWriteLink(); // 打开商品数据库的写连接 // 获取购物车数据库的帮助器对象 mCartHelper = CartDBHelper.getInstance(this, 1); mCartHelper.openWriteLink(); // 打开购物车数据库的写连接 downloadGoods(); // 模拟从网络下载商品图片 showCart(); // 展示购物车中的商品列表 } @Override protected void onPause() { super.onPause(); mGoodsHelper.closeLink(); // 关闭商品数据库的数据库连接 mCartHelper.closeLink(); // 关闭购物车数据库的数据库连接 } // 声明一个购物车中的商品信息列表 private List<CartInfo> mCartArray = new ArrayList<CartInfo>(); // 声明一个根据商品编号查找商品信息的映射 private HashMap<Long, GoodsInfo> mGoodsMap = new HashMap<Long, GoodsInfo>(); private void deleteGoods(CartInfo info) { MainApplication.goodsCount -= info.count; // 从购物车的数据库中删除商品 mCartHelper.delete("goods_id=" + info.goods_id); // 从购物车的列表中删除商品 for (int i = 0; i < mCartArray.size(); i++) { if (info.goods_id == mCartArray.get(i).goods_id) { mCartArray.remove(i); break; } } showCount(); // 显示最新的商品数量 ToastUtil.show(this, "已从购物车删除" + mGoodsMap.get(info.goods_id).name); mGoodsMap.remove(info.goods_id); refreshTotalPrice(); // 刷新购物车中所有商品的总金额 } // 展示购物车中的商品列表 private void showCart() { ll_cart.removeAllViews(); // 移除下面的所有子视图 mCartArray = mCartHelper.query("1=1"); // 查询购物车数据库中所有的商品记录 Log.d(TAG, "mCartArray.size()=" + mCartArray.size()); if (mCartArray == null || mCartArray.size() <= 0) { return; } for (int i = 0; i < mCartArray.size(); i++) { final CartInfo info = mCartArray.get(i); // 根据商品编号查询商品数据库中的商品记录 final GoodsInfo goods = mGoodsHelper.queryById(info.goods_id); Log.d(TAG, "name=" + goods.name + ",price=" + goods.price + ",desc=" + goods.desc); mGoodsMap.put(info.goods_id, goods); // 获取布局文件item_goods.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); // 给商品行添加点击事件。点击商品行跳到商品的详情页 view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(ShoppingCartActivity.this, ShoppingDetailActivity.class); intent.putExtra("goods_id", info.goods_id); startActivity(intent); // 跳到商品详情页面 } }); // 给商品行添加长按事件。长按商品行就删除该商品 view.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(final View v) { AlertDialog.Builder builder = new AlertDialog.Builder(ShoppingCartActivity.this); builder.setMessage("是否从购物车删除"+goods.name+"?"); builder.setPositiveButton("是", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { ll_cart.removeView(v); // 移除当前视图 deleteGoods(info); // 删除该商品 } }); builder.setNegativeButton("否", null); builder.create().show(); // 显示提醒对话框 return true; } }); iv_thumb.setImageURI(Uri.parse(goods.pic_path)); // 设置商品图片 tv_name.setText(goods.name); // 设置商品名称 tv_desc.setText(goods.desc); // 设置商品描述 tv_count.setText("" + info.count); // 设置商品数量 tv_price.setText("" + (int)goods.price); // 设置商品单价 tv_sum.setText("" + (int)(info.count * goods.price)); // 设置商品总价 ll_cart.addView(view); // 往购物车列表添加该商品行 } refreshTotalPrice(); // 重新计算购物车中的商品总金额 } // 重新计算购物车中的商品总金额 private void refreshTotalPrice() { int total_price = 0; for (CartInfo info : mCartArray) { GoodsInfo goods = mGoodsMap.get(info.goods_id); total_price += goods.price * info.count; } tv_total_price.setText("" + total_price); } private String mFirst = "true"; // 是否首次打开 // 模拟网络数据,初始化数据库中的商品信息 private void downloadGoods() { // 获取共享参数保存的是否首次打开参数 mFirst = SharedUtil.getIntance(this).readString("first", "true"); // 获取当前App的私有下载路径 String path = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString() + "/"; if (mFirst.equals("true")) // 如果是首次打开 { ArrayList<GoodsInfo> goodsList = GoodsInfo.getDefaultList(); // 模拟网络图片下载 for (int i = 0; i < goodsList.size(); i++) { GoodsInfo info = goodsList.get(i); long rowid = mGoodsHelper.insert(info); // 往商品数据库插入一条该商品的记录 info.rowid = rowid; Bitmap pic = BitmapFactory.decodeResource(getResources(), info.pic); String pic_path = path + rowid + ".jpg"; FileUtil.saveImage(pic_path, pic); // 往存储卡保存商品图片 pic.recycle(); // 回收位图对象 info.pic_path = pic_path; mGoodsHelper.update(info); // 更新商品数据库中该商品记录的图片路径 } } // 把是否首次打开写入共享参数 SharedUtil.getIntance(this).writeString("first", "false"); } }
ShoppingChannelActivity布局:
<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" /> <ScrollView android:layout_width="match_parent" android:layout_height="wrap_content" > <GridLayout android:id="@+id/gl_channel" android:layout_width="match_parent" android:layout_height="wrap_content" android:columnCount="2" /> </ScrollView> </LinearLayout>
ShoppingChannelActivity代码:
package com.example.myapplication; import android.annotation.SuppressLint; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.widget.Button; import android.widget.GridLayout; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; import com.example.myapplication.bean.GoodsInfo; import com.example.myapplication.database.CartDBHelper; import com.example.myapplication.database.GoodsDBHelper; import com.example.myapplication.util.Utils; import java.util.List; @SuppressLint("SetTextI18n") public class ShoppingChannelActivity extends AppCompatActivity implements View.OnClickListener { private TextView tv_count; private GridLayout gl_channel; // 声明一个商品频道的网格布局对象 private GoodsDBHelper mGoodsHelper; // 声明一个商品数据库的帮助器对象 private CartDBHelper mCartHelper; // 声明一个购物车数据库的帮助器对象 @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); gl_channel = findViewById(R.id.gl_channel); findViewById(R.id.iv_back).setOnClickListener(this); findViewById(R.id.iv_cart).setOnClickListener(this); } @Override public void onClick(View v) { if (v.getId() == R.id.iv_back) // 点击了返回图标 { finish(); // 关闭当前页面 } else if (v.getId() == R.id.iv_cart) // 点击了购物车图标 { // 从商场页面跳到购物车页面 Intent intent = new Intent(this, ShoppingCartActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // 设置启动标志 startActivity(intent); // 跳转到购物车页面 } } // 把指定编号的商品添加到购物车 private void addToCart(long goods_id, String goods_name) { MainApplication.goodsCount++; tv_count.setText("" + MainApplication.goodsCount); mCartHelper.save(goods_id); // 把该商品填入购物车数据库 ToastUtil.show(this, "已添加一部" + goods_name + "到购物车"); } @Override protected void onResume() { super.onResume(); tv_count.setText("" + MainApplication.goodsCount); // 获取商品数据库的帮助器对象 mGoodsHelper = GoodsDBHelper.getInstance(this, 1); mGoodsHelper.openReadLink(); // 打开商品数据库的读连接 // 获取购物车数据库的帮助器对象 mCartHelper = CartDBHelper.getInstance(this, 1); mCartHelper.openWriteLink(); // 打开购物车数据库的写连接 showGoods(); // 展示商品列表 } @Override protected void onPause() { super.onPause(); mGoodsHelper.closeLink(); // 关闭商品数据库的数据库连接 mCartHelper.closeLink(); // 关闭购物车数据库的数据库连接 } private void showGoods() { int screenWidth = Utils.getScreenWidth(this); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(screenWidth/2, LinearLayout.LayoutParams.WRAP_CONTENT); gl_channel.removeAllViews(); // 移除下面的所有子视图 // 查询商品数据库中的所有商品记录 List<GoodsInfo> goodsArray = mGoodsHelper.query("1=1"); for (final GoodsInfo info : goodsArray) { // 获取布局文件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); tv_name.setText(info.name); // 设置商品名称 iv_thumb.setImageURI(Uri.parse(info.pic_path)); // 设置商品图片 iv_thumb.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(ShoppingChannelActivity.this, ShoppingDetailActivity.class); intent.putExtra("goods_id", info.rowid); startActivity(intent); // 跳到商品详情页面 } }); tv_price.setText("" + (int)info.price); // 设置商品价格 btn_add.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { addToCart(info.rowid, info.name); // 添加到购物车 } }); gl_channel.addView(view, params); // 把商品视图添加到网格布局 } } }
ShoppingDetailActivity布局:
<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" /> <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" /> <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" /> <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" /> <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>
代码:
package com.example.myapplication; import android.annotation.SuppressLint; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import com.example.myapplication.bean.GoodsInfo; import com.example.myapplication.database.CartDBHelper; import com.example.myapplication.database.GoodsDBHelper; @SuppressLint("SetTextI18n") 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 long mGoodsId; // 当前商品的商品编号 private GoodsDBHelper mGoodsHelper; // 声明一个商品数据库的帮助器对象 private CartDBHelper mCartHelper; // 声明一个购物车数据库的帮助器对象 @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("" + MainApplication.goodsCount); } @Override public void onClick(View v) { if (v.getId() == R.id.iv_back) // 点击了返回图标 { finish(); // 关闭当前页面 } else if (v.getId() == R.id.iv_cart) // 点击了购物车图标 { Intent intent = new Intent(this, ShoppingCartActivity.class); startActivity(intent); // 跳转到购物车页面 } else if (v.getId() == R.id.btn_add_cart) // 点击了“添加”按钮 { addToCart(mGoodsId); // 把该商品添加到购物车 } } // 把指定编号的商品添加到购物车 private void addToCart(long goods_id) { MainApplication.goodsCount++; tv_count.setText("" + MainApplication.goodsCount); mCartHelper.save(goods_id); // 把该商品填入购物车数据库 ToastUtil.show(this, "成功添加至购物车"); } @Override protected void onResume() { super.onResume(); // 获取商品数据库的帮助器对象 mGoodsHelper = GoodsDBHelper.getInstance(this, 1); mGoodsHelper.openReadLink(); // 打开商品数据库的读连接 // 获取购物车数据库的帮助器对象 mCartHelper = CartDBHelper.getInstance(this, 1); mCartHelper.openWriteLink(); // 打开购物车数据库的写连接 showDetail(); // 展示商品详情 } @Override protected void onPause() { super.onPause(); mGoodsHelper.closeLink(); // 关闭商品数据库的数据库连接 mCartHelper.closeLink(); // 关闭购物车数据库的数据库连接 } private void showDetail() { // 获取上一个页面传来的商品编号 mGoodsId = getIntent().getLongExtra("goods_id", 0L); if (mGoodsId > 0) { // 根据商品编号查询商品数据库中的商品记录 GoodsInfo info = mGoodsHelper.queryById(mGoodsId); tv_title.setText(info.name); // 设置商品名称 tv_goods_desc.setText(info.desc); // 设置商品描述 tv_goods_price.setText("" + (int)info.price); // 设置商品价格 iv_goods_pic.setImageURI(Uri.parse(info.pic_path)); // 设置商品图片 } } }
CartInfo
package com.example.myapplication.bean; //购物车信息 public class CartInfo { public long rowid; // 行号 public int xuhao; // 序号 public long goods_id; // 商品编号 public int count; // 商品数量 public String update_time; // 更新时间 public CartInfo() { rowid = 0L; xuhao = 0; goods_id = 0L; count = 0; update_time = ""; } }
GoodsInfo
package com.example.myapplication.bean; import com.example.myapplication.R; import java.util.ArrayList; public class GoodsInfo { public long rowid; // 行号 public int xuhao; // 序号 public String name; // 名称 public String desc; // 描述 public float price; // 价格 public String pic_path; // 大图的保存路径 public int pic; // 大图的资源编号 public GoodsInfo() { rowid = 0L; xuhao = 0; name = ""; desc = ""; price = 0; pic_path = ""; pic = 0; } // 声明一个手机商品的名称数组 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.name = mNameArray[i]; info.desc = mDescArray[i]; info.price = mPriceArray[i]; info.pic = mPicArray[i]; goodsList.add(info); } return goodsList; } }
CartDBHelper
package com.example.myapplication.database; import android.annotation.SuppressLint; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; import com.example.myapplication.DateUtil; import com.example.myapplication.bean.CartInfo; import java.util.ArrayList; import java.util.List; @SuppressLint("DefaultLocale") public class CartDBHelper extends SQLiteOpenHelper { private static final String TAG = "CartDBHelper"; private static final String DB_NAME = "cart.db"; // 数据库的名称 private static final int DB_VERSION = 1; // 数据库的版本号 private static CartDBHelper mHelper = null; // 数据库帮助器的实例 private SQLiteDatabase mDB = null; // 数据库的实例 private static final String TABLE_NAME = "cart_info"; // 表的名称 private CartDBHelper(Context context) { super(context, DB_NAME, null, DB_VERSION); } private CartDBHelper(Context context, int version) { super(context, DB_NAME, null, version); } // 利用单例模式获取数据库帮助器的唯一实例 public static CartDBHelper getInstance(Context context, int version) { if (version > 0 && mHelper == null) { mHelper = new CartDBHelper(context, version); } else if (mHelper == null) { mHelper = new CartDBHelper(context); } return mHelper; } // 打开数据库的读连接 public SQLiteDatabase openReadLink() { if (mDB == null || !mDB.isOpen()) { mDB = mHelper.getReadableDatabase(); } return mDB; } // 打开数据库的写连接 public SQLiteDatabase openWriteLink() { if (mDB == null || !mDB.isOpen()) { mDB = mHelper.getWritableDatabase(); } return mDB; } // 关闭数据库连接 public void closeLink() { if (mDB != null && mDB.isOpen()) { mDB.close(); mDB = null; } } // 创建数据库,执行建表语句 @Override public void onCreate(SQLiteDatabase db) { Log.d(TAG, "onCreate"); String drop_sql = "DROP TABLE IF EXISTS " + TABLE_NAME + ";"; Log.d(TAG, "drop_sql:" + drop_sql); db.execSQL(drop_sql); String create_sql = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" + "_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," + "goods_id INTEGER NOT NULL," + "count INTEGER NOT NULL," + "update_time VARCHAR NOT NULL" + ");"; Log.d(TAG, "create_sql:" + create_sql); db.execSQL(create_sql); // 执行完整的SQL语句 } // 修改数据库,执行表结构变更语句 @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } // 根据指定条件删除表记录 public int delete(String condition) { // 执行删除记录动作,该语句返回删除记录的数目 return mDB.delete(TABLE_NAME, condition, null); } // 删除该表的所有记录 public int deleteAll() { // 执行删除记录动作,该语句返回删除记录的数目 return mDB.delete(TABLE_NAME, "1=1", null); } // 往该表添加一条记录 public long insert(CartInfo info) { List<CartInfo> infoList = new ArrayList<CartInfo>(); infoList.add(info); return insert(infoList); } // 往该表添加多条记录 public long insert(List<CartInfo> infoList) { long result = -1; for (CartInfo info : infoList) { Log.d(TAG, "goods_id=" + info.goods_id + ", count=" + info.count); // 如果存在相同rowid的记录,则更新记录 if (info.rowid > 0) { String condition = String.format("rowid='%d'", info.rowid); update(info, condition); result = info.rowid; continue; } // 不存在唯一性重复的记录,则插入新记录 ContentValues cv = new ContentValues(); cv.put("goods_id", info.goods_id); cv.put("count", info.count); cv.put("update_time", info.update_time); // 执行插入记录动作,该语句返回插入记录的行号 result = mDB.insert(TABLE_NAME, "", cv); if (result == -1) { // 添加成功则返回行号,添加失败则返回-1 return result; } } return result; } // 根据条件更新指定的表记录 public int update(CartInfo info, String condition) { ContentValues cv = new ContentValues(); cv.put("goods_id", info.goods_id); cv.put("count", info.count); cv.put("update_time", info.update_time); // 执行更新记录动作,该语句返回更新的记录数量 return mDB.update(TABLE_NAME, cv, condition, null); } public int update(CartInfo info) { // 执行更新记录动作,该语句返回更新的记录数量 return update(info, "rowid=" + info.rowid); } public void save(long goods_id) { CartInfo info = queryByGoodsId(goods_id); if (info == null) { // 不存在该商品,则插入一条记录 info = new CartInfo(); info.goods_id = goods_id; info.count = 1; info.update_time = DateUtil.getNowDateTime(""); insert(info); // 往购物车数据库中添加一条新的商品记录 } else { // 已存在该商品,则更新原记录 info.count++; // 该商品的数量加一 info.update_time = DateUtil.getNowDateTime(""); update(info); // 更新购物车数据库中的商品记录信息 } } // 根据指定条件查询记录,并返回结果数据列表 public List<CartInfo> query(String condition) { String sql = String.format("select rowid,_id,goods_id,count,update_time" + " from %s where %s;", TABLE_NAME, condition); Log.d(TAG, "query sql: " + sql); List<CartInfo> infoList = new ArrayList<CartInfo>(); // 执行记录查询动作,该语句返回结果集的游标 Cursor cursor = mDB.rawQuery(sql, null); // 循环取出游标指向的每条记录 while (cursor.moveToNext()) { CartInfo info = new CartInfo(); info.rowid = cursor.getLong(0); info.xuhao = cursor.getInt(1); info.goods_id = cursor.getLong(2); info.count = cursor.getInt(3); info.update_time = cursor.getString(4); infoList.add(info); } cursor.close(); // 查询完毕,关闭数据库游标 return infoList; } // 根据行号查询指定记录 public CartInfo queryById(long rowid) { CartInfo info = null; List<CartInfo> infoList = query(String.format("rowid='%d'", rowid)); if (infoList.size() > 0) { info = infoList.get(0); } return info; } // 根据商品编号查询指定记录 public CartInfo queryByGoodsId(long goods_id) { CartInfo info = null; List<CartInfo> infoList = query(String.format("goods_id='%d'", goods_id)); if (infoList.size() > 0) { info = infoList.get(0); } return info; } public int queryCount() { int count = 0; String sql = String.format("select sum(count) from %s;", TABLE_NAME); // 执行记录查询动作,该语句返回结果集的游标 Cursor cursor = mDB.rawQuery(sql, null); // 循环取出游标指向的每条记录 while (cursor.moveToNext()) { count = cursor.getInt(0); } Log.d(TAG, "count="+count); return count; } }
GoodsDBHelper
package com.example.myapplication.database; import android.annotation.SuppressLint; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; import com.example.myapplication.bean.GoodsInfo; import java.util.ArrayList; import java.util.List; @SuppressLint("DefaultLocale") public class GoodsDBHelper extends SQLiteOpenHelper { private static final String TAG = "GoodsDBHelper"; private static final String DB_NAME = "goods.db"; // 数据库的名称 private static final int DB_VERSION = 1; // 数据库的版本号 private static GoodsDBHelper mHelper = null; // 数据库帮助器的实例 private SQLiteDatabase mDB = null; // 数据库的实例 private static final String TABLE_NAME = "goods_info"; // 表的名称 private GoodsDBHelper(Context context) { super(context, DB_NAME, null, DB_VERSION); } private GoodsDBHelper(Context context, int version) { super(context, DB_NAME, null, version); } // 利用单例模式获取数据库帮助器的唯一实例 public static GoodsDBHelper getInstance(Context context, int version) { if (version > 0 && mHelper == null) { mHelper = new GoodsDBHelper(context, version); } else if (mHelper == null) { mHelper = new GoodsDBHelper(context); } return mHelper; } // 打开数据库的读连接 public SQLiteDatabase openReadLink() { if (mDB == null || !mDB.isOpen()) { mDB = mHelper.getReadableDatabase(); } return mDB; } // 打开数据库的写连接 public SQLiteDatabase openWriteLink() { if (mDB == null || !mDB.isOpen()) { mDB = mHelper.getWritableDatabase(); } return mDB; } // 关闭数据库连接 public void closeLink() { if (mDB != null && mDB.isOpen()) { mDB.close(); mDB = null; } } // 创建数据库,执行建表语句 @Override public void onCreate(SQLiteDatabase db) { Log.d(TAG, "onCreate"); String drop_sql = "DROP TABLE IF EXISTS " + TABLE_NAME + ";"; Log.d(TAG, "drop_sql:" + drop_sql); db.execSQL(drop_sql); String create_sql = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" + "_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," + "name VARCHAR NOT NULL," + "desc VARCHAR NOT NULL," + "price FLOAT NOT NULL," + "pic_path VARCHAR NOT NULL" + ");"; Log.d(TAG, "create_sql:" + create_sql); db.execSQL(create_sql); // 执行完整的SQL语句 } // 修改数据库,执行表结构变更语句 @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } // 根据指定条件删除表记录 public int delete(String condition) { // 执行删除记录动作,该语句返回删除记录的数目 return mDB.delete(TABLE_NAME, condition, null); } // 删除该表的所有记录 public int deleteAll() { // 执行删除记录动作,该语句返回删除记录的数目 return mDB.delete(TABLE_NAME, "1=1", null); } // 往该表添加一条记录 public long insert(GoodsInfo info) { List<GoodsInfo> infoList = new ArrayList<GoodsInfo>(); infoList.add(info); return insert(infoList); } // 往该表添加多条记录 public long insert(List<GoodsInfo> infoList) { long result = -1; for (GoodsInfo info : infoList) { // 如果存在相同rowid的记录,则更新记录 if (info.rowid > 0) { String condition = String.format("rowid='%d'", info.rowid); update(info, condition); result = info.rowid; continue; } // 不存在唯一性重复的记录,则插入新记录 ContentValues cv = new ContentValues(); cv.put("name", info.name); cv.put("desc", info.desc); cv.put("price", info.price); cv.put("pic_path", info.pic_path); // 执行插入记录动作,该语句返回插入记录的行号 result = mDB.insert(TABLE_NAME, "", cv); if (result == -1) { // 添加成功则返回行号,添加失败则返回-1 return result; } } return result; } // 根据条件更新指定的表记录 public int update(GoodsInfo info, String condition) { ContentValues cv = new ContentValues(); cv.put("name", info.name); cv.put("desc", info.desc); cv.put("price", info.price); cv.put("pic_path", info.pic_path); // 执行更新记录动作,该语句返回更新的记录数量 return mDB.update(TABLE_NAME, cv, condition, null); } public int update(GoodsInfo info) { // 执行更新记录动作,该语句返回更新的记录数量 return update(info, "rowid=" + info.rowid); } // 根据指定条件查询记录,并返回结果数据列表 public List<GoodsInfo> query(String condition) { String sql = String.format("select rowid,_id,name,desc,price,pic_path" + " from %s where %s;", TABLE_NAME, condition); Log.d(TAG, "query sql: " + sql); List<GoodsInfo> infoList = new ArrayList<GoodsInfo>(); // 执行记录查询动作,该语句返回结果集的游标 Cursor cursor = mDB.rawQuery(sql, null); // 循环取出游标指向的每条记录 while (cursor.moveToNext()) { GoodsInfo info = new GoodsInfo(); info.rowid = cursor.getLong(0); info.xuhao = cursor.getInt(1); info.name = cursor.getString(2); info.desc = cursor.getString(3); info.price = cursor.getFloat(4); info.pic_path = cursor.getString(5); infoList.add(info); } cursor.close(); // 查询完毕,关闭数据库游标 return infoList; } // 根据行号查询指定记录 public GoodsInfo queryById(long rowid) { GoodsInfo info = null; List<GoodsInfo> infoList = query(String.format("rowid='%d'", rowid)); if (infoList.size() > 0) { info = infoList.get(0); } return info; } }
MainApplication
package com.example.myapplication; import android.app.Application; import android.util.Log; import androidx.room.Room; import com.example.myapplication.database.BookDatabase; import com.example.myapplication.database.CartDBHelper; import java.util.HashMap; public class MainApplication extends Application { private final static String TAG = "MainApplication"; private static MainApplication mApp; // 声明一个当前应用的静态实例 // 声明一个公共的信息映射对象,可当作全局变量使用 public HashMap<String, String> infoMap = new HashMap<String, String>(); public static int goodsCount = 0; private BookDatabase bookDatabase; // 声明一个书籍数据库对象 // 利用单例模式获取当前应用的唯一实例 public static MainApplication getInstance() { return mApp; } @Override public void onCreate() { super.onCreate(); Log.d(TAG, "onCreate"); mApp = this; // 在打开应用时对静态的应用实例赋值 // 获取购物车数据库的帮助器对象 CartDBHelper cartHelper = CartDBHelper.getInstance(this, 1); cartHelper.openReadLink(); // 打开购物车数据库的读连接 goodsCount = cartHelper.queryCount(); // 查询购物车里面的商品数量 cartHelper.closeLink(); // 关闭购物车数据库的读连接 // 构建书籍数据库的实例 bookDatabase = Room.databaseBuilder(mApp, BookDatabase.class,"BookInfo") .addMigrations() // 允许迁移数据库(发生数据库变更时,Room默认删除原数据库再创建新数据库。如此一来原来的记录会丢失,故而要改为迁移方式以便保存原有记录) .allowMainThreadQueries() // 允许在主线程中操作数据库(Room默认不能在主线程中操作数据库) .build(); } // 获取书籍数据库的实例 public BookDatabase getBookDB() { return bookDatabase; } }
DateUtil
package com.example.myapplication.util; import android.annotation.SuppressLint; import android.text.TextUtils; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; @SuppressLint("SimpleDateFormat") public class DateUtil { // 获取当前的日期时间 public static String getNowDateTime(String formatStr) { String format = formatStr; if (TextUtils.isEmpty(format)) { format = "yyyyMMddHHmmss"; } SimpleDateFormat sdf = new SimpleDateFormat(format); return sdf.format(new Date()); } // 获取当前的时间 public static String getNowTime() { SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); return sdf.format(new Date()); } // 获取当前的时间(精确到毫秒) public static String getNowTimeDetail() { SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS"); return sdf.format(new Date()); } }
FileUtil
package com.example.myapplication.util; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FilenameFilter; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Locale; public class FileUtil { // 把字符串保存到指定路径的文本文件 public static void saveText(String path, String txt) { // 根据指定的文件路径构建文件输出流对象 try (FileOutputStream fos = new FileOutputStream(path)) { fos.write(txt.getBytes()); // 把字符串写入文件输出流 } catch (Exception e) { e.printStackTrace(); } } // 从指定路径的文本文件中读取内容字符串 public static String openText(String path) { String readStr = ""; // 根据指定的文件路径构建文件输入流对象 try (FileInputStream fis = new FileInputStream(path)) { byte[] b = new byte[fis.available()]; fis.read(b); // 从文件输入流读取字节数组 readStr = new String(b); // 把字节数组转换为字符串 } catch (Exception e) { e.printStackTrace(); } return readStr; // 返回文本文件中的文本字符串 } // 把位图数据保存到指定路径的图片文件 public static void saveImage(String path, Bitmap bitmap) { // 根据指定的文件路径构建文件输出流对象 try (FileOutputStream fos = new FileOutputStream(path)) { // 把位图数据压缩到文件输出流中 bitmap.compress(Bitmap.CompressFormat.JPEG, 80, fos); } catch (Exception e) { e.printStackTrace(); } } // 从指定路径的图片文件中读取位图数据 public static Bitmap openImage(String path) { Bitmap bitmap = null; // 声明一个位图对象 // 根据指定的文件路径构建文件输入流对象 try (FileInputStream fis = new FileInputStream(path)) { bitmap = BitmapFactory.decodeStream(fis); // 从文件输入流中解码位图数据 } catch (Exception e) { e.printStackTrace(); } return bitmap; // 返回图片文件中的位图数据 } public static List<File> getFileList(String path, String[] extendArray) { List<File> displayedContent = new ArrayList<File>(); File[] files = null; File directory = new File(path); if (extendArray != null && extendArray.length > 0) { FilenameFilter fileFilter = getTypeFilter(extendArray); files = directory.listFiles(fileFilter); } else { files = directory.listFiles(); } if (files != null) { for (File f : files) { if (!f.isDirectory() && !f.isHidden()) { displayedContent.add(f); } } } // 按照最后修改时间排序 Collections.sort(displayedContent, new Comparator<File>() { @Override public int compare(File o1, File o2) { return (o1.lastModified() > o2.lastModified()) ? -1 : 1; } }); return displayedContent; } public static FilenameFilter getTypeFilter(String[] extendArray) { final ArrayList<String> fileExtensions = new ArrayList<String>(); for (int i = 0; i < extendArray.length; i++) { fileExtensions.add(extendArray[i]); } FilenameFilter fileNameFilter = new FilenameFilter() { @Override public boolean accept(File directory, String fileName) { boolean matched = false; File f = new File(String.format("%s/%s", directory.getAbsolutePath(), fileName)); matched = f.isDirectory(); if (!matched) { for (String s : fileExtensions) { s = String.format(".{0,}\\%s$", s); s = s.toUpperCase(Locale.getDefault()); fileName = fileName.toUpperCase(Locale.getDefault()); matched = fileName.matches(s); if (matched) { break; } } } return matched; } }; return fileNameFilter; } }
SharedUtil
package com.example.myapplication.util; import android.content.Context; import android.content.SharedPreferences; // 这是共享参数的工具类,统一对共享参数的读写操作 public class SharedUtil { private static SharedUtil mUtil; // 声明一个共享参数工具类的实例 private static SharedPreferences mShared; // 声明一个共享参数的实例 // 通过单例模式获取共享参数工具类的唯一实例 public static SharedUtil getIntance(Context ctx) { if (mUtil == null) { mUtil = new SharedUtil(); } // 从cart.xml中获取共享参数对象 mShared = ctx.getSharedPreferences("cart", Context.MODE_PRIVATE); return mUtil; } // 把键名与字符串的配对信息写入共享参数 public void writeString(String key, String value) { SharedPreferences.Editor editor = mShared.edit(); // 获得编辑器的对象 editor.putString(key, value); // 添加一个指定键名的字符串参数 editor.commit(); // 提交编辑器中的修改 } // 根据键名到共享参数中查找对应的字符串对象 public String readString(String key, String defaultValue) { return mShared.getString(key, defaultValue); } // 把键名与整型数的配对信息写入共享参数 public void writeInt(String key, int value) { SharedPreferences.Editor editor = mShared.edit(); // 获得编辑器的对象 editor.putInt(key, value); // 添加一个指定键名的整型数参数 editor.commit(); // 提交编辑器中的修改 } // 根据键名到共享参数中查找对应的整型数对象 public int readInt(String key, int defaultValue) { return mShared.getInt(key, defaultValue); } }
ToastUtil
package com.example.myapplication.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(); } }
Utils
package com.example.myapplication.util; import android.content.Context; public class Utils { // 根据手机的分辨率从 dp 的单位 转成为 px(像素) public static int dip2px(Context context, float dpValue) { // 获取当前手机的像素密度(1个dp对应几个px) float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); // 四舍五入取整 } // 根据手机的分辨率从 px(像素) 的单位 转成为 dp public static int px2dip(Context context, float pxValue) { // 获取当前手机的像素密度(1个dp对应几个px) float scale = context.getResources().getDisplayMetrics().density; return (int) (pxValue / scale + 0.5f); // 四舍五入取整 } // 获得屏幕的宽度 public static int getScreenWidth(Context ctx) { return ctx.getResources().getDisplayMetrics().widthPixels; // int screenWidth; // // 从系统服务中获取窗口管理器 // WindowManager wm = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE); // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { // // 获取当前屏幕的四周边界 // Rect rect = wm.getCurrentWindowMetrics().getBounds(); // screenWidth = rect.width(); // } else { // DisplayMetrics dm = new DisplayMetrics(); // // 从默认显示器中获取显示参数保存到dm对象中 // wm.getDefaultDisplay().getMetrics(dm); // screenWidth = dm.widthPixels; // } // return screenWidth; // 返回屏幕的宽度数值 } // 获得屏幕的高度 public static int getScreenHeight(Context ctx) { return ctx.getResources().getDisplayMetrics().heightPixels; // int screenHeight; // // 从系统服务中获取窗口管理器 // WindowManager wm = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE); // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { // // 获取当前屏幕的四周边界 // Rect rect = wm.getCurrentWindowMetrics().getBounds(); // screenHeight = rect.height(); // } else { // DisplayMetrics dm = new DisplayMetrics(); // // 从默认显示器中获取显示参数保存到dm对象中 // wm.getDefaultDisplay().getMetrics(dm); // screenHeight = dm.heightPixels; // } // return screenHeight; // 返回屏幕的高度数值 } }
ViewUtil
package com.example.myapplication.util; import android.app.Activity; import android.content.Context; import android.view.View; import android.view.inputmethod.InputMethodManager; public class ViewUtil { public static void hideAllInputMethod(Activity act) { // 从系统服务中获取输入法管理器 InputMethodManager imm = (InputMethodManager) act.getSystemService(Context.INPUT_METHOD_SERVICE); if (imm.isActive()) { // 软键盘如果已经打开则关闭之 imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS); } } public static void hideOneInputMethod(Activity act, View v) { // 从系统服务中获取输入法管理器 InputMethodManager imm = (InputMethodManager) act.getSystemService(Context.INPUT_METHOD_SERVICE); // 关闭屏幕上的输入法软键盘 imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } }
第一个页面: ShoppingCartActivity
点击:逛逛手机商场
点击清空:
=======================================================================================================================