更新:如何使用ViewModelFactory,是否有必要使用它来传递我们的参数?有什么好处?这会打破实时数据的概念吗?
我想把一个参数发送到我房间数据库的word Dao中进行查询,但在我的情况下,我不知道如何传递这个参数。让我们从代码开始。。。WordDao.kt
@Dao
interface WordDao {
@Insert
fun insert(word: Word)
@Update
fun update(word: Word)
@Delete
fun delete(word: Word)
@Query("delete from En_Fa")
fun deleteAllNotes()
@Query("SELECT * FROM En_Fa ORDER BY id ASC")
fun getAllNotes(): LiveData<List<Word>>
@Query("Select * From En_Fa WHERE date == :today ")
fun getTodayWords(today: String): LiveData<List<Word>>
}
WordRepository.kt
class WordRepository(private val wordDao: WordDao, today: String) {
val readAllData: LiveData<List<Word>> = wordDao.getAllNotes()
val readToday: LiveData<List<Word>> = wordDao.getTodayWords(today)
fun addWord(word: Word) {
wordDao.insert(word)
}
}
WordViewModel.kt
class WordViewModel(application: Application): AndroidViewModel(application) {
val readAllData2: LiveData<List<Word>>
private val repository: WordRepository
init {
val wordDao = WordDatabase.getInstance(application).wordDao()
repository = WordRepository(wordDao, today)
readAllData2 = repository.readToday
}
fun addWord(word: Word){
viewModelScope.launch(Dispatchers.IO){
repository.addWord(word)
}
}
}
这是我的代码行,它在我的片段中创建了这个wordview模型类的对象
private val mWordViewModel: WordViewModel by viewModels()
那么如何将我的(今天(变量从我的片段传递到我的WordViewModel类
我想你正在寻找这个:
@Dao
interface WordDao {
// ...
@Query("Select * From En_Fa WHERE date == :today ")
fun getTodayWords2(today: String): <List<Word>
}
然后在存储库中:
class WordRepository{
// ... ...
var mutableWords: MutableLiveData<List<Word>> = MutableLiveData()
fun getWords(today: String): List<Word> { // WARNING! run this in background thread else it will crash
return wordDao.getTodayWords2(today)
}
fun getWordsAsync(today: String) {
Executors.newSingleThreadExecutor().execute {
val words = getWords(today)
liveWords.postValue(words) // <-- just doing this will trigger the observer and do next thing, such as, updating ui
}
}
}
然后在您的视图中模型:
class WordViewModel(application: Application): AndroidViewModel(application) {
// ... ...
val liveWords: LiveData<List<Word>> = repository.mutableWords
fun getWordsAsync(today: String) {
repository.getWordsAsync(today)
}
}
最后进入你的活动/片段:
fun viewModelDemo() {
mWordViewModel.liveWords.observe(this, Observer{
// todo: update the ui, eg
someTextView.text = it.toString() // <-- here you get the output
})
someButton.setOnClickListener{
// here you give the input
mWordViewModel.getWordsAsync(today) // get `today` from date picker or something
}
}
编辑
所以您有一个带有适配器的recyclerView。当数据集发生更改时,可以调用notifyDataSetChanged
。假设适配器如下所示:
class MyAdapter: RecyclerView.Adapter<ViewHolder> {
private var words: List<Word> = ArrayList() // initially points to an empty list
override fun getCount() { return words.size }
// ... ... other methods
// public method:
fun submitList(words1: List<Word>) {
this.words = words1 // so now it points to the submitted list
this.notifyDataSetChanged() // this tells recyclerView to update itself
}
}
然后在你的活动或片段中:
private lateinit var myAdapter: MyAdapter
override fun onCreate() { // or onViewCreated if using fragment
// ... ... some codes
this.myAdapter = MyAdapter()
binding.recyclerView.adapter = myAdapter
viewModelDemo()
}
fun viewModelDemo() {
mWordViewModel.liveWords.observe(this, Observer{
// todo: update the ui, eg
myAdapter.submitList(it) // <----- Here you call the submitList method
// <-- here you get the output
})
// --- ---
}
我希望这能奏效。
如果我答对了你的问题,那么,首先,您需要制作一个函数,返回要观察的liveData
对象,然后您需要使用ViewModelProviders
,在片段中为您提供ViewModel的对象。
mWordViewModel: WordViewModel = ViewModelProvider(this/getActivity()).get(WordViewModel::class.java)
mWordViewModel.getLiveDataFunction().observe(this/lifeCycleOwner, {
process result/response here
}
然后简单地使用。
mWordViewModel.addWord(today)