2010-09-30 5 views
28

Voici mon ArrayAdapter. Je voudrais rendre plus efficace en suivant le modèle ViewHolder:Comment puis-je faire en sorte que mon ArrayAdapter suive le modèle ViewHolder?

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

mais ne suis pas sûr d'y parvenir.

MISE À JOUR: ViewHolder Motif

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

J'ai créé un outil en ligne pour générer du code ViewHolder à partir d'une mise en page XML: http://www.buzzingandroid.com/tools/android-layout-finder/ – JesperB

Répondre

44

Le ViewHolder est essentiellement une instance de classe statique que vous associez en vue lors de sa création, la mise en cache l'enfant que vous êtes à la recherche considère en cours d'exécution. Si la vue existe déjà, récupérez l'instance de détenteur et utilisez ses champs au lieu d'appeler findViewById.

Dans votre cas:

@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; 
} 

mise en garde: Je n'ai pas essayé de compiler ce, afin de prendre avec un grain de sel.

+0

Ce genre de chose a à voir avec une question que j'ai posée plus tôt à propos de le recyclage des vues. Connaissez-vous des analyses de performance effectuées sur les frais généraux de création de vues? – Falmarri

+0

@Falmarri Pas spécifiquement, non. Ce modèle particulier permet d'éviter l'inefficacité de 'findViewById' plutôt que de créer une vue. Cependant, il serait simple de faire un test pour faire votre propre analyse de la réutilisation par rapport à la création. Je soupçonne que l'analyse de la mise en page XML seule suffirait à justifier la réutilisation. Si la vue est très simple et fait la mise en page programmatique, je n'ai aucune connaissance directe des frais généraux impliqués dans la création. – codelark

+0

excellent exemple de code. J'ai implémenté le modèle de support de vue. Vérifiez v.setBackgroundResource() est-ce que je fais cela correctement par rapport au modèle View Holder? –