2010-09-30 14 views
28

Hier ist mein ArrayAdapter. Ich mag diese effizienter gestalten, indem nach dem ViewHolder Muster:Wie kann ich meinen ArrayAdapter dem ViewHolder-Muster folgen lassen?

http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/view/List14.html

aber bin nicht sicher, wie dies zu erreichen.

UPDATE: ViewHolder Muster

private class QuoteAdapter extends ArrayAdapter<Quote> { 

    private ArrayList<Quote> items; 
    // used to keep selected position in ListView 
    private int selectedPos = -1; // init value for not-selected 

    public QuoteAdapter(Context context, int textViewResourceId, ArrayList<Quote> items) { 
     super(context, textViewResourceId, items); 
     this.items = items; 
    } 

    public void setSelectedPosition(int pos) { 
     selectedPos = pos; 
     // inform the view of this change 
     notifyDataSetChanged(); 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     View v = convertView; 
     ViewHolder holder; // to reference the child views for later actions 

     if (v == null) { 
      LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      v = vi.inflate(R.layout.mainrow, null); 

      // cache view fields into the holder 
      holder = new ViewHolder(); 
      holder.nameText = (TextView) v.findViewById(R.id.nameText); 
      holder.priceText = (TextView) v.findViewById(R.id.priceText); 
      holder.changeText = (TextView) v.findViewById(R.id.changeText); 

      // associate the holder with the view for later lookup 
      v.setTag(holder); 
     } 
     else { 
      // view already exists, get the holder instance from the view 
      holder = (ViewHolder)v.getTag(); 
     } 

     // change the row color based on selected state 
     if (selectedPos == position) { 
      v.setBackgroundResource(R.drawable.stocks_selected_gradient); 
      holder.nameText.setTextColor(Color.WHITE); 
      holder.priceText.setTextColor(Color.WHITE); 
      holder.changeText.setTextColor(Color.WHITE); 
     } else { 
      v.setBackgroundResource(R.drawable.stocks_gradient); 
      holder.nameText.setTextAppearance(getApplicationContext(), R.style.BlueText); 
      holder.priceText.setTextAppearance(getApplicationContext(), R.style.BlueText); 
      holder.changeText.setTextAppearance(getApplicationContext(), R.style.BlueText); 
     } 

     Quote q = items.get(position); 
     if (q != null) { 
      if (holder.nameText != null) { 
       holder.nameText.setText(q.getSymbol()); 
      } 
      if (holder.priceText != null) { 
       holder.priceText.setText(q.getLastTradePriceOnly()); 
      } 
      if (holder.changeText != null) { 
       try { 
        float floatedChange = Float.valueOf(q.getChange()); 
        if (floatedChange < 0) { 
         if (selectedPos != position) 
          holder.changeText.setTextAppearance(getApplicationContext(), R.style.RedText); // red 
        } else { 
         if (selectedPos != position) 
          holder.changeText.setTextAppearance(getApplicationContext(), R.style.GreenText); // green 
        } 
       } catch (NumberFormatException e) { 
        System.out.println("not a number"); 
       } catch (NullPointerException e) { 
        System.out.println("null number"); 
       } 
       holder.changeText.setText(q.getChange() + " (" + q.getPercentChange() + ")"); 
      } 
     } 
     return v; 
    } 
} 
+0

Ich habe ein Online-Tool erstellt, um ViewHolder-Code aus einem XML-Layout zu generieren: http://www.buzzingandroid.com/tools/android-layout-finder/ – JesperB

Antwort

44

Die ViewHolder ist im Grunde eine statische Klasse Instanz, die Sie mit Blick assoziieren, wenn es erstellt wird, das Kind das Caching sieht Sie suchen zur Laufzeit auf. Wenn die Ansicht bereits vorhanden ist, rufen Sie die Halterinstanz ab und verwenden Sie ihre Felder, anstatt findViewById aufzurufen.

In Ihrem Fall:

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    View v = convertView; 
    ViewHolder holder; // to reference the child views for later actions 

    if (v == null) { 
     LayoutInflater vi = 
      (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     v = vi.inflate(R.layout.mainrow, null); 
     // cache view fields into the holder 
     holder = new ViewHolder(); 
     holder.nameText = (TextView) v.findViewById(R.id.nameText); 
     holder.priceText = (TextView) v.findViewById(R.id.priceText); 
     holder.changeText = (TextView) v.findViewById(R.id.changeText); 
     // associate the holder with the view for later lookup 
     v.setTag(holder); 
    } 
    else { 
     // view already exists, get the holder instance from the view 
     holder = (ViewHolder) v.getTag(); 
    } 
    // no local variables with findViewById here 

    // use holder.nameText where you were 
    // using the local variable nameText before 

    return v; 
} 

// somewhere else in your class definition 
static class ViewHolder { 
    TextView nameText; 
    TextView priceText; 
    TextView changeText; 
} 

Vorbehalt: Ich versuche nicht, dies zu kompilieren, so mit einem Körnchen Salz.

+0

Diese Art von hat mit einer Frage zu tun, die ich zuvor gefragt habe Ansichten recyceln. Kennen Sie eine Leistungsanalyse für den Aufwand beim Erstellen von Sichten? – Falmarri

+0

@Falmarri Nicht speziell, nein. Dieses spezielle Muster soll die Ineffizienz von "findViewById" und nicht die Erstellung von Ansichten vermeiden. Es wäre jedoch einfach, einen Testfall zu erstellen, um eine eigene Analyse der Wiederverwendung von Ansichten im Vergleich zur Erstellung durchzuführen. Ich vermute, dass das Parsen des XML-Layouts alleine genug wäre, um die Wiederverwendung zu rechtfertigen. Wenn die View sehr einfach ist und ein programmatisches Layout hat, habe ich keine Ahnung von dem Overhead, der mit der Erstellung verbunden ist. – codelark

+0

großartiger Beispielcode. Ich habe das Ansichtshalter-Muster implementiert. Check out v.setBackgroundResource() mache ich das in Bezug auf das View-Holder-Muster richtig? –

Verwandte Themen