2010-09-30 26 views
28

Aquí está mi ArrayAdapter. Me gustaría que esto sea más eficiente, siguiendo el patrón ViewHolder:¿Cómo puedo hacer que mi ArrayAdapter siga el patrón ViewHolder?

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

pero no estoy seguro de cómo lograr esto.

ACTUALIZACIÓN: ViewHolder Patrón

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

He creado una herramienta en línea para generar el código de ViewHolder a partir de un diseño XML: http://www.buzzingandroid.com/tools/android-layout-finder/ – JesperB

Respuesta

44

El ViewHolder es básicamente una instancia de clase estática que se asocia a una vista cuando se la crea, almacenamiento en caché el niño ve que está mirando hacia arriba en tiempo de ejecución. Si la vista ya existe, recupere la instancia del titular y use sus campos en lugar de llamar al findViewById.

En su caso:

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

advertencia: Yo no intento compilar esto, a fin de tomar con un grano de sal.

+0

Esto tiene que ver con una pregunta que hice antes sobre vistas de reciclaje. ¿Conoces algún análisis de rendimiento realizado sobre la sobrecarga de la creación de vistas? – Falmarri

+0

@Falmarri No específicamente, no. Este patrón particular es para evitar la ineficiencia de 'findViewById' en lugar de la creación de Vista. Sin embargo, sería simple hacer un caso de prueba para hacer su propio análisis de Ver reutilización contra creación. Sospecho que analizar solo el diseño XML sería causa suficiente para garantizar la reutilización. Si la Vista es muy simple y tiene un diseño programático, no tengo conocimiento de primera mano de los gastos generales involucrados en la creación. – codelark

+0

excelente código de ejemplo. Implementé el patrón del titular de la vista. Eche un vistazo a v.setBackgroundResource() ¿Lo estoy haciendo correctamente en relación con el patrón de View Holder? –

Cuestiones relacionadas