0

下面是2段代码。每个都有一个名为 IconicAdapter 的内部类。在 getView 方法中,我们创建了一个名为 row 的 View 实例。我的问题是......我们实例化行的方式有什么区别,即。使用布局充气机并使用 super.getview()。如果这个例子没有让区别变得清晰,那么请解释一个我将使用布局充气机的具体例子:

样品 1:

public class DynamicDemo extends ListActivity {
  TextView selection;
  private static final String[] items={"lorem", "ipsum", "dolor",
          "sit", "amet",
          "consectetuer", "adipiscing", "elit", "morbi", "vel",
          "ligula", "vitae", "arcu", "aliquet", "mollis",
          "etiam", "vel", "erat", "placerat", "ante",
          "porttitor", "sodales", "pellentesque", "augue", "purus"};

  @Override
  public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    setContentView(R.layout.main);
    setListAdapter(new IconicAdapter());
    selection=(TextView)findViewById(R.id.selection);
  }

  public void onListItemClick(ListView parent, View v,
                              int position, long id) {
    selection.setText(items[position]);
  }

  class IconicAdapter extends ArrayAdapter<String> {
    IconicAdapter() {
      super(DynamicDemo.this, R.layout.row, items);
    }

    public View getView(int position, View convertView,
                        ViewGroup parent) {
      LayoutInflater inflater=getLayoutInflater();
      View row=inflater.inflate(R.layout.row, parent, false);
      TextView label=(TextView)row.findViewById(R.id.label);

      label.setText(items[position]);

      ImageView icon=(ImageView)row.findViewById(R.id.icon);

      if (items[position].length()>4) {
        icon.setImageResource(R.drawable.delete);
      }
      else {
        icon.setImageResource(R.drawable.ok);
      }

      return(row);
    }
  }
}

样本 2:

public class DynamicDemo extends ListActivity {
  TextView selection;
  private static final String[] items={"lorem", "ipsum", "dolor",
          "sit", "amet",
          "consectetuer", "adipiscing", "elit", "morbi", "vel",
          "ligula", "vitae", "arcu", "aliquet", "mollis",
          "etiam", "vel", "erat", "placerat", "ante",
          "porttitor", "sodales", "pellentesque", "augue", "purus"};

  @Override
  public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    setContentView(R.layout.main);
    setListAdapter(new IconicAdapter());
    selection=(TextView)findViewById(R.id.selection);
  }

  public void onListItemClick(ListView parent, View v,
                              int position, long id) {
    selection.setText(items[position]);
  }

  class IconicAdapter extends ArrayAdapter<String> {
    IconicAdapter() {
      super(DynamicDemo.this, R.layout.row, items);
    }

    public View getView(int position, View convertView,
                        ViewGroup parent) {
      LayoutInflater inflater=getLayoutInflater();
      View row=super.getView(position, convertView, parent);
      TextView label=(TextView)row.findViewById(R.id.label);

      label.setText(items[position]);

      ImageView icon=(ImageView)row.findViewById(R.id.icon);

      if (items[position].length()>4) {
        icon.setImageResource(R.drawable.delete);
      }
      else {
        icon.setImageResource(R.drawable.ok);
      }

      return(row);
    }
  }
}
4

2 回答 2

2

理论上完全没有区别,但在实践中是有区别的。

你忽略了convertView争论,但ArrayAdapter不要。convertView 是用于平滑滚动的棘手优化。滚动时,listview 会定期调用getView提供的适配器上的方法。在您的情况下(示例 #2),您创建了许多垃圾 GC 堆的对象。此外,您每次都在从 XML 中扩充您的布局。ArrayAdapter.getView而不是创建新对象重用旧的,只需调用 textView.setText (顺便说一句,你调用 label.setText 两次:第一次在 super.getView 中,第二次label.setText(items[position])

此外,您View每次都getView通过调用来查询 s 实例findViewById。而不是尝试使用ViewHolder模式

于 2012-08-01T15:07:19.610 回答
2

在第一种情况下,LayoutInflater您使用 a 膨胀布局文件,该文件将View用于ListView' 行。这让您完全覆盖在方法View 中构建行的getView方式。您通常会希望使用它,因为它非常灵活并且可以让您完全控制(但您还必须注意和优化getView方法,不像您在提供的示例中所做的那样)。

在第二种情况下,您使用的View是超类getView方法返回的。在这种情况下,你让ArrayAdapter超类实现View它想要的,然后使用这个简单View的来进一步更新/修改它。当您对超类构建行视图的方式感到满意并且只打算对已经构建的View. 例如,假设您构建了一个扩展的自定义适配器,ArrayAdapter并且在此适配器中您希望为行视图提供备用背景颜色。然后你会实现这样的getView方法:

public View getView(int position, View convertView, ViewGroup parent) {
      // let the superclass build the View and set the data on it 
      View row=super.getView(position, convertView, parent);
      // we want to modify the View's background so we do
      if (position % 2 == 0) {
          row.setBackgroundColor(Color.RED);
      } else {
          row.setBackgroundColor(Color.GREEN);
      } 
      return row;
}

我们本来可以使用的,LayoutInflator但是对于外观的微小变化是没有用的。

于 2012-08-01T15:10:05.520 回答