一、为什么要写这个项目大二下学期《Android基础及应用》课程设计我选择实现一个完整的购物商城App。原因很简单购物流程涵盖了移动开发中最核心的组件列表、数据库、异步、交互做完一个购物App等于把Android大半本教材都实践了一遍。项目前后开发约两周实际写代码不到一周其余时间在踩坑和优化最终实现了用户注册登录 → 商品浏览 → 搜索 → 购物车 → 订单生成 → 个人中心订单/收藏 的全套流程。代码结构清晰技术栈较新适合初学者学习完整项目的开发思路。二、项目展示截图略图1 登录界面图2 商品列表含自动轮播Banner 实时搜索图3 商品详情加购、收藏图4 购物车数量增减、删除、总价图5 订单确认模拟支付图6 个人中心订单记录 收藏列表三、技术栈选型分类 技术 说明语言 Kotlin 空安全、协程支持、简洁UI ConstraintLayout、LinearLayout、RecyclerView、CardView、ViewPager2 常用组件图片加载 Glide 网络图片 占位图 缓存数据库 RoomSQLite 用户、订单、收藏存储异步 Kotlin Coroutines 避免主线程阻塞状态管理 单例模式CartManager、GlobalState 购物车与用户状态最低SDK API 21 覆盖95%设备测试设备 Pixel 4 模拟器API33 真机Android 12四、核心功能实现1. 用户模块注册/登录· 使用 Room 创建 users 表id、username、password。· 注册时插入用户登录时查询验证。· 登录成功后用 GlobalState.currentUserId 保存用户ID供全局使用。关键代码协程 挂起函数kotlin// 注册lifecycleScope.launch {val existing db.userDao().findByUsername(username)if (existing null) {db.userDao().insert(User(username username, password password))Toast.makeText(thisLoginActivity, 注册成功, Toast.LENGTH_SHORT).show()}}// 登录lifecycleScope.launch {val user db.userDao().login(username, password)if (user ! null) {GlobalState.currentUserId user.idstartActivity(Intent(thisLoginActivity, MainActivity::class.java))finish()}}2. 商品列表 轮播图 实时搜索· 商品数据硬编码在 MainActivity 的 allProducts 列表中13个商品带图片URL、名称、价格、描述。· 轮播图ViewPager2 BannerAdapter配合 Handler 实现自动滚动每3秒切换。在 onPause 中停止onResume 中重启。· 搜索EditText 添加 TextWatcher实时过滤 displayedProducts并刷新 RecyclerView。kotlinsearchEditText.addTextChangedListener(object : TextWatcher {override fun afterTextChanged(s: Editable?) {val query s.toString()displayedProducts.clear()if (query.isEmpty()) {displayedProducts.addAll(allProducts)} else {displayedProducts.addAll(allProducts.filter {it.name.contains(query, ignoreCase true)})}productAdapter.notifyDataSetChanged()}})3. 商品详情 购物车 收藏· 页面跳转通过 Intent 传递实现了 Serializable 的 Product 对象。· 加入购物车调用 CartManager.addProduct(product)。CartManager 是一个单例内部维护 mutableListOfCartItem每个 CartItem 包含 Product 和数量。· 收藏favorites 表存储 (userId, productId)。在详情页通过协程查询当前是否已收藏点击时插入或删除记录并同步按钮状态。购物车单例部分代码kotlinobject CartManager {private val cartItems mutableListOfCartItem()fun addProduct(product: Product) {val existing cartItems.find { it.product.id product.id }if (existing ! null) existing.quantityelse cartItems.add(CartItem(product, 1))}fun updateQuantity(productId: Int, newQuantity: Int) {val item cartItems.find { it.product.id productId }if (item ! null) {if (newQuantity 0) cartItems.remove(item)else item.quantity newQuantity}}fun getTotalPrice(): Double cartItems.sumOf { it.product.price * it.quantity }}4. 购物车页面· 从 CartManager 获取列表展示在 RecyclerView 中。· 每个商品项带 “”、“-”、“删除” 按钮点击后调用 CartManager.updateQuantity()然后刷新整个列表和总价。· 总价实时显示在页面底部点击“去结算”跳转订单页面。5. 订单生成模拟支付· 在 CheckoutActivity 中获取当前购物车内容将商品列表拼接成字符串例如“卫衣 x1, 运动鞋 x2”。· 构建 Order 对象userId、totalPrice、orderTimeDate、itemsJson。· 使用协程调用 OrderDao.insert(order) 存入数据库。· 清空购物车CartManager.clear()弹出“支付成功”关闭当前页面。Room 订单实体kotlinEntity(tableName orders)data class Order(PrimaryKey(autoGenerate true)val id: Int 0,val userId: Int,val totalPrice: Double,val orderTime: Date Date(),val itemsJson: String // 存储商品名和数量)6. 个人中心订单 收藏· 分别从 OrderDao 和 FavoriteDao 查询当前用户的数据。· 订单列表展示订单总价、时间、商品摘要。· 收藏列表先获取收藏的 productId 列表再从全局 GlobalState.allProducts 中过滤出商品对象展示在 RecyclerView 中。---五、数据库设计Room表名 字段 说明users id, username, password 用户表orders id, userId, totalPrice, orderTime, itemsJson 订单表favorites id, userId, productId 收藏关系表类型转换器解决 Room 不支持 Date 类型kotlinclass Converters {TypeConverterfun fromTimestamp(value: Long?): Date? value?.let { Date(it) }TypeConverterfun dateToTimestamp(date: Date?): Long? date?.time}在 AppDatabase 类上添加 TypeConverters(Converters::class)。---六、开发中遇到的坑与解决1. Gradle 下载慢 / 失败· 问题Sync 时卡在 download gradle-7.1-bin.zip。· 解决修改 gradle/wrapper/gradle-wrapper.properties 中的 distributionUrl 为腾讯云镜像distributionUrlhttps://mirrors.cloud.tencent.com/gradle/gradle-7.1-bin.zip2. Room 编译错误Cannot figure out how to save this field into databaseDate 类型· 解决编写 TypeConverter并在数据库类上标注。3. 协程中调用挂起函数需要生命周期作用域· 问题直接在 Activity 中调用 db.userDao().insert() 会报错。· 解决使用 lifecycleScope.launch { } 包裹所有数据库操作。4. Glide 图片不显示· 原因未添加网络权限或依赖缺失。· 解决在 AndroidManifest.xml 添加 uses-permission android:nameandroid.permission.INTERNET /并在 build.gradle 中添加 Glide 依赖。5. 轮播图自动滚动内存泄漏· 问题未在 onPause 中停止 Handler。· 解决在 onPause 中移除回调onResume 中重新启动。---七、项目结构关键文件app/src/main/java/.../├── MainActivity.kt // 商品列表轮播图搜索├── DetailActivity.kt // 商品详情购物车收藏├── CartActivity.kt // 购物车列表├── CheckoutActivity.kt // 订单生成├── LoginActivity.kt // 登录注册├── ProfileActivity.kt // 个人中心├── CartManager.kt // 购物车单例├── GlobalState.kt // 全局用户ID 商品列表├── data/│ ├── AppDatabase.kt│ ├── User.kt, Order.kt, Favorite.kt│ ├── UserDao.kt, OrderDao.kt, FavoriteDao.kt│ └── Converters.kt└── adapter/├── ProductAdapter.kt├── CartAdapter.kt├── OrderAdapter.kt└── FavoriteAdapter.kt---八、总结与展望通过这个项目我完整实践了 Android 开发的现代技术栈Kotlin Room 协程 Glide ViewPager2并独立完成了从产品需求分析、数据库设计、功能实现到测试的全流程。技术收获· 深入理解了 Room 与 SQLite 的关系学会了使用 TypeConverter。· 掌握了协程在 Android 中的正确使用方式lifecycleScope 挂起函数。· 积累了复杂状态管理购物车、收藏的经验。· 培养了独立排查问题的能力Gradle、依赖冲突、权限适配等。可扩展方向· 接入后端 APIRetrofit 商品数据动态获取。· 集成微信/支付宝支付需企业资质。· 增加商品分类、筛选、评价功能。· 使用 DataStore 替代 SharedPreferences 保存登录。---十、最后写这篇博客一是记录自己从坑里爬出来的过程二是希望帮助到正在学习 Android 的初学者。如果你也遇到类似的问题欢迎留言交流。觉得有用的话点个赞、收藏、关注我会持续输出技术干货。版权声明本文为原创转载请附上原文出处链接。
【Android实战】从0到1开发一款完整购物商城App
发布时间:2026/5/21 14:40:28
一、为什么要写这个项目大二下学期《Android基础及应用》课程设计我选择实现一个完整的购物商城App。原因很简单购物流程涵盖了移动开发中最核心的组件列表、数据库、异步、交互做完一个购物App等于把Android大半本教材都实践了一遍。项目前后开发约两周实际写代码不到一周其余时间在踩坑和优化最终实现了用户注册登录 → 商品浏览 → 搜索 → 购物车 → 订单生成 → 个人中心订单/收藏 的全套流程。代码结构清晰技术栈较新适合初学者学习完整项目的开发思路。二、项目展示截图略图1 登录界面图2 商品列表含自动轮播Banner 实时搜索图3 商品详情加购、收藏图4 购物车数量增减、删除、总价图5 订单确认模拟支付图6 个人中心订单记录 收藏列表三、技术栈选型分类 技术 说明语言 Kotlin 空安全、协程支持、简洁UI ConstraintLayout、LinearLayout、RecyclerView、CardView、ViewPager2 常用组件图片加载 Glide 网络图片 占位图 缓存数据库 RoomSQLite 用户、订单、收藏存储异步 Kotlin Coroutines 避免主线程阻塞状态管理 单例模式CartManager、GlobalState 购物车与用户状态最低SDK API 21 覆盖95%设备测试设备 Pixel 4 模拟器API33 真机Android 12四、核心功能实现1. 用户模块注册/登录· 使用 Room 创建 users 表id、username、password。· 注册时插入用户登录时查询验证。· 登录成功后用 GlobalState.currentUserId 保存用户ID供全局使用。关键代码协程 挂起函数kotlin// 注册lifecycleScope.launch {val existing db.userDao().findByUsername(username)if (existing null) {db.userDao().insert(User(username username, password password))Toast.makeText(thisLoginActivity, 注册成功, Toast.LENGTH_SHORT).show()}}// 登录lifecycleScope.launch {val user db.userDao().login(username, password)if (user ! null) {GlobalState.currentUserId user.idstartActivity(Intent(thisLoginActivity, MainActivity::class.java))finish()}}2. 商品列表 轮播图 实时搜索· 商品数据硬编码在 MainActivity 的 allProducts 列表中13个商品带图片URL、名称、价格、描述。· 轮播图ViewPager2 BannerAdapter配合 Handler 实现自动滚动每3秒切换。在 onPause 中停止onResume 中重启。· 搜索EditText 添加 TextWatcher实时过滤 displayedProducts并刷新 RecyclerView。kotlinsearchEditText.addTextChangedListener(object : TextWatcher {override fun afterTextChanged(s: Editable?) {val query s.toString()displayedProducts.clear()if (query.isEmpty()) {displayedProducts.addAll(allProducts)} else {displayedProducts.addAll(allProducts.filter {it.name.contains(query, ignoreCase true)})}productAdapter.notifyDataSetChanged()}})3. 商品详情 购物车 收藏· 页面跳转通过 Intent 传递实现了 Serializable 的 Product 对象。· 加入购物车调用 CartManager.addProduct(product)。CartManager 是一个单例内部维护 mutableListOfCartItem每个 CartItem 包含 Product 和数量。· 收藏favorites 表存储 (userId, productId)。在详情页通过协程查询当前是否已收藏点击时插入或删除记录并同步按钮状态。购物车单例部分代码kotlinobject CartManager {private val cartItems mutableListOfCartItem()fun addProduct(product: Product) {val existing cartItems.find { it.product.id product.id }if (existing ! null) existing.quantityelse cartItems.add(CartItem(product, 1))}fun updateQuantity(productId: Int, newQuantity: Int) {val item cartItems.find { it.product.id productId }if (item ! null) {if (newQuantity 0) cartItems.remove(item)else item.quantity newQuantity}}fun getTotalPrice(): Double cartItems.sumOf { it.product.price * it.quantity }}4. 购物车页面· 从 CartManager 获取列表展示在 RecyclerView 中。· 每个商品项带 “”、“-”、“删除” 按钮点击后调用 CartManager.updateQuantity()然后刷新整个列表和总价。· 总价实时显示在页面底部点击“去结算”跳转订单页面。5. 订单生成模拟支付· 在 CheckoutActivity 中获取当前购物车内容将商品列表拼接成字符串例如“卫衣 x1, 运动鞋 x2”。· 构建 Order 对象userId、totalPrice、orderTimeDate、itemsJson。· 使用协程调用 OrderDao.insert(order) 存入数据库。· 清空购物车CartManager.clear()弹出“支付成功”关闭当前页面。Room 订单实体kotlinEntity(tableName orders)data class Order(PrimaryKey(autoGenerate true)val id: Int 0,val userId: Int,val totalPrice: Double,val orderTime: Date Date(),val itemsJson: String // 存储商品名和数量)6. 个人中心订单 收藏· 分别从 OrderDao 和 FavoriteDao 查询当前用户的数据。· 订单列表展示订单总价、时间、商品摘要。· 收藏列表先获取收藏的 productId 列表再从全局 GlobalState.allProducts 中过滤出商品对象展示在 RecyclerView 中。---五、数据库设计Room表名 字段 说明users id, username, password 用户表orders id, userId, totalPrice, orderTime, itemsJson 订单表favorites id, userId, productId 收藏关系表类型转换器解决 Room 不支持 Date 类型kotlinclass Converters {TypeConverterfun fromTimestamp(value: Long?): Date? value?.let { Date(it) }TypeConverterfun dateToTimestamp(date: Date?): Long? date?.time}在 AppDatabase 类上添加 TypeConverters(Converters::class)。---六、开发中遇到的坑与解决1. Gradle 下载慢 / 失败· 问题Sync 时卡在 download gradle-7.1-bin.zip。· 解决修改 gradle/wrapper/gradle-wrapper.properties 中的 distributionUrl 为腾讯云镜像distributionUrlhttps://mirrors.cloud.tencent.com/gradle/gradle-7.1-bin.zip2. Room 编译错误Cannot figure out how to save this field into databaseDate 类型· 解决编写 TypeConverter并在数据库类上标注。3. 协程中调用挂起函数需要生命周期作用域· 问题直接在 Activity 中调用 db.userDao().insert() 会报错。· 解决使用 lifecycleScope.launch { } 包裹所有数据库操作。4. Glide 图片不显示· 原因未添加网络权限或依赖缺失。· 解决在 AndroidManifest.xml 添加 uses-permission android:nameandroid.permission.INTERNET /并在 build.gradle 中添加 Glide 依赖。5. 轮播图自动滚动内存泄漏· 问题未在 onPause 中停止 Handler。· 解决在 onPause 中移除回调onResume 中重新启动。---七、项目结构关键文件app/src/main/java/.../├── MainActivity.kt // 商品列表轮播图搜索├── DetailActivity.kt // 商品详情购物车收藏├── CartActivity.kt // 购物车列表├── CheckoutActivity.kt // 订单生成├── LoginActivity.kt // 登录注册├── ProfileActivity.kt // 个人中心├── CartManager.kt // 购物车单例├── GlobalState.kt // 全局用户ID 商品列表├── data/│ ├── AppDatabase.kt│ ├── User.kt, Order.kt, Favorite.kt│ ├── UserDao.kt, OrderDao.kt, FavoriteDao.kt│ └── Converters.kt└── adapter/├── ProductAdapter.kt├── CartAdapter.kt├── OrderAdapter.kt└── FavoriteAdapter.kt---八、总结与展望通过这个项目我完整实践了 Android 开发的现代技术栈Kotlin Room 协程 Glide ViewPager2并独立完成了从产品需求分析、数据库设计、功能实现到测试的全流程。技术收获· 深入理解了 Room 与 SQLite 的关系学会了使用 TypeConverter。· 掌握了协程在 Android 中的正确使用方式lifecycleScope 挂起函数。· 积累了复杂状态管理购物车、收藏的经验。· 培养了独立排查问题的能力Gradle、依赖冲突、权限适配等。可扩展方向· 接入后端 APIRetrofit 商品数据动态获取。· 集成微信/支付宝支付需企业资质。· 增加商品分类、筛选、评价功能。· 使用 DataStore 替代 SharedPreferences 保存登录。---十、最后写这篇博客一是记录自己从坑里爬出来的过程二是希望帮助到正在学习 Android 的初学者。如果你也遇到类似的问题欢迎留言交流。觉得有用的话点个赞、收藏、关注我会持续输出技术干货。版权声明本文为原创转载请附上原文出处链接。