RecyclerView:如何使用ViewModel刷新CardViews的完整列表?

时间:2019-06-26 06:19:43

标签: android android-recyclerview android-viewmodel

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

@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过滤列表,效果也很好。

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未加载到列表中。我在这里想念什么?

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

1 个答案:

答案 0 :(得分:0)

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

Method片段内部或Activity内部,您可以在其中获取实时数据观察并将其发送到适配器newData方法。

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();。重新渲染视图,因为数据已更改。