Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何更改房间Dao中LiveData的ViewModel源_Android_Viewmodel_Android Room_Android Architecture Components_Android Livedata - Fatal编程技术网

Android 如何更改房间Dao中LiveData的ViewModel源

Android 如何更改房间Dao中LiveData的ViewModel源,android,viewmodel,android-room,android-architecture-components,android-livedata,Android,Viewmodel,Android Room,Android Architecture Components,Android Livedata,如何更改房间Dao中LiveData的ViewModel源。 在WordDao中,我有两个问题: @Dao public interface WordDao { @Query("SELECT * FROM " + Word.TABLE_NAME + " ORDER BY text ASC") LiveData<List<Word>> getWordsByAsc(); @Query("SELECT * FROM " + Word.TABLE_NAME

如何更改房间Dao中LiveData的ViewModel源。 在WordDao中,我有两个问题:

@Dao
public interface WordDao {

   @Query("SELECT * FROM " + Word.TABLE_NAME + " ORDER BY text ASC")
   LiveData<List<Word>> getWordsByAsc();

   @Query("SELECT * FROM " + Word.TABLE_NAME + " ORDER BY text DESC")
   LiveData<List<Word>> getWordsByDesc();
}
@Dao
公共接口WordDao{
@查询(“从“+Word.TABLE\u NAME+”按文本排序ASC”中选择*)
LiveData getWordsByAsc();
@查询(“从“+Word.TABLE_NAME+”按文本说明排序”中选择*)
LiveData getWordsByDesc();
}
我还有一个存储库类:

public class WordRepository {
   public LiveData<List<Word>> getWordsByAsc() {
       return wordDao.getWordsByAsc();
   }

   public LiveData<List<Word>> getWordsByDesc() {
       return wordDao.getWordsByDesc();
   }
}
公共类WordRepository{
公共LiveData getWordsByAsc(){
返回wordDao.getWordsByAsc();
}
公共LiveData getWordsByDesc(){
返回wordDao.getWordsByDesc();
}
}
和我的ViewModel类:

public class WordViewModel extends AndroidViewModel {
    private boolean isSortAsc = true;
    private LiveData<Word> words;
    private WordRepository wordRepository;

    public WordViewModel(@NonNull Application application) {
        super(application);

        wordRepository = new WordRepository(application);
        words = wordRepository.getWordsByAsc();
    }

    public LiveData<List<Word>> getWords() {
       return words;
    }

    public void sortButtonClicked() {
       isSortAsc = !isSortAsc;
       //TODO how change here source of data depending on the isSortAsc
       //It works only after change configuration of screen, not insta
       words = isSortAsc ? wordRepository.getWordsByAsc() : 
            wordRepository.getWordsByDesc()
    }
}
公共类WordViewModel扩展了AndroidViewModel{
私有布尔值isSortAsc=true;
私有数据字;
专用字库字库;
公共WordViewModel(@NonNull应用程序){
超级(应用);
wordRepository=新的wordRepository(应用程序);
words=wordRepository.getWordsByAsc();
}
公共LiveData getWords(){
返回单词;
}
public void排序按钮单击(){
isSortAsc=!isSortAsc;
//TODO如何根据isSortAsc更改此处的数据源
//只有在更改屏幕配置后才能工作,而不是insta
words=isSortAsc?wordRepository.getWordsByAsc():
wordRepository.getWordsByDesc()
}
}
在我的活动中,我添加了观察者:

 wordViewModel.getWords().observe(this, new Observer<List<Word>>() {
      @Override
      public void onChanged(@Nullable List<Word> words) {
          adapter.setWords(words);
      }
 });
wordViewModel.getWords().observe(这是一个新的观察者(){
@凌驾
公共void onChanged(@Nullable List words){
adapter.setWords(单词);
}
});
在setWords(words)方法中,我也调用“notifyDataSetChanged()”

如何根据“isSortAsc”参数更改LiveData的viewModel类源 (words=isSortAsc?wordRepository.getWordsByAsc():wordRepository.getWordsByDesc()


它仅在更改屏幕配置后有效,而在insta更改LiveData单词的源代码后无效。一种方法可能是使用
MediatorLiveData
…例如:

val words = MediatorLiveData<Word>().apply {
    this.addSource(sortDirection) {
        if (sortDirection.value) {
             this.value = wordRepository.getWordsByAsc()
        } else {
             this.value = wordRepository.getWordsByDesc()
        }
    }
}
val words=MediatorLiveData()。应用{
this.addSource(sortDirection){
if(sortDirection.value){
this.value=wordRepository.getWordsByAsc()
}否则{
this.value=wordRepository.getWordsByDesc()
}
}
}
我在下面做了类似的事情(设置
方向

我认为以下功能需要修改

wordViewModel.getWords().observe(this, new Observer<List<Word>>() {
      @Override
      public void onChanged(@Nullable List<Word> words) {
          adapter.setAdapter(words);
          notifyDataSetChanged();
      }
 });
wordViewModel.getWords().observe(这是一个新的观察者(){
@凌驾
公共void onChanged(@Nullable List words){
adapter.setAdapter(单词);
notifyDataSetChanged();
}
});

还有一件事,在触发onChanged之前,words变量不会有任何值。因此,您必须确保只有在onChanged()之后才调用getWords()

我认为这是一个简单的解决方案,始终查询表ASC ie,只有在用户选择descending.Collection.Sort()时才反转列表是由安卓系统提供的,因此它的性能应该更好

 public void sortButtonClicked() {
       isSortAsc = !isSortAsc;
       //TODO how change here source of data depending on the isSortAsc
       //It works only after change configuration of screen, not insta
 words = wordRepository.getWordsByAsc();
      if(!isSortAsc) {
         Collections.reverse(words);
       }
}
我希望这将对您有所帮助。

使用

第一个make
isSortAsc
LiveData

private MutableLiveData<Boolean> isSortAsc = new MutableLiveData<Boolean>(true);

这是我的命名错误,应该是这样的:adapter.setWords(words);在我的adapter In setWords中,我有notifyDataSetChanged(),但它不起作用。你有代码来解释getWords()将在哪里触发吗?下面的代码是在activity wordViewModel.getWords()中设置的。观察(这是新的观察者(){@Override public void onChanged(@Nullable List words){adapter.setWords(words);}}}});我想更新适配器列表,当ViewModel中的LiveData源将更改单独适配器类中的setWords时,如下所示:public void setWords(List allWords){this.allWords=allWords;notifyDataSetChanged();}问题是wordViewModel.getWords()。GetWordsBySC()已观察到observe由于这是在构造函数中发生的。当您点击sortButtonClicked时,观察到的livedata不会发生任何更改,它仍然引用旧的,直到观察重新创建。这就是更改配置时发生的情况。您有什么想法吗,当源在ViewMode中更改时,我如何处理调用此livedata的更改l?我提出了一个解决方案,在活动中,我观察到可变的LiveData是SortAsc,在这个布尔值的一次更改中,我从一个LiveData中移除了observer,并将observer添加到第二个LiveData中,它可以工作,但我不喜欢这个解决方案,因为我在ViewModel中有两个LiveData引用,我在构造函数中做了类似的东西rds.setValue(wordRepository.getWordsByAsc().getValue());words.addSource(isSortAsc,new Observer(){@Override public void onChanged(@Nullable Boolean isSort){words.postValue(isSort?wordRepository.getWordsByAsc().getValue():wordRepository.getWordsByDesc().getValue();}}});“但是现在我没有任何值,
isSortAsc
需要更改为
LiveData
值(ViewModel类中的setter将设置
isSortAsc.value
(查看我链接到的示例代码以获取完整示例)如果我能很好地理解,我会这样做:“private MutableLiveData isSortAsc;”,我在构造函数中设置:“isSortAsc=new MutableLiveData();isSortAsc.setValue(true);”在方法中设置:“public void sortButtonClicked(){isSortAsc.setValue(!isSortAsc.getValue();}”值总是空的,你看到的值是空的(在哪里)?
words = Transformations.switchMap(isSortAsc, 
    value -> value ? wordRepository.getWordsByAsc() : wordRepository.getWordsByDesc())