为什么我的RecyclerView在我不通知适配器时更新了?

时间:2018-01-26 12:20:04

标签: java android android-recyclerview recycler-adapter

我很难理解为什么我的recyclerView会在setAdapter()之后添加数据而不再调用notifyDataSetChanged()时获取更新!

同一类型: - >我在列表中添加3个字符串 - >仅为第一个添加的(notifyItemInserted)

通知适配器

结果:显示3个字符串。

如果有人能帮助我理解我会非常感激他:)。

https://www.noelshack.com/2018-04-5-1516969446-recycler.png

我的代码:

public class MainActivity extends AppCompatActivity {
List<String> mList = new ArrayList<>();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //Call before set adapter so it's normal if show when the adapter is set
    mList.add("Before set the adapter");

    RecyclerView recyclerView = findViewById(R.id.rcv);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    final Adapter mAdapter = new Adapter(mList);
    recyclerView.setAdapter(mAdapter);


    Button button = findViewById(R.id.button);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            mList.add("Button add " +0);
            mAdapter.notifyItemInserted(mList.size()-1);

            //Again it's showing but never notify
            mList.add("Button add " +1);
            mList.add("Button add " +2);
        }
    });

    //Called after setAdapter and NEVER notify the adapter but it's still show the data
    addMoreData();

}


private void addMoreData() {
    for (int i = 0; i < 10; i++) {
        mList.add("addMoreData: " + i);
    }
}


class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
    class ViewHolder extends RecyclerView.ViewHolder {
        TextView nameTextView;

        ViewHolder(View itemView) {

            super(itemView);
            nameTextView = (TextView) itemView.findViewById(R.id.textview);
        }
    }

    @Override
    public Adapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.raw, parent, false);
        return new Adapter.ViewHolder(view);
    }

    private List<String> mList;

    Adapter(List<String> list) {
        mList = list;
    }

    @Override
    public void onBindViewHolder(Adapter.ViewHolder holder, int position) {
        holder.nameTextView.setText(mList.get(position));

    }

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

2 个答案:

答案 0 :(得分:1)

您大多使用通知调用来保持当前显示的视图处于正确状态,但这并不会阻止Adapter将数据提供给其他RecyclerView组件。

如果您的RecyclerView已滚动,您可以非常清楚地看到它 - 如果您更新列表而不通知,然后滚动到底部,您将获得新项目。

在你的情况下,你在最后添加项目并仅通知它 - 购买LayoutManager确定它仍然可以布置更多的视图。

答案 1 :(得分:1)

我认为,由于notifyDataSetChanged的工作原理,这就是结果。

谷歌工程师说;

  

当您调用notifyDataSetChanged时,RecyclerView会使数据无效   但是直到下一个动画帧才更新UI。这是怎么回事   android视图系统有效。当窗口小部件无效时(例如,更改   它的数据)它要求一个布局,这意味着它将被重新测量和   在下一个视图遍历中重新布局。这样做是为了我们可以   批量所有更改,直到下次更新屏幕。

这意味着; nofiyDataSetChanged等待UI线程。因此,代码中notifyItemInserted的以下行并不重要。

    mList.add("Button add " +0);
    mAdapter.notifyItemInserted(mList.size()-1);

    //Again it's showing but never notify
    mList.add("Button add " +1);
    mList.add("Button add " +2);