I have a RecyclerView List of CardViews. I would like the user to be able to filter the List based on CardView types by clicking on different TextViews for the types. The filter works correctly the first time. If I click on the One TextView the List is filtered and the View shows only the One cards. A backspace brings the user back to the full List. Next, the user clicks on the Two TextView. Here is where the problem occurs, as the View shows the filtered List of One cards rather than the epected Two cards. So the observer is defaulting to the original One card filter type rather than the expected Two card filter type.
The same error occurs if the user chooses the Two card TextView first. In this case, only the Two cards are shown in the View as expected. The back space returns the user to the full List. Then a click on the One TextView filters the List again but shows the Two cards rather than the expected One cards.
What am I missing here? I tried to use removeObserver() and removeObservers() after each click on the TextView but no luck. How do I re-use an observer with multiple filter criteria so that I don't have to set up individual observers for each filter that would then require individual methods in the ViewModel, Repository and Dao?
public class MainActivity extends AppCompatActivity {
// for filtering card type
final String type0 = "OneCards";
final String type1 = "TwoCards";
private List<Card> filteredModelList0 = null;
private List<Card> filteredModelList1 = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mViewModel = new ViewModelProvider(this).get(ViewModel.class);
}
public void onClickFilterList(View view) {
// set up an AlertDialog for the user to select a filter
final AlertDialog.Builder alertDialogFilter = new AlertDialog.Builder(MainActivity.this);
LayoutInflater inflaterFilter = getLayoutInflater();
final ViewGroup nullParent = null;
final View dialogLayoutFilter = inflaterFilter.inflate(R.layout.filter_main_aldialog, nullParent);
alertDialogFilter.setView(dialogLayoutFilter);
final AlertDialog dialogFilter = alertDialogFilter.create();
dialogFilter.show();
TextView allOnes = dialogLayoutFilter.findViewById(R.id.AllOnes);
TextView allTwos = dialogLayoutFilter.findViewById(R.id.AllTwos);
allOnes.setOnClickListener(v -> {
mViewModel.getFilteredList(type0).observe(this, filterList -> {
filteredModelList0 = filterList;
if (filterList.size() == 0) {
Toast.makeText(MainActivity.this, "There are no 'One' cards", Toast.LENGTH_SHORT).show();
filteredModelList0 = null;
} else {
cardsAdapter.setCardList(filteredModelList0);
Toast.makeText(MainActivity.this, "There are 'One' cards", Toast.LENGTH_SHORT).show();
}
});
dialogFilter.dismiss();
});
allTwos.setOnClickListener(v -> {
mViewModel.getFilteredList(type1).observe(this, filterList -> {
filteredModelList1 = filterList;
if (filterList.size() == 0) {
Toast.makeText(MainActivity.this, "There are no 'Two' cards", Toast.LENGTH_SHORT).show();
filteredModelList1 = null;
} else {
cardsAdapter.setCardList(filteredModelList1);
Toast.makeText(MainActivity.this, "There are 'Two' cards", Toast.LENGTH_SHORT).show();
}
});
dialogFilter.dismiss();
});
}
ViewModel
public class ViewModel extends AndroidViewModel {
…
private MutableLiveData<List<Card>> filteredList = null;
public LiveData<List<Card>> getFilteredList(String cardType) {
if (filteredList == null) {
filteredList = new MutableLiveData<>();
loadFilteredCards(cardType);
}
return filteredList;
}
public void loadFilteredCards(String cardType){
filteredList.postValue(repository.getFilteredCards(cardType));
}
Adapter
…
public class Adapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public List<Card> mListItems;
…
public void setCardList(List<Card> newList) {
if (mListItems != null) {
PostDiffCallback postDiffCallback = new PostDiffCallback(mListItems, newList);
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(postDiffCallback);
mListItems.clear();
mListItems.addAll(newList);
diffResult.dispatchUpdatesTo(this);
} else { // first initialization.
mListItems = newList;
}
}
}
from Android: how do I use observer for multiple filter criteria?
No comments:
Post a Comment