kodeusz
kodeusz

Reputation: 188

How can I change in ViewModel source of my LiveData from Room Dao

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

Answers (4)

Zac
Zac

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

AnasAbubacker
AnasAbubacker

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

John O&#39;Reilly
John O&#39;Reilly

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

AnasAbubacker
AnasAbubacker

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

Related Questions