如何更新RecyclerView的视图-不传递数据副本

时间:2018-08-16 23:36:32

标签: android android-recyclerview recycler-adapter android-viewholder

我想每30秒更新一次RecyclerView视图的视图。我使用以下语句:

adapter.notifyItemRangeChanged(0, channelsInGroup.size());

,它不起作用。我可以通过将内容复制到新的arraylist,将新的arraylist传递给适配器,然后清空来使其工作 新的数组列表,并在更新后重新填充它,最后调用notifyItemRangeChanged

channelsInGroup.clear();

g = channelsLab.getGroupByTitle(mGroupTitle)
List<Channel> channelListNew = new ArrayList<Channel>();
for (Channel c : g.getChannels()) {
    channelListNew.add(c);
}

channelsInGroup.addAll(channelListNew);
adapter.notifyItemRangeChanged(0, channelsInGroup.size());

如何在不必传递arraylist副本的情况下更新RecyclerView中的视图?我想使用原始的g.getChannels(),它会定期更新。

相关代码段:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    mRootView = inflater.inflate(R.layout.fragment_channel_epg, container, false);

    RecyclerView recyclerView = mRootView.findViewById(R.id.recyclerView);
    LinearLayoutManager horizontalLayoutManagaer
            = new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false);
    recyclerView.setLayoutManager(horizontalLayoutManagaer);

    adapter = new MyRecyclerViewAdapter(getContext(), channelsInGroup);
    recyclerView.setAdapter(adapter);

    return mRootView;
}

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

    private List<Channel> mChannelsList;
    private LayoutInflater mInflater;

    MyRecyclerViewAdapter(Context context, List<Channel> channelList) {
        this.mInflater = LayoutInflater.from(context);
        this.mChannelsList = channelList;
    }

    @Override
    @NonNull
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = mInflater.inflate(R.layout.epg_row_of_playing_channel, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        if (mChannelsList.get(position).getProgrammeListNext24Hours() != null) {
           holder.myTextView.setText(mChannelsList.get(position).getProgrammeListNext24Hours().get(0).getTitle().get(0));
        }
        else {
            holder.myTextView.setText("yok");
        }
    }

    @Override
    public int getItemCount() {
        return mChannelsList.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        TextView myTextView;

        ViewHolder(View itemView) {
            super(itemView);
            myTextView = itemView.findViewById(R.id.programme_description_in_epg_bar);
        }
    }
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    channelsLab = ChannelsLab.get(BKD_ChannelEPGFragment.this.getContext());
    g = channelsLab.getGroupByTitle(mGroupTitle);
    channelsInGroup = g.getChannels();

}

2 个答案:

答案 0 :(得分:1)

如果要对新旧列表之间的变化进行动画处理,则可以使用DiffUtil而不需要调用任何notify方法。创建一个扩展DiffUtil.Callback的类,如下所示。

public class MyDiffCallback extends DiffUtil.Callback {

    List<Channel> oldList;
    List<Channel> newList;

    MyDiffCallback(List<Channel> oldList, List<Channel> newList) {
        oldList = this.oldList;
        newList = this.newList;
    }

    public int getOldListSize() {
        return oldList.size;
    }

    public int getNewListSize() {
        return newList.size;
    }

    @Override
    public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
        // If you have an id for the data then it should be used here.
        return oldList.get(oldItemPosition).id == newList.get(newItemPosition).id;
    }

    @Override
    public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
        // Replace id with whatever is appropriate to check if the contents are the same.
        return oldList.get(oldItemPosition).id  == newList.get(newItemPosition).id;
    }
}

然后在适配器内部创建一个方法来计算差异并交换数据。

public void swap(List<Channel> channelList) {
    MyDiffCallback diffCallback = new MyDiffCallback(mChannelsList, channelList);
    DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(diffCallback);
    mChannelsList.clear();
    mChannelsList.addAll(channelList);
    diffResult.dispatchUpdatesTo(this);
}

现在您可以执行adapter.swap(newList),其中newList应该包含旧数据和新数据。

要将新项添加到列表中而不包括旧数据,只需从mChannelsList.clear()中删除swap()并为其提供要添加到列表中的新数据即可。

答案 1 :(得分:0)

只需致电adapter.notifyDataSetChanged()