RecyclerView: how to refresh full List of CardViews with ViewModel?

守給你的承諾、 提交于 2019-12-11 14:58:04

问题


I have a Main Activity that extends AppCompatActivity with a RecyclerView. It is working fine to load a List of CardViews from a Room database and then filter the List. Problem occurs after pressing Back space to return the user to the original List.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(layout.activity_main);
    ...
    mViewModel = ViewModelProviders.of(MainActivity.this).get(MainViewModel.class);
    mViewModel.getAllCards().observe(this, new Observer<List<Card>>() {
        @Override
        public void onChanged(@Nullable final List<Card> cards) {
            if (cards == null) {
                return;
            }
           adapter.setCardList(cards);
        }     
    }); 
}

I filter the List using a click on TextView and that is working fine as well.

allWaitingfors.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
    if (mViewModel.filterListCardTypeWaitingfor() != null) {
        mViewModel.filterListCardTypeWaitingfor().removeObservers((AppCompatActivity) context);
    }
    mViewModel.filterListCardTypeWaitingfor().observe(MainActivity.this, new Observer<List<Card>>() {
        @Override
        public void onChanged(@Nullable final List<Card> filterWaitingforCards) {
            if (filterWaitingforCards != null && filterWaitingforCards.size() == 0) {
                Toast.makeText(MainActivity.this, "There are no cards", Toast.LENGTH_SHORT).show();
            }
            else {
                adapter.setCardList(filterWaitingforCards);
            }
        }
    });
    dialogFilter.dismiss();
  }
});

If the List is currently filtered and then the user presses Back space, I'd like to return the user to the original RecyclerView list. This is where my problem is. The CardViews are not loading in the List. What am I missing here?

@Override
public void onBackPressed() {  
if (mViewModel.filterListCardTypeWaitingfor() != null) {
    mViewModel.filterListCardTypeWaitingfor().removeObservers((AppCompatActivity) context);
    mViewModel.getAllCards().removeObservers((AppCompatActivity) context);
    mViewModel.getAllCards().observe(this, new Observer<List<Card>>() {
    @Override
    public void onChanged(@Nullable final List<Quickcard> cards2) {
        if (cards2 == null) {
            return;
        }
        else {
              adapter.setCardList(cards2);
        }

    });
}
else {
    Toast.makeText(MainActivity.this, "Exit", Toast.LENGTH_SHORT).show();
    MainActivity.this.finish();
    super.onBackPressed();
  }
}

Adapter

public class CardListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

private Context context;
private LayoutInflater layoutInflater;
private List<Card> cardList = Collections.emptyList();

public CardListAdapter(Context context, RecyclerItemClickListener recyclerItemClickListener) {
this.context = context;
this.layoutInflater = LayoutInflater.from(context);
}
…
public void setCardList(List<Card> newCardsList) {

if (cardList != null) {

    PostDiffCallback postDiffCallback = new PostDiffCallback(cardList, newCardsList);
    DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(postDiffCallback);
    cardList.clear();
    this.cardList = newCardsList;
    diffResult.dispatchUpdatesTo(this);
} else {
    this.cardList = newCardsList;
  }
}

class PostDiffCallback extends DiffUtil.Callback {

    private final List<Card> oldPosts, newPosts;

    private PostDiffCallback(List<Card> oldPosts, List<Card> newPosts) {
    this.oldPosts = oldPosts;
    this.newPosts = newPosts;
}

    @Override
    public int getOldListSize() {
        return oldPosts.size();
    }

    @Override
    public int getNewListSize() {
        return newPosts.size();
    }

    @Override
    public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
        return oldPosts.get(oldItemPosition).getId() == newPosts.get(newItemPosition).getId();
    }

    @Override
    public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
       return oldPosts.get(oldItemPosition).equals(newPosts.get(newItemPosition));
    }
}

回答1:


When you received the data from the ViewModel live data observe, in onChanged method

Method Inside fragment or inside Activity where you can get the live data observation and send to adapter newData method.

controlRoomViewModel.getLiveDispatchData().observe(this, new Observer<Dispatch>(){
            @Override
            public void onChanged(@Nullable Dispatch dispatch) {
                if (dispatch != null) {

                    content = dispatch.getContent();
                    adapter.addContentItems((ArrayList<ContentItem>) content);
                }
            }
        });

Method of the adapter

 public void addContentItems(ArrayList<ContentItem> newContentItems) {
        if (newContentItems == null) {
            return;
        }

        if (contentItems != null && contentItems.size() > 0)
            contentItems.clear();

        for (ContentItem contentItem : newContentItems) {
            contentItems.add(contentItem);
        }
        notifyDataSetChanged();
    }

Mainly you have to call notifyDataSetChanged(); to re-render the views because data gots changed.



来源:https://stackoverflow.com/questions/56766367/recyclerview-how-to-refresh-full-list-of-cardviews-with-viewmodel

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!