上一篇
安卓列表控件添加数据库
- 行业动态
- 2025-04-24
- 2480
通过SQLiteHelper创建数据库表,查询数据转存至List/RecyclerView的适配器,设置控件数据源即可实现
技术选型与准备
技术组件 | 说明 |
---|---|
数据库 | SQLite(原生)或 Room(推荐,基于SQLite的抽象层) |
列表控件 | RecyclerView(推荐,性能优于ListView) |
架构组件 | ViewModel + LiveData(数据响应式更新) |
实现步骤
添加依赖(以Room为例)
在 build.gradle
中添加:
// Room相关依赖 implementation "androidx.room:room-runtime:2.5.1" annotationProcessor "androidx.room:room-compiler:2.5.1" // 如果使用Kotlin协程 implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4"
定义数据库实体
// Entity标注表名,字段需指定类型 @Entity(tableName = "user") data class User( @PrimaryKey(autoGenerate = true) val id: Int, val name: String, val age: Int )
创建DAO接口
// 定义访问数据库的方法 @Dao interface UserDao { @Query("SELECT FROM user") fun getAllUsers(): LiveData<List<User>> // 支持观察数据变化 @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insertUser(user: User) }
创建数据库类
// 继承RoomDatabase并包含DAO @Database(entities = [User::class], version = 1) abstract class AppDatabase : RoomDatabase() { abstract fun userDao(): UserDao }
初始化数据库(单例模式)
// 在Application中初始化 class MyApp : Application() { companion object { lateinit var database: AppDatabase } override fun onCreate() { super.onCreate() database = Room.databaseBuilder( applicationContext, AppDatabase::class.java, "app_database" ).build() } }
创建RecyclerView适配器
class UserAdapter(private val users: List<User>) : RecyclerView.Adapter<UserAdapter.ViewHolder>() { inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val nameTv: TextView = itemView.findViewById(R.id.name) val ageTv: TextView = itemView.findViewById(R.id.age) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val view = LayoutInflater.from(parent.context).inflate(R.layout.item_user, parent, false) return ViewHolder(view) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { val user = users[position] holder.nameTv.text = user.name holder.ageTv.text = user.age.toString() } override fun getItemCount() = users.size }
绑定数据到RecyclerView
class MainActivity : AppCompatActivity() { private lateinit var adapter: UserAdapter private lateinit var viewModel: UserViewModel override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 初始化ViewModel和LiveData viewModel = ViewModelProvider(this)[UserViewModel::class.java] val recyclerView = findViewById<RecyclerView>(R.id.recyclerView) adapter = UserAdapter(emptyList()) // 初始空数据 recyclerView.adapter = adapter recyclerView.layoutManager = LinearLayoutManager(this) // 观察LiveData并更新UI viewModel.allUsers.observe(this) { users -> adapter = UserAdapter(users) // 重新设置适配器触发更新 recyclerView.adapter = adapter } } }
创建ViewModel管理数据
class UserViewModel(application: Application) : AndroidViewModel(application) { private val userDao = MyApp.database.userDao() val allUsers: LiveData<List<User>> = userDao.getAllUsers() fun addUser(name: String, age: Int) { viewModelScope.launch { userDao.insertUser(User(0, name, age)) // ID自动生成 } } }
关键问题与解决方案
问题描述 | 解决方案 |
---|---|
数据不刷新 | 确保使用 LiveData 或手动调用 adapter.notifyDataSetChanged() |
主线程阻塞 | 使用 suspend 函数在协程中操作数据库,避免UI卡顿 |
RecyclerView显示异常 | 检查 item_user.xml 布局文件是否正确,确保 LayoutManager 已设置 |
相关问题与解答
问题1:如何实现列表数据的实时更新?
解答:
通过 LiveData
监听数据库变化,当数据表内容发生增删改时,LiveData
会自动触发 Observer
,重新获取数据并更新 RecyclerView
。
// 在ViewModel中定义LiveData val allUsers: LiveData<List<User>> = userDao.getAllUsers()
问题2:如何在子线程中插入数据?
解答:
使用 viewModelScope.launch
启动协程,确保数据库操作在非主线程执行:
fun addUser(name: String, age: Int) { viewModelScope.launch { userDao.insertUser(User(0, name, age)) // 协程内执行IO操作 } }