1.
2. public void updateView(int itemIndex) {
3. //得到第一个可显示控件的位置,
4. int visiblePosition = mListView.getFirstVisiblePosition();
5. //只有当要更新的view在可见的位置时才更新,不可见时,跳过不更新
6. if (itemIndex - visiblePosition >= 0) {
7. //得到要更新的item的view
8. View view = mListView.getChildAt(itemIndex - visiblePosition);
9. //从view中取得holder
10. ViewHolder holder = (ViewHolder) view.getTag();
11. HashMap<String, Object> item = data.get(itemIndex);
12.
13. holder.listItem = (RelativeLayout) view.findViewById(R.id.rl_item);
14. holder.ibPlay = (ImageButton) view.findViewById(R.id.ib_play);
15. holder.ibDelete = (ImageButton) view.findViewById(R.id.ib_delete);
16. holder.tvName = (TextView) view.findViewById(R.id.tv_record_sound_name);
17. holder.tvLastModifyTime = (TextView) view
18. .findViewById(R.id.tv_record_time);
19. holder.tvCurrentPlayTime = (TextView) view
20. .findViewById(R.id.tv_current_play_time);
21. holder.tvTotalTime = (TextView) view.findViewById(R.id.tv_total_time);
22. holder.sb = (MySeekBar) view.findViewById(R.id.pb_play);
23. holder.layout = (LinearLayout) view
24. .findViewById(R.id.play_progress_info);
25.
26. updateData(itemIndex, holder, item);
27. }
28. }
自定义一个adapter继承BaseAdapter,写一个如上的方法,要更新数据时,不要调用notifyDataSetChanged()方法,调用上面的方法,即可做到更新单个item
在很多时候ListView列表数据不需要全部刷新,只需刷新有数据变化的那一条,这时可以用getChildAt(index)获取某个指定position的view,并对该view进行刷新。
注意:在ListView中,使用getChildAt(index)的取值,只能是当前可见区域(列表可滚动)的子项!
即取值范围在 >= ListView.getFirstVisiblePosition() && <= ListView.getLastVisiblePosition();
1)所以如果想获取前部的将会出现返回Null值空指针问题;
2)getChildCount跟getCount获取的值将会不一样(数量多时);
3 )如果使用了getChildAt(index).findViewById(...)设置值的话,滚动列表时值就会改变了。
需要使用getFirstVisiblePosition()获得第一个可见的位置,再用当前的position-它,再用getChildAt取值!即getChildAt(position - ListView。getFirstVisiblePosition()).findViewById(...)去设置值
2.如果想更新某一行数据,需要配合ListView的滚动状态使用,一般不滚动时才加载更新数据
//全局变量,用来记录ScrollView的滚动状态,1表示开始滚动,2表示正在滚动,0表示停止滚动
伪代码
ListView设置
public int scrollStates;
class OnScrollListenerImpl implements OnScrollListener{
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
scrollStates = scrollState;
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
int lastInScreen = firstVisibleItem + visibleItemCount;
}
listView.setOnScrollListener(new OnScrollListenerImpl());
Activity中
if(scrollStates==OnScrollListener.SCROLL_STATE_IDLE){
更新视图数据
}
下面这个方法是google 2011年开发者大会上提出的方法——ListView单条更新:
首先我们看一下adapter的getView方法,我们要进行单条刷新就要手动调用这个方法。
public View getView(int
那么这三个参数是如何确定的呢,第三个参数很好确定,就是你的listview。
为了确定另外两个参数position和converView,这里介绍几个lisView的新方法:
getFirstVisiblePosition(),该方法获取当前状态下list的第一个可见item的position。
getLastVisiblePosition(),该方法获取当前状态下list的最后一个可见item的position。
getItemAtPosition(int position),该方法返回当前状态下position位置上listView的convertView
ps:这里的convertView是复用的,也就是说不管position的值是多大(这个要看你整个list有多大),converView的个数应该始终是屏幕上能显示的list的条数那么多。
所 以,我们通过从getFirstVisiblePosition的值到getLastVisiblePosition的值之间的listitem和需要进 行更新的条件(比如id)进行比较确定哪一个是要更新的(如果不在当前可是范围内也就没有必要更新了,等list拉动的时候自然就会更新出来)
private void updateSingleRow(ListView listView, long id) {
if (listView != null) {
int start = listView.getFirstVisiblePosition();
for (int i = start, j = listView.getLastVisiblePosition(); i <= j; i++)
if (id == ((Messages) listView.getItemAtPosition(i)).getId()) {
View view = listView.getChildAt(i - start);
getView(i, view, listView);
break;
}
}
}