2011-03-03 19 views
7

Quiero hacer algo muy simple. Tengo una vista de lista en mi aplicación a la que agrego texto dinámicamente. Pero, después de cierto punto, me gustaría cambiar el color del texto dentro de la lista. Entonces, hice un XML que definía mi elemento de lista personalizado y subclassed el ArrayAdapter. Pero, cada vez que llamo al método add() en mi ArrayAdapter personalizado, un elemento se agrega a la vista de lista, pero el texto no se coloca en él.Anulando Android ArrayAdapter

Aquí es mi XML: `

<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/list_content" android:textSize="8pt" 
    android:gravity="center" android:layout_margin="4dip" 
    android:layout_width="fill_parent" android:layout_height="wrap_content" android:textColor="#FF00FF00"/> 

Y mi ArrayAdapter subclase:

private class customAdapter extends ArrayAdapter<String> { 
    public View v; 
    public customAdapter(Context context){ 
     super(context, R.layout.gamelistitem); 
    } 

    @Override 
    public View getView(int pos, View convertView, ViewGroup parent){ 
     this.v = convertView; 
     if(v==null) { 
      LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      v=vi.inflate(R.layout.gamelistitem, null); 
     } 

     if(timeLeft!=0) { 
      TextView tv = (TextView)v.findViewById(R.id.list_content); 
      //tv.setText(str[pos]); 
      tv.setTextColor(Color.GREEN); 
     } 
     else { 
      TextView tv = (TextView)v.findViewById(R.id.list_content); 
      //tv.setText(str[pos]); 
      tv.setTextColor(Color.RED); 
     } 

     return v; 
    } 
} 

Estoy seguro de que estoy haciendo algo muy mal, pero todavía soy un poco nuevo en Android .

¡Gracias! `

Respuesta

10

Debe establecer el texto en getView(). Obtenga el valor para establecer con getItem(pos), luego configúrelo.

public View getView(int pos, View convertView, ViewGroup parent){ 
    this.v = convertView; 
    if(v==null) { 
     LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     v=vi.inflate(R.layout.gamelistitem, null); 
    } 

    // Moved this outside the if blocks, because we need it regardless 
    // of the value of timeLeft. 
    TextView tv = (TextView)v.findViewById(R.id.list_content); 
    tv.setText(getItem(pos)); 

    if(timeLeft!=0) { 
     //TextView tv = (TextView)v.findViewById(R.id.list_content); 
     //tv.setText(str[pos]); 
     tv.setTextColor(Color.GREEN); 
    } 
    else { 
     //TextView tv = (TextView)v.findViewById(R.id.list_content); 
     //tv.setText(str[pos]); 
     tv.setTextColor(Color.RED); 
    } 

    return v; 
} 

Además, hay una razón por la que está almacenando v como una variable miembro, y no sólo dentro de la función?

+0

Estaba almacenando v porque pensé que podría necesitar anular el método add() ya que mi ListView comienza con nada pero gana objetos a lo largo del tiempo. –

+0

@ Brian515: Ah. Esa es una de las cosas buenas de extender una clase completa como ArrayAdapter. Ya maneja casi todo lo que necesita (como 'add()'), y puede preocuparse solo por los bits impares como datos personalizados o vistas personalizadas. – erichamion

+0

No he tenido la oportunidad de jugar mucho con ListView (estoy empezando), pero desde mi comprensión de lo que estás haciendo y de cómo funciona ListView, puedo ver otro problema potencial. Según entiendo, ListView recicla las vistas, por lo que si está verificando el valor de timeLeft cuando se agrega la vista, los elementos antiguos pueden cambiar de verde a rojo a medida que el usuario se desplaza hacia arriba y hacia abajo. Si eso sucede, tal vez considere usar un objeto que contenga tanto el String como el timeLeft actual cuando se cree, en lugar de solo String? – erichamion