如何使用视图模型和实时数据将参数传递给我的 Word Dao 进行查询?
how to pass a parameter to my Word Dao for query using View Model and Live Data?
更新:如何使用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 模型的对象 class
private val mWordViewModel: WordViewModel by viewModels()
那么如何将我的(今天)变量从我的片段传递到我的 WordViewModel class
如果我答对了你的问题,
首先,您需要创建一个函数来 return 要观察的 liveData
对象,然后您需要使用 ViewModelProviders
来为您提供片段中的 ViewModel 对象。
mWordViewModel: WordViewModel = ViewModelProvider(this/getActivity()).get(WordViewModel::class.java)
mWordViewModel.getLiveDataFunction().observe(this/lifeCycleOwner, {
process result/response here
}
那就直接用吧。
mWordViewModel.addWord(today)
我想你正在寻找这个:
@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
}
}
}
然后在你的 viewModel 中:
class WordViewModel(application: Application): AndroidViewModel(application) {
// ... ...
val liveWords: LiveData<List<Word>> = repository.mutableWords
fun getWordsAsync(today: String) {
repository.getWordsAsync(today)
}
}
然后终于在你的 activity / 片段中:
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
}
}
然后在您的 activity 或片段中:
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
})
// --- ---
}
我希望这能奏效。
更新:如何使用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 模型的对象 classprivate val mWordViewModel: WordViewModel by viewModels()
那么如何将我的(今天)变量从我的片段传递到我的 WordViewModel class
如果我答对了你的问题,
首先,您需要创建一个函数来 return 要观察的 liveData
对象,然后您需要使用 ViewModelProviders
来为您提供片段中的 ViewModel 对象。
mWordViewModel: WordViewModel = ViewModelProvider(this/getActivity()).get(WordViewModel::class.java)
mWordViewModel.getLiveDataFunction().observe(this/lifeCycleOwner, {
process result/response here
}
那就直接用吧。
mWordViewModel.addWord(today)
我想你正在寻找这个:
@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
}
}
}
然后在你的 viewModel 中:
class WordViewModel(application: Application): AndroidViewModel(application) {
// ... ...
val liveWords: LiveData<List<Word>> = repository.mutableWords
fun getWordsAsync(today: String) {
repository.getWordsAsync(today)
}
}
然后终于在你的 activity / 片段中:
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
}
}
然后在您的 activity 或片段中:
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
})
// --- ---
}
我希望这能奏效。