【问题标题】:DIsplay LiveData in a ListView在 ListView 中显示 LiveData
【发布时间】:2020-12-07 10:47:04
【问题描述】:

我有一个Activity,我有一个LiveData,我想在ListView 中显示它。

我的代码sn-p:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_records)
    this.recordListView.emptyView = recordListEmptyView
    viewModel = ViewModelProvider(this).get(RecordsViewModel::class.java)
    recordDAO = AppDatabase.getDb(this).recordDao()
    recordDAO.findAllSync().observe(this) {
        //display livedata in listview after getting added
        //adapter = ArrayAdapter(this,list_items,syncedRecords)
        //listview.adapter = adapter
    }
}

添加记录后,我想在我有评论的地方显示记录。 我可以让它与普通的findAll() 一起工作,并将我的适配器设置为findAll() 的返回值,但我无法让它与LiveData 一起工作。

我的 DAO 类:

@Dao
interface RecordDAO{

    @Update(onConflict = REPLACE)
    fun update(record:Record) : Int

    @Insert(onConflict = IGNORE)
    fun persist(record: Record): Long

    @Delete
    fun delete(record: Record): Int

    @Delete
    fun deleteAll(records: List<Record>)

    @Query("SELECT * FROM record")
    fun findAll(): List<Record>

    @Query("SELECT * FROM record")
    fun findAllSync(): LiveData<List<Record>>

    @Query("SELECT * FROM record WHERE id = :id")
    fun findById(id: Int): Record?

}

【问题讨论】:

    标签: android kotlin android-room dao


    【解决方案1】:

    这是它应该如何工作的。由于您没有包含视图模型代码,因此很难知道确切的错误。在这里你观察到一个函数的结果(recordDAO.findAllSync().observe),所以我猜livedata是一个只在findAllSync范围内的变量。

    这不是它的工作方式。实时数据应该是 viewModel 的成员变量

    class RecordsViewModel : ViewModel() {
        val records = MutableLiveData<RecordDAO>()
    
        // this function gives the records to the live data. No need for a return value
        fun findAllSync() {
            // Retrieve the records somehow, here this should be edited by you
            records.value = someService.getRecords()
        }
    }
    

    然后在活动/片段中,您观察实时数据并请求记录更新(您也可以直接从视图模型的init 请求更新,具体取决于您想要获取数据的方式/时间)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_records)
        this.recordListView.emptyView = recordListEmptyView
        viewModel = ViewModelProvider(this).get(RecordsViewModel::class.java)
        
        // THIS CHANGED
        viewModel.findAllSync()
        viewModel.records.observe(this) { records ->
            val adapter = ArrayAdapter(this,list_items, records)
            listview.adapter = adapter
        }
    }
    

    注意:我使用了MutableLiveData。更简洁的方法是拥有一个私人MutableLiveData 和一个公共LiveData

    private val _records = MutableLiveData<RecordDAO>()
    val records: LiveData<RecordDAO> = _records
    

    vm使用_records.value设置数据,但由于Activity只能读取不可变的,它不能编辑值,只有viewmodel可以。你不需要这样做,但知道总是很高兴

    【讨论】:

    • 我没有任何错误但没有显示记录是问题
    • 这个我不太明白,viewmodel中的findAllSync方法是不是用在什么地方?
    • @YasinEraslan 抱歉,我的回答中缺少一行。检查我添加评论的行 // THIS CHANGED
    • recordDao.records 是从哪里来的?
    • 你所说的服务是什么意思,我实际上只有一个 sql 数据库,使用 findAll()(我可以从我的数据库中获取所有记录
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-08
    相关资源
    最近更新 更多