Reputation: 188
How can I change in ViewModel source of my LiveData from Room Dao. In WordDao I have two queries:
@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();
}
I have also Repository class:
public class WordRepository {
public LiveData<List<Word>> getWordsByAsc() {
return wordDao.getWordsByAsc();
}
public LiveData<List<Word>> getWordsByDesc() {
return wordDao.getWordsByDesc();
}
}
and my ViewModel class:
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()
}
}
In my Activity I have added observer:
wordViewModel.getWords().observe(this, new Observer<List<Word>>() {
@Override
public void onChanged(@Nullable List<Word> words) {
adapter.setWords(words);
}
});
In setWords(words) method I call also "notifyDataSetChanged()".
How change in the viewModel class source of LiveData depending on the "isSortAsc" parameter (words = isSortAsc ? wordRepository.getWordsByAsc() : wordRepository.getWordsByDesc()
It works only after change configuration of screen, not after insta change source for LiveData words
Upvotes: 6
Views: 4539
Reputation: 1072
A solution using Transformations.switchMap
First make isSortAsc
LiveData
private MutableLiveData<Boolean> isSortAsc = new MutableLiveData<Boolean>(true);
Then use Transformations.switchMap on isSortAsc
like so:
words = Transformations.switchMap(isSortAsc,
value -> value ? wordRepository.getWordsByAsc() : wordRepository.getWordsByDesc())
Upvotes: 1
Reputation: 3607
I think here it is simple solution, always query the table ASC ie and reverse the list only in case user choose descending. Collection.Sort() is provided by Android so it should be perform better.
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);
}
}
I hope this will help you.
Upvotes: 0
Reputation: 10350
One approach might be to use MediatorLiveData
....for example:
val words = MediatorLiveData<Word>().apply {
this.addSource(sortDirection) {
if (sortDirection.value) {
this.value = wordRepository.getWordsByAsc()
} else {
this.value = wordRepository.getWordsByDesc()
}
}
}
I do something similar in following (with setting of direction
)
https://github.com/joreilly/galway-bus-android/blob/master/app/src/main/java/com/surrus/galwaybus/ui/viewmodel/BusStopsViewModel.kt
Upvotes: 3
Reputation: 3607
I believe the following function needs to be modified
wordViewModel.getWords().observe(this, new Observer<List<Word>>() {
@Override
public void onChanged(@Nullable List<Word> words) {
adapter.setAdapter(words);
notifyDataSetChanged();
}
});
One more thing the words variable won't have any value until onChanged is triggered. So you have to make sure getWords() should be called only after onChanged()
Upvotes: -1