RecyclerView、LIstView的局部刷新
程序员文章站
2022-06-17 13:52:06
...
最近项目中用到了点击显示下拉列表,列表呀当然要用list显示啊,当然也可以不用,有人说,可以简单粗暴的用死布局直接刚。好了,那个说直接刚的人你可以闭嘴了,数据是后台返的,是变化的,这样只能用列表来动态的显示数据,再加上后来还加入了一个点击颜色变化的需求,遂才引出这篇文章,List列表的局部更新。
一、RecyclerView局部刷新
RecyclerView的局部刷新是有区分的,有数据的刷新和 item 结构的刷新,局部的 item 插入、删除、移动刷新方法都是结构的刷新。而 notifyItemChanged、notifyItemRangeChanged 方法属于数据的刷新。
1. 数据刷新
数据刷新还分全部刷新和局部刷新,
全部刷新:**notifyDataSetChanged()**,**notifyItemChanged(int)**;
局部刷新:**notifyItemRangeChanged(int,int)**(从指定位置开始刷新指定个item),
**notifyItemChanged(int, Object)**。
这里notifyItemChanged,第二个参数控制刷新全部还是局部,如:
@Override
public void onBindViewHolder(MyViewHolder holder, final int position, List<Object> payloads) {
super.onBindViewHolder(holder, position, payloads);
if (payloads.isEmpty()){
//全部刷新
}else {
//局部刷新
}
}
这里主要讲刷新指定item。
2. item 结构刷新
结构刷新分:插入、移动、移除一个并自动刷新
插入:notifyItemInserted(int)
用法:
/**
* 添加并更新数据,同时具有动画效果
*/
public void addDataAt(int position, DataBean data) {
mDatas.add(position, data);
notifyItemInserted(position);//更新数据集,注意如果用adapter.notifyDataSetChanged()将没有动画效果
}
移动:notifyItemMoved(int)
移除:notifyItemRemoved(int)
用法:
/**
* 移除并更新数据,同时具有动画效果
*/
public void removeDataAt(int position) {
mDatas.remove(position);
notifyItemRemoved(position);
}
二、ListView局部刷新
非notifyDataSetChanged方式。
方法一:更新对应view的内容
item点击事件{
datas.set(position, "改变当前位置数据" + position);
updateSingle(position);//要更新的位置
}
/**
*
* @param position 要更新的位置
*/
private void updateSingle(int position) {
/**第一个可见的位置**/
int firstVisiblePosition = listView.getFirstVisiblePosition();
/**最后一个可见的位置**/
int lastVisiblePosition = listView.getLastVisiblePosition();
/**在看见范围内才更新,不可见的滑动后自动会调用getView方法更新**/
if (position >= firstVisiblePosition && position <= lastVisiblePosition) {
/**获取指定位置view对象**/
View view = listView.getChildAt(position - firstVisiblePosition);
TextView textView = (TextView) view.findViewById(R.id.textView);
textView.setText(datas.get(position));
}
}
方法二:通过ViewHolder去设置值
/**
* 找出对应的ViewHolder,通过ViewHolder去设置值
*
* @param position 要更新的位置
*/
private void updateOne(int position) {
/**第一个可见的位置**/
int firstVisiblePosition = listView.getFirstVisiblePosition();
/**最后一个可见的位置**/
int lastVisiblePosition = listView.getLastVisiblePosition();
/**在看见范围内才更新,不可见的滑动后自动会调用getView方法更新**/
if (position >= firstVisiblePosition && position <= lastVisiblePosition) {
/**获取指定位置view对象**/
View view = listView.getChildAt(position - firstVisiblePosition);
/**通过ViewHolder找出缓存的对应控件**/
TextView textView = CommonViewHolder.get(view, R.id.textView);
textView.setText(datas.get(position));
}
}
方法三:调用一次getView()方法
这种方法是调用适配器对应的getView方法,用它里面的代码对界面进行刷新。这也是google在IO大会上推荐的做法
item点击事件{
datas.set(position, "改变当前位置数据" + position);
updateItem(position);//要更新的位置
}
/**
* 调用一次getView()方法;Google推荐的做法
*
* @param position 要更新的位置
*/
private void updateItem(int position) {
/**第一个可见的位置**/
int firstVisiblePosition = listView.getFirstVisiblePosition();
/**最后一个可见的位置**/
int lastVisiblePosition = listView.getLastVisiblePosition();
/**在看见范围内才更新,不可见的滑动后自动会调用getView方法更新**/
if (position >= firstVisiblePosition && position <= lastVisiblePosition) {
/**获取指定位置view对象**/
View view = listView.getChildAt(position - firstVisiblePosition);
commonAdapter.getView(position, view, listView);
}
}
最后,参考链接:
DylanAndroid的csdn博客