2012-09-26 6 views
9

Sé que suena muy simple, y hay preguntas sobre esto. Pero nada de eso podría resolver mi problema. Así que aquí vamos:Cambiar el color de fondo de un elemento en Android ListActivity onListItemClick

que quieren cambiar el color de fondo de un elemento de la lista en un ListActivity cuando el usuario hace clic en él, y cambiarlo de nuevo al color original cuando el usuario hace clic de nuevo (es decir, Seleccionar/Deseleccionar elemento tipo de mirada)

He intentado usar getChildAt, funciona perfectamente si tengo todos los elementos visibles en una pantalla sin tener que desplazarme.

Código:

getListView().getChildAt(position).setBackgroundColor(Color.CYAN); 

El problema comienza cuando tenga más elementos de la lista y el usuario tiene que desplazarse a través de ellos. Una vez que se cambia el fondo de un elemento, aparece el color de fondo en los elementos recientemente visibles a medida que me desplazo. Además, el getChildAt(position) devuelve null (y por lo tanto un NullPointerException) al hacer clic de nuevo en el elemento.

¿Alguien puede ayudarme con un código simple que me ayuda a cambiar el color de fondo de un elemento de la lista?

¡Gracias de antemano!

+0

Creo que este tema le ayudará a hacer eso. http://stackoverflow.com/questions/2217753/changing-background-color-of-listview-items-on-android – thiagolsilva

Respuesta

5

Claro. Haría esto en el método getView() de un ListAdapter personalizado.

MyAdapter extends SimpleAdapter { 
    private ArrayList<Integer> coloredItems = new ArrayList<Integer>(); 

    public MyAdapter(...) { 
     super(...); 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     View v = super.getView(position, convertView, parent); 

     if (coloredItems.contains(position)) { 
      v.setBackgroundColor(Color.CYAN); 
     } else { 
      v.setBackgroundColor(Color.BLACK); //or whatever was original 
     } 

     return v; 
    } 
} 

actualización coloredItems cuando se hace clic en un elemento de la lista.

@Override 
public void onListItemClick(ListView l, View v, int position, long id) { 
    if (coloredItems.contains(position)) { 
     //remove position from coloredItems 
     v.setBackgroundColor(Color.BLACK); //or whatever was original 
    } else { 
     //add position to coloredItems 
     v.setBackgroundColor(Color.CYAN); 
    } 
} 
+0

¡Impresionante! Eso funcionó perfecto! Me costó mucho tratar de descubrir la solución. Tu respuesta fue muy útil. Desearía poder darte dos votos ... :) ¡Gracias otra vez! :) –

+0

¡De nada! – heycosmo

+0

después de unas pocas horas de callejones sin salida me mostró el camino correcto, hombre bien hecho! –

1

Lo que hago es crear un archivo xml llamado i.e. list_background y ponerlo en la carpeta dibujable.

el XML tiene el siguiente aspecto:

<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:drawable="@color/list_selected" android:state_pressed="true" /> 
    <item android:drawable="@android:color/white" /> 
</selector> 

Y en el código XML para el artículo de la ListView pongo este XML como elementos de fondo es decir

item.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
      style="@style/Fill" 
      android:background="@drawable/list_background"> 

    <!-- Your layout here --> 
</RelativeLayout> 

style = @ style/Fill es solo un atajo que hice para android: layout_height = "match_parent" y android: layout_width = "match_parent

Luego, en onListItemClick:

public void onListItemClick(ListView l, View v, int position, long id) { 
    v.setPressed(!v.isPressed) //Toggle between colors of the view 
} 
+0

¡Gracias por la ayuda! Pero tiene dos problemas con esta solución: 1) Puede seleccionar solo un elemento a la vez; si trata de seleccionar otro, el primero perderá automáticamente su color de fondo. 2) Si selecciona un elemento, desplácese hacia abajo y luego desplácese hacia atrás, ¡lo que verá es que el elemento seleccionado ya no tiene color de fondo! :( Por favor, ayuda. –

+2

Sí, necesita modificar el método 'getView' de su ListAdapter para persistir ese estado (ver mi respuesta a continuación). Porque ListView reutiliza Vistas de elementos, un elemento que aparece en la parte superior (después un desplazamiento) puede heredar rasgos de un elemento que quedó en la parte inferior a menos que esos rasgos se reinicien en 'getView'. – heycosmo

+0

@heycosmo: ¿Qué pasa si no estoy usando mi propio ListAdapter? Porque estoy usando un Adaptador simple. ¿Cómo puedo resolver esto? ? –

0

esto es cómo lo hice:

crear una variable global View ColoredView; a continuación, cuando setOnItemClickListener para su ListView, hace esto:

MenuList.setOnItemClickListener(new OnItemClickListener() { 

      @Override 
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
       if (ColoredView != null) 
        ColoredView.setBackgroundColor(Color.WHITE); //original color 

       view.setBackgroundColor(Color.BLUE); //selected color 
       ColoredView = view; 
      } 
     }); 

Es la manera más simple en mi opinión.

2

Si se trata de ListFragment entonces este código será útil,

@Override 
    public void onViewCreated(View view, Bundle savedInstanceState) { 
     super.onViewCreated(view, savedInstanceState); 
     if (view != null) { 
      getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); 
      getListView().setDescendantFocusability(ListView.FOCUS_AFTER_DESCENDANTS); 
      catagoryValueListView=getListView(); 
      catagoryValueListView.setOnItemClickListener(new OnItemClickListener() { 

      @Override 
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
       if (ColoredView != null) 
        ColoredView.setBackgroundColor(Color.WHITE); //original color 

       view.setBackgroundColor(Color.BLUE); //selected color 
       ColoredView = view; 
            } 
     }); 
    } 

} 
+0

Actualice su respuesta y pase el código dentro de las etiquetas de código. –

0

Gracias heycosmo. tu solución resolvió mi problema

No tenemos idea de por qué debemos establecer el fondo en 2 lugares.

1. getView del adaptador()

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    .... 
    .... 
    .... 
     if(arrayBools[position]) { 
      view.setBackgroundColor(Common.colorBkgroundSelected); 
     } 
     else{ 
      view.setBackgroundColor(Common.colorBkgroundNormal);    
     } 
    .... 
    .... 
    .... 
} 

2. onListItemClick de ListActivity().

@Override 
protected void onListItemClick(ListView l, View v, int position, long id) { 
     super.onListItemClick(l, v, position, id);  
     arrayBools[position] = (arrayBools[position] ? false : true); 

    if(arrayBools[position]) { 
     v.setBackgroundColor(colorBkgroundSelected); 
    } 
    else{ 
     v.setBackgroundColor(colorBkgroundNormal);   
    }  
} 
1

Simplemente puede hacerlo de esta manera en onListItemClick método

@Override 
protected void onListItemClick(ListView l, View v, int position, long id) { 
    super.onListItemClick(l, v, position, id); 

    for (int a = 0; a < l.getChildCount(); a++) { 
     l.getChildAt(a).setBackgroundColor(Color.TRANSPARENT); 
    } 

    ColorDrawable colorDrawable1 = new ColorDrawable(
      Color.parseColor("#A0A3A0")); 
    v.setBackgroundDrawable(colorDrawable1); 

    if (position == 0) { 
     Intent i = new Intent(MainActivity.this, NewActivity.class); 

     startActivity(i); 
    } 

} 
Cuestiones relacionadas