I got the answer on this site about how to express ORDER BY CASE and it's works fine.
like bellow
Dao:
@Query("SELECT * FROM decks ORDER BY " +
"CASE WHEN :parameter = 0 THEN dateTime END ASC, " +
"CASE WHEN :parameter = 1 THEN dateTime END DESC, " +
"CASE WHEN :parameter = 2 THEN deckName END ASC, " +
"CASE WHEN :parameter = 3 THEN deckName END DESC")
List<Deck> getAllDecksByOrder(int parameter);
But When I press the AVD's run app button,the user select order of recycler view return to the default order(in this case parameter = 0 although I didn't define it).
How Can I persist the state of order changed by user(onOptionsItemSelected)?Idon't have idea to handle this.
excerpted code bellow
Thank you.
Repository
public class DeckRepository {
private final MutableLiveData<List<Deck>> searchResults
= new MutableLiveData<>();
private List<Deck> results;
private final DeckDao deckDao;
.
public DeckRepository(Application application){
RoomDatabase db;
db = RoomDatabase.getDatabase(application);
deckDao = db.deckDao();
}
Handler handler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg){
searchResults.setValue(results);
}
};
public void getAllDecksByOrder(int parameter){
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() ->{
results = deckDao.getAllDecksByOrder(parameter);
handler.sendEmptyMessage(0);
});
executor.shutdown();
}
public MutableLiveData<List<Deck>> getSearchResults(){
return searchResults;
}
}
mainViewModel
public class MainViewModel extends AndroidViewModel{
private DeckRepository repository;
private MutableLiveData<List<Deck>> searchResults;
public MainViewModel(Application application){
super(application);
repository = new DeckRepository(application);
searchResults = repository.getSearchResults();
}
public MutableLiveData<List<Deck>> getSearchResults(){
return searchResults;
}
public void getAllDecksByOrder(int parameter){
repository.getAllDecksByOrder(parameter);
}
}
MainFragment
public class MainFragment extends Fragment implements NoticeDialogFragment.NoticeDialogListener {
private MainViewModel mViewModel;
private DeckListAdapter adapter;
int parameter;
.
.
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.order_dateTime_ASC: {
mViewModel.getAllDecksByOrder(0);
return true;
}
case R.id.order_dateTime_DESC: {
mViewModel.getAllDecksByOrder(1);
return true;
}
case R.id.order_question_ASC: {
mViewModel.getAllDecksByOrder(2);
return true;
}
case R.id.order_question_DESC: {
mViewModel.getAllDecksByOrder(3);
return true;
}
default:
return super.onOptionsItemSelected(item);
}
}
.
.
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mViewModel = new ViewModelProvider(this).get(MainViewModel.class);
mViewModel.getAllDecksByOrder(parameter);
mViewModel.getSearchResults().observe(getViewLifecycleOwner(), new Observer<List<Deck>>() {
@Override
public void onChanged(@Nullable final List<Deck> decks) {
adapter.setDeckList(decks);
}
});
}
.
.
}
Entity
@Entity(tableName = "decks")
public class Deck {
@PrimaryKey(autoGenerate = true)
@NonNull
@ColumnInfo(name = "deckId")
private int id;
@ColumnInfo(name = "deckName")
private String name;
@ColumnInfo(name = "deckListCount")
private int listCount;
private LocalDateTime dateTime;
public Deck(String name, int listCount, LocalDateTime dateTime){
this.name = name;
this.listCount = listCount;
this.dateTime = dateTime;
}
.
.
}
I figured it out by ordinary way in roomdatabase (add feild for parameter in this case in Entity. update parameter in Query and retrieve it in Livedata's observe.).