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 は、バターのような滑らかなスクロールを実現するためのトリッキーな最適化です。スクロールすると、リストビューgetViewは提供されたアダプターのメソッドを定期的に呼び出します。あなたの場合 (サンプル #2)、GC ヒープを散らかす多くのオブジェクトを作成します。さらに、毎回 XML からレイアウトを膨らませています。ArrayAdapter.getView新しいオブジェクトを作成する代わりに古いものを再利用し、textView.setText を呼び出すだけです (ところで、label.setText を 2 回呼び出します。最初は super.getView で、次にlabel.setText(items[position])) 。

さらに、 を呼び出すたびにViews インスタンスを照会します。その代わりに、patternを使用してみてください。getViewfindViewByIdViewHolder

于 2012-08-01T15:07:19.610 に答える
2

最初のケースでは、の行用のLayoutInflaterレイアウト ファイルを膨張させます。 これにより、メソッドで行が構築される方法を完全にオーバーライドできます。これは非常に柔軟性があり、完全に制御できるため、通常はこれを使用することをお勧めします(ただし、提供したサンプルで行ったのとは異なり、メソッドを注意して最適化する必要もあります)。ViewListViewViewgetViewgetView

2 番目のケース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 に答える