我是android开发的新手,正在阅读一些示例代码。我从适配器类(派生自ArrayAdapter)中的示例代码复制了一个方法,派生类除了文本视图之外还有一个复选框:

@Override
public View getView(int position, View convertView, ViewGroup parent) {

  View listItem = super.getView(position, convertView, parent);

  CheckedTextView checkMark = null;
  ViewHolder holder = (ViewHolder) listItem.getTag();
  if (holder != null) {
    checkMark = holder.checkMark;
  } else {
    checkMark = (CheckedTextView) listItem.findViewById(android.R.id.text1);
    holder = new ViewHolder(checkMark);
    listItem.setTag(holder);
  }

  checkMark.setChecked(isInCollection(position));
  return listItem;
}

private class ViewHolder {
  protected final CheckedTextView checkMark;

  public ViewHolder(CheckedTextView checkMark) {
     this.checkMark = checkMark;
  }
}

示例代码是通过在viewholder对象中缓存视图来优化getview。
我感到困惑的是,我认为convertview如果不为空,将被重新使用,然后视图数据被填充到其中并返回。
如果是这样,那么如何依赖代码中调用的settag/gettag方法?看起来,为了让同一个对象工作,必须检索它?

最佳答案

在随后的调用中,gettag返回的视图可能用于不同的列表项,并返回错误的视图
适配器使用回收蛋白。这个类允许listview只创建屏幕上合适的行布局,外加一个或两个用于滚动和预加载的行布局。所以如果你有一个1000行的listview和一个只显示7行的屏幕,那么listviiew很可能只有8个惟一的视图。
现在使用我上面的例子来回答您的问题:只创建了8个行布局和8个后续的视图保持器。当用户滚动时,不会创建新的行布局;只有行布局的内容会更改。因此getTag()将始终具有引用相应视图的有效viewholder。
(有帮助吗?)

07-24 09:44