向AndroidViewModel传递参数遇阻,Room教程扩展问题求助
问题原因分析
你的问题核心在于ViewModel的初始化时机:当你通过ViewModelProviders.of(this).get(WordViewModel.class)创建ViewModel实例时,它的构造函数会立刻执行——此时mode的默认值是0,mAllWords已经被初始化为mRepository.getAllWords()返回的LiveData。之后你再设置mode=1,构造函数早已执行完毕,不会触发mAllWords的重新初始化,所以你观察到的始终是构造时生成的那个LiveData,自然看不到预期的变化。
最简单的解决方案
不需要在ViewModel里维护mode状态字段,直接通过方法参数传递查询条件,让ViewModel根据参数返回对应的LiveData即可。这种方式不仅解决当前问题,还能轻松扩展后续的多参数需求。
修改后的WordViewModel代码:
public class WordViewModel extends AndroidViewModel { private WordRepository mRepository; public WordViewModel(Application application) { super(application); mRepository = new WordRepository(application); } // 直接接收参数,返回对应的查询结果LiveData public LiveData<List<Word>> getWords(int mode) { if (mode == 0) { return mRepository.getAllWords(); } else { return mRepository.getSomethingElse(); } } public void insert(Word word) { mRepository.insert(word); } }
Activity中的调用代码:
mWordViewModel = ViewModelProviders.of(this).get(WordViewModel.class); // 直接传递mode参数,获取并观察对应的LiveData mWordViewModel.getWords(1).observe(this, new Observer<List<Word>>() { @Override public void onChanged(@Nullable final List<Word> words) { adapter.setWords(words); } });
扩展到多参数场景
如果后续需要传递更多查询参数(比如关键词、排序方式等),只需要扩展getWords方法的参数列表即可,完全不需要创建多个ViewModel:
// 示例:多参数查询 public LiveData<List<Word>> getWords(int mode, String keyword, boolean isAscending) { if (mode == 0) { return mRepository.getWordsByKeyword(keyword, isAscending); } else { return mRepository.getFilteredSomethingElse(keyword); } }
这种方案既简洁又符合ViewModel的设计原则——ViewModel只负责协调仓库和UI层的数据交互,不需要维护额外的业务状态,所有查询条件通过方法参数传递即可。
内容的提问来源于stack exchange,提问作者ro.nin
相关产品推荐
相关产品推荐

