方案1:
针对需要更新的item调用public View getView(int position, View convertView, ViewGroup parent)即可。
如:
public class AuthorListAdapter extends BaseAdapter { ... @Override public View getView(int position, View convertView, ViewGroup parent) { ... return convertView; } /** * 更新Item视图,减少不必要的重绘 * * @param listView * @param position */ public void updateItemView(ListView listView, int position) { //换算成 Item View 在 ViewGroup 中的 index int index = position - listView.getFirstVisiblePosition(); if (index >= 0 && index < listView.getChildCount()) { //更新数据 AuthorInfo authorInfo = mAuthorInfoList.get(position); authorInfo.setNickName("Google Android"); authorInfo.setMotto("My name is Android ."); authorInfo.setPortrait(R.mipmap.ic_launcher); //更新单个Item View itemView = listView.getChildAt(index); getView(position, itemView, listView); } } }
注意:在ListView中,getChildAt(int position)返回的item是指的可视区域内的第position个元素。使用getChildAt(index)的取值,只能是当前可见区域(列表可滚动)的子项!
即取值范围在 >= ListView.getFirstVisiblePosition() && <= ListView.getLastVisiblePosition();
这里涉及到listview的复用原理,简单来说:一个元素很多的listview,如果页面的可视区域内最多可以看到6个元素,假如它们的index是0-5,那么在内存中只有6个item对象。当第7个item(即index=6)进入到可视区域的时候,那么其实是在复用index=0的item。由于在滑动时getView这个更新控件的方法执行非常频繁,所以肉眼是丝毫看不出这种复用的。
方案2
@Override public View getView(int position, View convertView, ViewGroup parent) { View view = super.getView(position, convertView, parent); view.setTag(getItemId(position)); return view; }
For the update check every element of list, if a view with given id is there it's visible so we perform the update.
private void update(long id) { int c = list.getChildCount(); for (int i = 0; i < c; i++) { View view = list.getChildAt(i); if ((Long)view.getTag() == id) { // update view } } }
It's actually easier than other methods and better when you dealing with ids not positions! Also you must call update for items which get visible.