前言:
初学者在学习RecyclerView这个控件后,会不自觉地使用setAdapter()
来更新数据。在初学或教学过程中该方式或许没有问题。然而在实际开发或较高更新性能状态下该方式是不可取的,可能会造成OOM或No Adapter/Skip Layout等问题。与Java中线程资源更新方式类型,RecyclerView数据的更新同样使用notify()
家族进行更新。本文将快速帮助初学者使用正确方式进行更新数据源。
一:notifyItemChanged()
该方法使用类是适配器,作用是更新某个item子项的数据。需要说明的是,该更新方式不仅可以更新文字,图片等资源也是可以的。示例方法如下:
private void itemNotifyItemChanged(){
Bean bean = beanList.get(2);
bean.setImageViewId(R.drawable.app);
beanAdapter.notifyItemChanged(2);
}
说明:itemNotifyItemChanged()
这个方法是我们自己写的。在该方法里面,首先通过RecyclerView的数据源(某个List集合或其它泛型集合)的获得具体下标索引的Bean对象。然后更新该Bean的图片资源,最后通过适配器的notifyItemChanged()
更新下标为2的第三项item子项。那么当我们想要更新时,只需要调用我们写的该方法即可。
二:notifyItemInsert()
该方法使用类是适配器,作用是插入RecyclerView的具体索引位置的item数据(就是在第几项插入数据)。
private void itemNotifyItemInsert(){
Bean bean = new Bean(R.drawable.app,"App");
beanList.add(2, bean);
beanAdapter.notifyItemInserted(2);
}
说明:itemNotifyItemInsert()
仍然是我们自己写的(目的是为了减少耦合)。在该方法里面,首先创建一个Bean对象并把基本数据存入。然后使用泛型集合插入具体索引位置的数据,最后通过notifyItemInserted()
在第三项后插入一个item数据。
三:notifyItemRemoved()
该方法使用类是适配器,作用是删除RecyclerView的具体索引位置的item数据(就是在第几项删除数据)。
private void itemNotifyItemRemoved(){
beanList.remove(1);
beanAdapter.notifyItemRemoved(1);
}
说明:首先先移除我们数据源具体索引位置的数据,这里移除的是第二项,然后调用notifyItemRemoved()
方法也移除第二项的item子项。
四:notifyItemRangeRemoved()
该方法使用类是适配器,作用是删除RecyclerView的具体索引位置到指定长度的item数据(就是在第几项删除数据一直删除多少个为止)。
private void itemNotifyItemRangeRemoved(){
beanList.remove(2);
beanList.remove(2);
beanAdapter.notifyItemRangeRemoved(2,2);
}
说明:这里先删除数据源从第三项开始长度为2的数据(就是删除第三项、第四项),然后调用notifyItemRangeRemoved()
方法删除指定索引位置指定长度的数据。第一参数为要删除的数据索引位置,第二个是要删除的长度。
五:notifyItemRangeInserted()
该方法使用类是适配器,作用是插入RecyclerView的具体索引位置到指定长度的item数据(就是在第几项插入数据一直插入多少个为止)。
private void itemNotifyItemInsertRange(){
List<Bean> addBeanList = new ArrayList<Bean>();
addBeanList.add(new Bean(R.drawable.app, "Google"));
addBeanList.add(new Bean(R.drawable.app, "Google"));
addBeanList.add(new Bean(R.drawable.app, "Google"));
addBeanList.add(new Bean(R.drawable.app, "Google"));
addBeanList.add(new Bean(R.drawable.app, "Google"));
beanList.addAll(2, addBeanList);
beanAdapter.notifyItemRangeInserted(2,5);
}
说明:这里我们先创建一个数据源,然后添加数据。接着调用泛型集合的addAll()
方法,将待插入的数据源插入,最后调用notifyItemRangeInserted()
插入完成,该方法第一个参数为要插入的位置开始,第二个待插入的长度。
如果读者对全局代码有所疑惑,请看下面:
public class MainActivity extends AppCompatActivity {
private Button buttonUpdate;
private RecyclerView recyclerView;
private BeanAdapter beanAdapter;
private List<Bean> beanList = new ArrayList<Bean>();
private void initData(){
beanList.add(new Bean(R.drawable.apple, "Apple"));
beanList.add(new Bean(R.drawable.music, "Apple"));
beanList.add(new Bean(R.drawable.apple, "Apple"));
beanList.add(new Bean(R.drawable.music, "Apple"));
beanList.add(new Bean(R.drawable.apple, "Apple"));
beanList.add(new Bean(R.drawable.music, "Apple"));
beanList.add(new Bean(R.drawable.apple, "Apple"));
beanList.add(new Bean(R.drawable.music, "Apple"));
beanList.add(new Bean(R.drawable.apple, "Apple"));
beanList.add(new Bean(R.drawable.music, "Apple"));
beanList.add(new Bean(R.drawable.apple, "Apple"));
beanList.add(new Bean(R.drawable.music, "Apple"));
beanList.add(new Bean(R.drawable.apple, "Apple"));
beanList.add(new Bean(R.drawable.music, "Apple"));
beanList.add(new Bean(R.drawable.apple, "Apple"));
beanList.add(new Bean(R.drawable.music, "Apple"));
}
private void initRecyclerView(Context context){
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
initData();
beanAdapter = new BeanAdapter(beanList, context);
recyclerView.setAdapter(beanAdapter);
}
private void initView(){
buttonUpdate = (Button) findViewById(R.id.button_update);
}
private void itemNotifyItemChanged(){
Bean bean = beanList.get(2);
bean.setImageViewId(R.drawable.app);
beanAdapter.notifyItemChanged(2);
}
private void itemNotifyItemInsert(){
Bean bean = new Bean(R.drawable.app,"App");
beanList.add(2, bean);
beanAdapter.notifyItemInserted(2);
}
private void itemNotifyItemRemoved(){
beanList.remove(1);
beanAdapter.notifyItemRemoved(1);
}
private void itemNotifyItemInsertRange(){
List<Bean> addBeanList = new ArrayList<Bean>();
addBeanList.add(new Bean(R.drawable.app, "Google"));
addBeanList.add(new Bean(R.drawable.app, "Google"));
addBeanList.add(new Bean(R.drawable.app, "Google"));
addBeanList.add(new Bean(R.drawable.app, "Google"));
addBeanList.add(new Bean(R.drawable.app, "Google"));
beanList.addAll(2, addBeanList);
beanAdapter.notifyItemRangeInserted(2,4);
}
private void itemNotifyItemRangeRemoved(){
beanList.remove(2);
beanList.remove(2);
beanAdapter.notifyItemRangeRemoved(2,2);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initRecyclerView(MainActivity.this);
buttonUpdate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
itemNotifyItemRemoved();
}
});
}
}