jetpack compose监听room数据库

638 阅读1分钟

首先在app/build.gradle引入

    
    def room_version = "2.5.0"
    implementation "androidx.room:room-runtime:$room_version"
    //room 协程
    implementation "androidx.room:room-ktx:$room_version"
    annotationProcessor "androidx.room:room-compiler:$room_version"

    // To use Kotlin annotation processing tool (kapt)
    kapt "androidx.room:room-compiler:$room_version"
//     To use Kotlin Symbol Processing (KSP)
//    ksp "androidx.room:room-compiler:$room_version"

如果要开启kapt,还需引用

plugins {
    ...
    id "org.jetbrains.kotlin.kapt"
}

此处用官方示例,再用flow包装

@Entity
data class UserAccount(
    @PrimaryKey(autoGenerate = true) val index: Int?,
    @ColumnInfo(name = "title") val title: String,
    @ColumnInfo(name = "account") val account: String,
    @ColumnInfo(name = "password") val password: String,
    @ColumnInfo(name = "remark") val remark: String?,
)
@Dao
interface UserDao {
    //此处用Flow包装以便监听
    @Query("SELECT * FROM UserAccount")
    fun getAll(): Flow<List<UserAccount>>
    @Insert
    fun insertAll(vararg users: UserAccount)
    @Insert
    fun insert(users: UserAccount)
    @Delete
    fun delete(user: UserAccount)
}

Database方法

@Database(entities = [UserAccount::class], version = 1/*, exportSchema = false*/)
abstract class UserDatas : RoomDatabase() {
    abstract fun userDao(): UserDao
}

如果不想配置exportScheme,则需要在build.gradle中配置

defaultConfig {
    ...
javaCompileOptions {
    annotationProcessorOptions {
        arguments += [
                "room.schemaLocation": "$projectDir/schemas".toString(),
                "room.incremental"   : "true"
            ]
        }
    }
}
class MainViewModel(/*private val dao: UserDao*/) : ViewModel()
{
    //其实最理想的dao访问应该是从viewModel构造中获取,而不是此写法
    val userDao by lazy { db.userDao() }
    private var userDaoSize = MutableStateFlow(userDao.getAll())

    //    @Delete
    fun deleteItem(user: UserAccount) = userDao.delete(user)
    fun userDaoChanged(): Boolean = userDao.getAll() == userDaoSize.value
    fun getAll(): Flow<List<UserAccount>> = userDao.getAll()
}

调用

@Composable
fun MainScreen(
    viewModel: MainViewModel = viewModel(),
    context: Context = LocalContext.current
) {
    //把数据库的元素监听为状态
    val all = viewModel.getAll().collectAsState(initial = listOf())

    Column() {
        LazyColumn {
            items(all.value.size) { index ->
                PassItem(icon = null, userAccount = all.value[index]) {
                    Toast.makeText(context, "点击item:${all.value[index]}", Toast.LENGTH_SHORT).show()
                }
            }
        }
    }
    LaunchedEffect(viewModel.userDaoChanged()) {
        //dao的数据变化 会被调用
        Log.d(TAG, "All users:$all,size=${all.value.size}")
    }
}