RecyclerView:如何使用ViewModel刷新CardViews的完整列表? [英] RecyclerView: how to refresh full List of CardViews with ViewModel?

查看:65
本文介绍了RecyclerView:如何使用ViewModel刷新CardViews的完整列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Main Activity,它通过RecyclerView扩展了AppCompatActivity.从Room数据库加载CardViews列表,然后过滤列表,效果很好.按退格键将用户返回到原始列表后,会出现问题.

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

我通过单击TextView过滤列表,效果也很好.

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();
  }
});

如果列表当前已被过滤,然后用户按Back Backspace,我想将用户返回到原始的RecyclerView列表.这是我的问题所在. CardViews未加载到列表中.我在这里想念什么?

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();
  }
}

适配器

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

推荐答案

当您从ViewModel实时数据观察中接收到数据时,请使用onChanged方法

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

在片段内部或活动"内部的方法,您可以在其中获取实时数据观察并发送到适配器newData方法.

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

适配器的方法

 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();
    }

主要是您必须调用notifyDataSetChanged();.重新渲染视图,因为数据已更改.

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

这篇关于RecyclerView:如何使用ViewModel刷新CardViews的完整列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆