Search code examples
javaandroidandroid-recyclerviewsql-order-byandroid-room

How Can I persist the state changed by ORDER BY CASE WHEN?


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;
    }
.
.
}

Solution

  • 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.).