更新Adapter
自始至终只用一个adapter和list,并对其update。
Adapter有4个方法:notify()、notifyAll()、notifyDataSetChanged ()、notifyDataSetInvalidated (),区别如下:
1.notify()和notifyAll()一般用于唤醒被锁或等待中adapter的情况:
notify()和notifyAll()都是Object对象用于通知处在等待该对象的线程的方法。
void notify():唤醒一个正在等待该对象的线程。
void notifyAll():唤醒所有正在等待该对象的线程。
两者的最大区别在于:
notifyAll使所有原来在该对象上等待被notify的线程统统退出wait的状态,变成等待该对象上的锁,一旦该对象被解锁,他们就会去竞争。
notify他只是选择一个wait状态线程进行通知,并使它获得该对象上的锁,但不惊动其他同样在等待被该对象notify的线程们,当第一个线程运行完毕以后释放对象上的锁,此时如果该对象没有再次使用notify语句,即便该对象已经空闲,其他wait状态等待的线程由于没有得到该对象的通知,继续处在wait状态,直到这个对象发出一个notify或notifyAll,它们等待的是被notify或notifyAll,而不是锁。
2.notifyDataSetChanged和notifyDataSetInvalidated 一般用于adapter的数据发生变化的时候调用:
notifyDataSetChanged方法通过一个外部的方法控制如果适配器的内容改变时需要强制调用getView来刷新每个Item的内容。
notifyDataSetChanged ()该方法内部实现了在每个观察者上面调用onChanged事件。每当发现数据集有改变的情况,或者读取到数据的新状态时,就会调用此方法。
notifyDataSetInvalidated ()该方法内部实现了在每个观察者上面调用onInvalidated事件。每当发现数据集监控有改变的情况,比如该数据集不再有效,就会调用此方法。
notifyDataSetInvalidated(),会重绘控件(还原到初始状态)
notifyDataSetChanged(),重绘当前可见区域
参考链接:http://blog.csdn.net/u013742672/article/details/72956905
所以,只是更新listview的list个数时,可以用notifyDataSetChanged,eg:
dataList.add\(addNumber\); adapter.notifyDataSetChanged\(\);
但是,如果要更新expandableList某个childView中内容时,比如随着uploadTask更新progressBar,要用notifyDataSetInvalidated, 否则只用notifyDataSetChanged或不notify的话,只能手动unfold/fold groupView来更新childView, eg:
uploadTask.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>(){
@Override
@SuppressWarnings("VisibleForTests")
public void onProgress(UploadTask.TaskSnapshot taskSnapshot){
int progress = (int) (100.0 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount();
if (progres % 10 == 0) {
docAdapter.progress = progress;
docAdapter.notifyDataSetInvalidated();
}
}
});
RecyclerView的Adapter有新的update方法:
- notifyItemChanged(int position) 更新列表position位置上的数据可以调用
- notifyItemInserted(int position) 列表position位置添加一条数据时可以调用,伴有动画效果
- notifyItemRemoved(int position) 列表position位置移除一条数据时调用,伴有动画效果
- notifyItemMoved(int fromPosition, int toPosition) 列表fromPosition位置的数据移到toPosition位置时调用,伴有动画效果
- notifyItemRangeChanged(int positionStart, int itemCount) 列表从positionStart位置到itemCount数量的列表项进行数据刷新
- notifyItemRangeInserted(int positionStart, int itemCount) 列表从positionStart位置到itemCount数量的列表项批量添加数据时调用,伴有动画效果
- notifyItemRangeRemoved(int positionStart, int itemCount) 列表从positionStart位置到itemCount数量的列表项批量删除数据时调用,伴有动画效果
eg:
http://blog.csdn.net/leejizhou/article/details/51179233
在非UI线程中用notifyItemChanged()不能更新,可以这样:
recyclerView.post(new Runnable() {
@Override
public void run\(\) {
adapter.notifyItemChanged\(0\);
}
});
https://stackoverflow.com/questions/2919778/update-listview-in-the-main-thread-from-another-thread