使用layoutinflater添加有什么价值

时间:2012-08-01 14:51:19

标签: android android-layout

以下是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);
    }
  }
}

2 个答案:

答案 0 :(得分:2)

在理论上根本没有差异,但在实践中有。

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

此外,您每次都在View通过调用getView查询findViewById个实例。而不是尝试使用ViewHolder pattern

答案 1 :(得分:2)

在第一种使用LayoutInflater的情况下,您会为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,但外观上的一个小变化是没用的。