以编程方式向RecyclerView添加新项目?

130

我仍在努力理解recyclerview。 我有一个ArrayList,我使用它来初始化一个recycler view。

在设置适配器和布局管理器之后,如何向recycler视图添加新项?

private void initData() {
        mItems = new ArrayList<String>();
        for (int i = 0; i < ITEMS_COUNT; i++) {
            mItems.add("Item " + (i + 1));
        }
    }

    private void initRecyclerView() {
        mRecentRecyclerView = (RecyclerView) findViewById(R.id.recentrecyclerView);
        mRecentRecyclerView.setHasFixedSize(true);
        mRecentLayoutManager = new LinearLayoutManager(this);
        mRecentRecyclerView.setLayoutManager(mRecentLayoutManager);



        mAdapter = new RecyclerView.Adapter<CustomViewHolder>() {
            @Override
            public CustomViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
                View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.notice_snippet
                        , viewGroup, false);
                return new CustomViewHolder(view);
            }

            @Override
            public void onBindViewHolder(CustomViewHolder viewHolder, int i) {
                viewHolder.noticeSubject.setText(mItems.get(i));
            }

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

        };
        mRecentRecyclerView.setAdapter(mAdapter);

    private class CustomViewHolder extends RecyclerView.ViewHolder {

        private TextView noticeSubject;

        public CustomViewHolder(View itemView) {
            super(itemView);

            noticeSubject = (TextView) itemView.findViewById(R.id.notice_subject);
        }
    }

基本上,在我完成initdata()initRecyclerView()之后,我应该如何向RecyclerView中添加一个新项?


你可以在Github上查看此示例。祝你编码愉快! - Cabezas
3个回答

306

首先将您的项目添加到mItems,然后使用:

mAdapter.notifyItemInserted(mItems.size() - 1);

使用此方法优于使用:

mAdapter.notifyDataSetChanged();

在性能方面。


15
好的回答。这也意味着它不会破坏动画效果。 - Ben Pearson
7
这应该被接受为正确答案,另一个会破坏动画并且比这个方案效率更低。 - Massimo
34
我是回答被采纳的那个人,我认为这个应该被采纳:D。 - Abdelrahman Elkady
2
@AJW 是的,mItems 的最后一个元素的索引是 mItems.size()-1。 - Mostafa
2
谢谢!在onBindViewHolder中我有一些应该从互联网上加载的图片。每次接收到数据,我都需要将其添加到列表中,并调用notifyDataSetChanged()方法。但是这会导致图像闪烁的效果。上面提到的是我一直在寻找的正确解决方案。你也可以使用mAdapter.notifyItemRangeInserted(mItems.size() - 1, new_array_of_items_to_be_added.size()); - GOBINATH.M
显示剩余5条评论

45

只需将其添加到您的数据结构(mItems)中,然后通知适配器数据集已更改即可。

private void addItem(String item) {
  mItems.add(item);
  mAdapter.notifyDataSetChanged();
}

addItem("New Item");

2
如果我想添加的不是字符串,而是ViewGroup呢? - IgorGanapolsky
1
@IgorGanapolsky 我也有同样的疑问。你找到解决办法了吗? - Sash_KP
这里也有同样的疑问!需要帮助吗? - Srujan Barai
我想要从另一个适配器类中调用 addItem() 方法,但是 addItem() 是一个非静态方法,因此不能接受非静态调用。我应该使用哪个对象来调用这个方法? - Srujan Barai
5
@IgorGanapolsky Adapter会指定item类型,因此它可以是任何对象。但请记住,您添加的item只是数据。RecyclerView具有内置函数,用于填充和绑定视图,这是在调用notifyDataSetChanged()时发生的。您可以调试onBindViewHolder以查看正在编辑的视图。 - Chris
1
@IgorGanapolsky 您的 ArrayList<T> 必须使用您想要添加的对象类型,例如 ArrayList<ViewGroup> 而不是 ArrayList<String>。然后,您只需将参数类型从 String 更改为 ViewGroup 即可。(抱歉打扰了)。 - Eric Reed

18

如果您要将多个项目添加到列表中,请使用以下方法:

mAdapter.notifyItemRangeInserted(startPosition, itemcount);

该操作通知任何已注册的观察者,从positionStart位置开始的当前反映itemCount个项目已经新插入。之前位于positionStart及其后面的项目现在可以从位置positinStart+itemCount开始找到。

数据集中现有的项目仍被认为是最新的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接