Android RecyclerView 真正的布局刷新的正确方式
来源:互联网 发布:电信网络电视连接不上 编辑:程序博客网 时间:2024/06/05 10:26
在平时使用RecyclerView时,当想进行布局刷新时,我们通常会调用notifyItemChanged(int positon)进行布局刷新,如果item中图片的话,那么刷新就会出现闪烁,这是怎么回事了? 原因就是notifyItemChanged(int positon)是刷新整个item视图的,也就是重新调用onBindViewHolder方法进行item中所有控件的刷新,这自然会造成图片的重新设置了。
那么如果想要精细到刷新某个item中的某个控件呢?下面我就介绍下recyclerView中真正的布局刷新。
首先需要了解Adapter中的两个方法,一个是三个参数的onBindViewHolder(RecyclerView.ViewHolder holder, int position,List payloads),一个是两个参数的notifyItemChanged(int position, Object payload)。
看起来这2个方法比平时使用的多了一个payload参数,那么这个payload究竟有什么意义呢?在我的理解下,我认为payload可以用来存储一些变量值或者常数,然后在notifyItemChanged中传进去payload,指定某个item进行刷新,在这个Item的onBindViewHolder中就可以从第三个参数拿到传过来的payload。下面看看官方的解释。
* The payloads parameter is a merge list from {@link #notifyItemChanged(int, Object)} or* {@link #notifyItemRangeChanged(int, int, Object)}. If the payloads list is not empty,* the ViewHolder is currently bound to old data and Adapter may run an efficient partial* update using the payload info. If the payload is empty, Adapter must run a full bind.* Adapter should not assume that the payload passed in notify methods will be received by* onBindViewHolder(). For example when the view is not attached to the screen, the* payload in notifyItemChange() will be simply dropped.* @param payloads A non-null list of merged payloads. Can be empty list if requires full* update.
也就是说payloads是一个从notifyItemChanged(int, Object)中第二个参数和#notifyItemRangeChanged(int, int, Object)中第三个参数传进来的一个参数。如果payloads不为空并且viewHolder已经绑定了旧数据了,那么adapter会使用payloads参数进行布局刷新。如果payloads为空,adapter就会重新绑定数据,也就是刷新整个item。但是adapter不能保证payload通过nofityItemChanged方法会被onBindViewHolder接收,例如当view没有绑定到screen时,payloads就会失效被丢弃。
{#notifyItemChanged(int, Object)} or { #notifyItemRangeChanged(int, int, Object)}
public final void notifyItemChanged(int position, Object payload) { mObservable.notifyItemRangeChanged(position, 1, payload); }public final void notifyItemRangeChanged(int positionStart, int itemCount, Object payload) { mObservable.notifyItemRangeChanged(positionStart, itemCount, payload); }
当我们调用只有一个参数的notifyItemChanged(int position)时 默认payload为null 也即会进行整个itemd的全部刷新,所以会造成图片闪烁的原因就是在这里。
public final void notifyItemChanged(int position) { mObservable.notifyItemRangeChanged(position, 1); }mObservable中的notifyItemRangeChanged方法public void notifyItemRangeChanged(int positionStart, int itemCount) { notifyItemRangeChanged(positionStart, itemCount, null);//payload为null 进行整个item的刷新 }
使用方法:
@Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { //为空 不使用 } @Override public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position,List payloads) { final ContactHolder contact= (ContactHolder) holder; if(payloads.isEmpty()){//payloads为空 即不是调用notifyItemChanged(position,payloads)方法执行的 //在这里进行初始化item全部控件 contact.userName.setText(mList.get(position).getName()); contact.userId.setText(mList.get(position).getId()); contact.userImg.setImageResources(mList.get(position).getImg()); }else{//payloads不为空 即调用notifyItemChanged(position,payloads)方法后执行的 //在这里可以获取payloads中的数据 进行局部刷新 //假设是int类型 int type= (int) payloads.get(0);// 刷新哪个部分 标志位 switch(type){ case 0: contact.userName.setText(mList.get(position).getName());//只刷新userName break; case 1: contact.userId.setText(mList.get(position).getId());//只刷新userId break; case 2: contact.userImg.setImageResources(mList.get(position).getImg());//只刷新userImg break; } } } public class ContactHolder extends RecyclerView.ViewHolder{ public CheckBox checkBox; public TextView userName; public TextView userId; public ImageView userImg; public ContactHolder(View itemView) { super(itemView); checkBox= (CheckBox) itemView.findViewById(R.id.ContactSelect_list_item_checkBox); userName= (TextView) itemView.findViewById(R.id.ContactSelect_list_item_user_name); userId= (TextView) itemView.findViewById(R.id.ContactSelect_list_item_user_employeeId); userImg= (ImageView) itemView.findViewById(R.id.ContactSelect_list_item_img); } }
调用adapter.notifyItemChanged(position,payloads)或者直接在adapter中直接调用notifyItemChanged(position,payloads)进行刷新
mList.get(100).setName("Jason");notifyItemChanged(100,0);//刷新position为100上的userNamemList.get(102).setName("Yukito");notifyItemChanged(102,0);//刷新position为102上的userNamemList.get(10).setId("12306");notifyItemChanged(10,1);//刷新position为10上的userIdmList.get(100).setId("Jason");mList.get(11).setId("110");notifyItemChanged(11,0);//刷新position为11上的userIdmList.get(20).setImg(R.drawable.img_one);notifyItemChanged(20,0);//刷新position为20上的userImgmList.get(26).setImg(R.drawable.img_two);notifyItemChanged(26,0);//刷新position为26上的userImg
RecyclerView中实现checkBox单选布局刷新 实战:
http://blog.csdn.net/qq402164452/article/details/53462037
- Android RecyclerView 真正的布局刷新的正确方式
- android 打造真正的下拉刷新上拉加载recyclerview(三):下拉刷新上拉加载
- android 打造真正的下拉刷新上拉加载recyclerview(三):下拉刷新上拉加载
- Android RecyclerView中实现ChecckBox单选的正确方式
- android 打造真正的下拉刷新上拉加载recyclerview(一):使用
- android 打造真正的下拉刷新上拉加载recyclerview(二):添加删除头尾部
- android 打造真正的下拉刷新上拉加载recyclerview(四):自动加载和其他封装
- android 打造真正的下拉刷新上拉加载recyclerview(一):使用
- android 打造真正的下拉刷新上拉加载recyclerview(二):添加删除头尾部
- android 打造真正的下拉刷新上拉加载recyclerview(四):自动加载和其他封装
- RecyclerView添加Header的正确方式
- RecyclerView添加Header的正确方式
- RecyclerView添加Header的正确方式
- RecyclerView添加Header的正确方式
- android RecyclerView的复杂布局
- android RecyclerView的复杂布局
- RecyclerView的几种布局方式
- android studio导入recyclerview的正确姿势
- jmp far ptr 标号
- 成绩处理函数版
- super()与this()的区别?
- [转]mysql group by 用法解析(详细)
- 前端--React-tutorial(入门书籍)
- Android RecyclerView 真正的布局刷新的正确方式
- HDOJ 2066 一个人的旅行(Dijstra 类似多源最短路)
- 64bit windows odbc
- ProtocolBuffer ObjectiveC配置使用
- ADB can't work
- 【腾讯优测干货分享】越用越卡为哪般——如何降低App的待机内存(一)
- javascirpt prototype
- spring,springmvc,mybatis基本整合(一)--xml文件配置方式(1)
- 使用axis2解析wsdl生成Webservice客户端代码