1. 项目结构
2. 资源和配置
2.1 图片和布局文件
2.1.1 图片资源
2.1.2 布局文件
2.2 模块gradle配置
Room依赖
dependencies {
implementation 'androidx.room:room-runtime:2.2.1'
annotationProcessor 'androidx.room:room-runtime:2.2.1'
}
2.3 清单文件配置(AndroidManifest.xml)
2.3.1 配置文件读写权限
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
</manifest>
2.3.2 Application配置自己的.MyApplication
<application
android:name=".MyApplication"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:requestLegacyExternalStorage="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MyApplication"
tools:targetApi="31">
</application>
2.3.3启动Activity配置
<activity
android:name=".activities.ShoppingChannelActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
2.3.3其它Activity配置
<activity
android:name=".activities.ShoppingDetailActivity"
android:exported="false">
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
<activity
android:name=".activities.ShoppingCartActivity"
android:exported="false">
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
2.4 界面主题配置
2.5 常量配置
颜色常量
3. 代码
3.1 Activity代码
(1)购物车,ShoppingCartActivity.java
public class ShoppingCartActivity extends AppCompatActivity implements View.OnClickListener {
private TextView tv_count;
private ShoppingDBHelper mDBHelper;
private LinearLayout ll_cart;
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);
TextView tv_title = findViewById(R.id.tv_title);
tv_title.setText("购物车");
findViewById(R.id.iv_back).setOnClickListener(this);
findViewById(R.id.btn_clear).setOnClickListener(this);
findViewById(R.id.btn_settle).setOnClickListener(this);
findViewById(R.id.btn_shopping_channel).setOnClickListener(this);
ll_empty = findViewById(R.id.ll_empty);
ll_content = findViewById(R.id.ll_content);
ll_cart = findViewById(R.id.ll_cart);
tv_count = findViewById(R.id.tv_count);
tv_count.setText(String.valueOf(MyApplication.getInstance().goodsCount));
tv_total_price = findViewById(R.id.tv_total_price);
mDBHelper = ShoppingDBHelper.getInstance(this);
}
@Override
protected void onResume() {
super.onResume();
showCart();
}
private void showCart() {
ll_cart.removeAllViews();
mCartList = mDBHelper.queryAllCartInfo();
if (mCartList.size() == 0) {
showCount();
return;
}
for (CartInfo info : mCartList) {
GoodsInfo goods = mDBHelper.queryGoodsInfoById(info.goodsId);
mGoodsMap.put(info.goodsId, goods);
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();
}
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.deteteAllCartInfo();
MyApplication.getInstance().goodsCount = 0;
showCount();
ToastUtil.show(this, "购物车已清空");
break;
case R.id.btn_settle:
Log.d(null,"-----------------------撒非得---------------------");
AlertDialog.Builder builder = new AlertDialog.Builder(ShoppingCartActivity.this);
builder.setTitle("结算商品");
builder.setMessage("客观抱歉,支付功能尚未开通,请下次再来");
builder.setPositiveButton("我知道了", null);
builder.create().show();
break;
}
}
}
(2)手机商城,ShoppingChannelActivity.java
public class ShoppingChannelActivity extends AppCompatActivity implements View.OnClickListener {
private ShoppingDBHelper mDBHelper;
private TextView tv_title;
private TextView tv_count;
private GridLayout gl_channel;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_shopping_channel);
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);
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() {
int screenWidth = getResources().getDisplayMetrics().widthPixels;
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
screenWidth / 2, LinearLayout.LayoutParams.WRAP_CONTENT);
gl_channel.removeAllViews();
List<GoodsInfo> list = mDBHelper.queryGoodsInfo();
for (GoodsInfo info : list) {
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 -> {
addToChart(info.id, info.name);
});
view.setOnClickListener(v -> {
Intent intent = new Intent(ShoppingChannelActivity.this, ShoppingDetailActivity.class);
intent.putExtra("goods_id", info.id);
startActivity(intent);
});
gl_channel.addView(view, params);
}
}
private void addToChart(int goodsId, String goodsName) {
int count = ++MyApplication.getInstance().goodsCount;
tv_count.setText(String.valueOf(count));
mDBHelper.insertChartInfo(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;
}
}
}
(3)商品详情,ShoppingChannelActivity.java
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);
iv_goods_pic = findViewById(R.id.iv_goods_pic);
tv_goods_desc = findViewById(R.id.tv_goods_desc);
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) {
int count = ++MyApplication.getInstance().goodsCount;
tv_count.setText(String.valueOf(count));
mDBHelper.insertChartInfo(goodsId);
ToastUtil.show(this, "成功添加至购物车");
}
}
3.2 数据库代码
ShoppingDBHelper.java
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;
private SQLiteDatabase mWDB;
public ShoppingDBHelper(@Nullable Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
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 sqLiteDatabase, int i, int i1) {
}
public List<GoodsInfo> queryGoodsInfo(){
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 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 void closeLink() {
if (mRDB != null && mRDB.isOpen()) {
mRDB.close();
mRDB = null;
}
if (mWDB != null && mWDB.isOpen()) {
mWDB.close();
mWDB = null;
}
}
public SQLiteDatabase openWriteLink() {
if (mWDB == null || !mWDB.isOpen()) {
mWDB = mHelper.getWritableDatabase();
}
return mWDB;
}
public SQLiteDatabase openReadLink() {
if (mRDB == null || !mRDB.isOpen()) {
mRDB = mHelper.getReadableDatabase();
}
return mRDB;
}
public void insertChartInfo(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> queryAllCartInfo() {
List<CartInfo> list = new ArrayList<>();
Cursor cursor = mRDB.query(TABLE_CART_INFO, null, 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;
}
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;
}
public void deleteCartInfoByGoodsId(int goodsId) {
mWDB.delete(TABLE_CART_INFO, "goods_id=?", new String[]{String.valueOf(goodsId)});
}
public void deteteAllCartInfo(){
mWDB.delete(TABLE_CART_INFO, "1=1",null);
// mWDB.delete(TABLE_CART_INFO, null,null);
}
}
3.3 实体类
CartInfo .java
package com.example.myapplication.entity;
public class CartInfo {
public int id;
public int goodsId;
public int count;
public CartInfo() {}
}
GoodsInfo .java
public class GoodsInfo {
public int id;
public String name;
public String description;
public float price;
public String picPath;
public int pic;
public GoodsInfo(int id, String name, String description, float price, String picPath, int pic) {
this.id = id;
this.name = name;
this.description = description;
this.price = price;
this.picPath = picPath;
this.pic = 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};
public static int[] mPicArray = {
R.drawable.xiaomi, R.drawable.img2,
R.drawable.img3, R.drawable.img4,
R.drawable.img5, R.drawable.img6,
};
public GoodsInfo() {
}
public static ArrayList<GoodsInfo> getDefaultList() {
ArrayList<GoodsInfo> goodsList = new ArrayList<>();
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;
}
}
3.4 Util 工具类
FileUtil .java
package com.example.myapplication.util;
import android.graphics.Bitmap;
import java.io.FileOutputStream;
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.PNG, 100, fos);
}catch (Exception e) {
e.printStackTrace();
}finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
SharedUtil .java
package com.example.myapplication.util;
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);
}
}
ToastUtil .java
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();
}
}
3.5 MyApplication.java
public class MyApplication extends Application {
public static MyApplication mApp;
public HashMap<String, String> infoMap = new HashMap<>();
public static MyApplication getInstance() {
return mApp;
}
public int goodsCount;
private void initGoodsInfo(){
boolean isFirst = SharedUtil.getInstance(this).readBoolean("first", true);
String directory = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString() + File.separator;
if (isFirst) {
List<GoodsInfo> list = GoodsInfo.getDefaultList();
for (GoodsInfo info : list) {
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), info.pic);
String path = directory + info.id + ".png";
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);
}
}
@Override
public void onCreate() {
super.onCreate();
mApp = this;
initGoodsInfo();
}
@Override
public void onTerminate() {
super.onTerminate();
Log.d("HKHL", "MyApplication onTerminate");
}
@Override
public void onConfigurationChanged(@NonNull Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.d("HKHL", "MyApplication onConfigurationChanged");
}
}
3.6 布局代码
activity_shopping.xml
<?xml version="1.0" encoding="utf-8"?>
<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="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:textSize="15sp"
android:textColor="@color/black"
android:text="图片"
>
</TextView>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:gravity="center"
android:textSize="15sp"
android:textColor="@color/black"
android:text="名称"
>
</TextView>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="15sp"
android:textColor="@color/black"
android:gravity="center"
android:text="数量"
>
</TextView>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="15sp"
android:textColor="@color/black"
android:gravity="center"
android:text="单价"
>
</TextView>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="15sp"
android:textColor="@color/black"
android:gravity="center"
android:text="总价"
>
</TextView>
</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="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="15sp"
android:text="清空"
>
</Button>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:textColor="@color/black"
android:textSize="15sp"
android:text="总金额:"
>
</TextView>
<TextView
android:id="@+id/tv_total_price"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:textColor="@color/red"
android:textSize="17sp"
>
</TextView>
<Button
android:id="@+id/btn_settle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="17sp"
android:text="结算"
>
</Button>
</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_marginTop="100dp"
android:layout_marginBottom="100dp"
android:gravity="center"
android:textSize="17sp"
android:text="哎呀,购物车空空如也,快去选购商品吧">
</TextView>
<Button
android:id="@+id/btn_shopping_channel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="17sp"
android:layout_gravity="center"
android:text="逛逛手机商场"
>
</Button>
</LinearLayout>
</RelativeLayout>
</ScrollView>
</LinearLayout>
\
activity_shopping_channel.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"
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"
>
</GridLayout>
</ScrollView>
</LinearLayout>
activity_shopping_detail.xml
<?xml version="1.0" encoding="utf-8"?>
<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/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"
android: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"
android:text="1990" />
<TextView
android:id="@+id/tv_goods_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:textSize="15sp"
android:textColor="@color/black"
android: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>
item_cart.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="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"
android: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"
android: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"
android: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"
android: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"
android: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"
android:text="2000"
/>
</LinearLayout>
item_goods.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
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"
android:text="小米手机"
></TextView>
<ImageView
android:id="@+id/iv_thumb"
android:layout_width="180dp"
android:layout_height="150dp"
android:scaleType="fitCenter"
android:src="@drawable/xiaomi"
>
</ImageView>
<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"
android:text="20"
></TextView>
<Button
android:id="@+id/btn_add"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"
android:gravity="center"
android:textColor="@color/black"
android:textSize="15sp"
android:text="加入购物车"
>
</Button>
</LinearLayout>
</LinearLayout>
title_shopping.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:background="#aaaaff"
android:layout_height="50dp">
<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"
>
</ImageView>
<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/ic_cart"
>
</ImageView>
<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"
android:text="">
</TextView>
<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">
</TextView>
</RelativeLayout>
4. 结果演示