El elemento ListView no permanecerá "seleccionado"

Quiero cambiar el fondo de un elemento listview cuando el usuario hace clic en él. Algo así como la página de configuración de Honeycomb (aunque no estoy lidiando con sólo la configuración por lo que no estoy usando PreferenceActivity) Tengo esta funcionalidad trabajando a través de un selector de estado selector de estado de recursos, excepto para los casos al hacer clic en el menú listview cambia el lineal A la derecha del listview (tipo de vista de pantalla dividida). Supongo que el listview pierde el foco de modo state_pressed ya no es cierto.

<item android:state_pressed="true"> <shape > <solid android:color="@color/blue1" /> </shape> </item> 

¿Algún consejo para mantener ese elemento de vista de lista coloreado hasta que se seleccione otro elemento de vista de lista? ¡Gracias!

EDITAR:

Pude conseguir el fondo cambiado en un setOnItemClickListener con

 view.setBackgroundResource(R.color.red); 

Sólo necesito una seleccionada a la vez, así que cuando se hace clic en los demás elementos de la lista, intenté lv.invalidate() y lv.getChildAt(0).invalidate() pero ninguno funcionó y la segunda causa la excepción de puntero nulo. ¿Alguna idea para volver a poner el color?

Cuando suelta el dedo de la celda ya no se registra presionado. Lo que usted va a querer hacer es cambiar el fondo de la fila individual cuando un usuario selecciona. Esto significa implementar onItemClick o onItemTouch y marcar el adaptador para volver a dibujar la fila con el nuevo fondo. Si ya está utilizando un adaptador de lista personalizada, puede implementar una comprobación contra un booleano en su método getView (). También necesitará realizar un seguimiento de qué filas están "seleccionadas" y cuáles no.

Pseudocódigo:

  public View getView(int pos, View convertView, ViewGroup parent) { if(isChecked[pos]) //set background to checked color } 

Espero que esto ayude,

1.- Cree un archivo de forma para el elemento enfocado: \ drawable \ list_selector_focused.xml

  <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <gradient android:angle="90" android:startColor="#f5c98c" android:endColor="#f7ddb8"/> </shape> 

2.- Crea un archivo de forma para el elemento presionado: \ drawable \ list_selector_pressed.xml

  <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <gradient android:angle="90" android:startColor="#fb9d23" android:endColor="#ffc579" /> </shape> 

3.- Crear archivo selector de lista: \ drawable \ list_selector.xml

  <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" android:drawable="@drawable/list_selector_pressed" /> <item android:state_focused="true" android:drawable="@drawable/list_selector_focused" /> <item android:drawable="@drawable/list_selector_focused" /> </selector> 

4.- Agregue este atributo a su ListView en el archivo de diseño:

  android:choiceMode="singleChoice" android:listSelector="@drawable/list_selector" 

Puede utilizar colores en lugar de formas de degradado,

Esta es la implementación de la idea sgarman :

  package com.mypackage; import java.util.Vector; import com.myapp.R; import com.myapp.data.Address; import android.content.Context; import android.graphics.Color; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; public class AddressesListAdapter extends BaseAdapter{ protected Context context; protected LayoutInflater mInflater; protected int itemResourceId; protected Vector<Address> contentItems = new Vector<Address>(); protected Vector<Boolean> selectedStates; private static final String TAG = "myapp"; public AddressesListAdapter(Context context, Vector<Address> contentItems) { this.context = context; this.contentItems = contentItems; mInflater = LayoutInflater.from(context); itemResourceId = R.layout.address_list_item; selectedStates = new Vector<Boolean>(); //initial fill clearSelectedState(); } @Override public int getCount() { return contentItems.size(); } @Override public Object getItem(int position) { return contentItems.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { final ViewHolder holder; if (convertView == null) { convertView = mInflater.inflate(itemResourceId, null); holder = new ViewHolder(); holder.addressName = (TextView) convertView.findViewById(R.id.addressName); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } Address address = (Address) contentItems.get(position); holder.addressName.setText(address.getAddressName()); holder.addressName.setOnClickListener(new SetFocusListener(position)); //restore saved position from saving vector if (selectedStates.get(position)) holder.addressName.setBackgroundColor(Color.BLUE); else holder.addressName.setBackgroundColor(Color.TRANSPARENT); return convertView; } private void clearSelectedState () { selectedStates.clear(); for (int i = 0 ; i <= contentItems.size(); i++) { selectedStates.add(new Boolean(false)); } } private class SetFocusListener implements View.OnClickListener { private int position; public SetFocusListener(int position) { this.position = position; } @Override public void onClick(View v) { //clear selected state vector clearSelectedState(); //set selected position selectedStates.set(position, new Boolean(true)); //refresh adapter to redraw focus notifyDataSetChanged(); } } static class ViewHolder { TextView addressName; } } 

Sólo preocupación de que puede ser costoso para configurar nuevo oyente para cada iteración getView ()

De forma predeterminada, "Seleccionado" no es lo mismo que "Click" cuando usas una interfaz táctil, algo que me causa dolores de cabeza reales cuando inicié el desarrollo de Android.

Para apoyar a los usuarios que navegan por el tacto ya los usuarios que usan scrollwheels / trackballs, puede usar setSelection y hacer su manipulación en una implementación de AdapterView.OnItemSelectedListener (set with setOnItemSelectedListener ).

Otra idea es que setSelection no resaltará un elemento si el último evento fue un evento táctil.

Te recomendamos que crees una vista personalizada para los elementos de la lista y que realices el resaltado allí.

Espero que esto ayude,

Phil Lello

El estado androide marcado se utiliza mejor para resolver este problema.

Alguien mencionó usando android: background = "? Android: attr / activatedBackgroundIndicator".

Esto solo apunta a uno de los recursos activados_background_ * en frameworks / base / core / res / res / drawable del código fuente de android. Por ejemplo activate_background_holo_dark.xml:

 <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_activated="true" android:drawable="@android:drawable/list_activated_holo" /> <item android:drawable="@color/transparent" /> </selector> 

Así que esencialmente desea utilizar state_activated para representar cuando el usuario presiona el botón también cuando está en un estado marcado (es decir, en estado persistente seleccionado). Tenga en cuenta que activado sólo se introdujo después de Honeycomb, si está orientado a dispositivos más antiguos, tendrá que confiar en state_checked (más detalles aquí ).

Ahora si desea establecer un elemento como marcado, necesita llamar a listView.setItemChecked(position, true) . Es probable que desee establecer la propiedad android:choiceMode en su ListView al valor apropiado (por ejemplo, si sólo desea seleccionar una cosa a la vez use singleChoice ). No es necesario invalidar, la llamada a setItemChecked activará un relayout que actualizará la vista.

También tenga cuidado si permite reordenar elementos en su ListView, ya que los elementos marcados actualmente tendrán que actualizarse. Si utiliza IDs estables, se tratará automáticamente.

Para ver un ejemplo de esto en acción, echa un vistazo al código de ejemplo NavigationDrawer que se encuentra en la serie de ejercicios : http://developer.android.com/training/implementing-navigation/nav-drawer.html .

Ok, así que probé la solución anterior de donde dice "Esta es la implementación de sgarman idea:" Esto sólo funciona si SetFocusListener es un OnTouchListner. Ohterwise el método onClick consume el clic. Tuve que emparejar esta solución con un oyente de OnItemClick en mi artículo de la lista para conseguir la lista para demostrar realmente el artículo resaltado.

He utilizado android:state_activated="true" lugar de state_selected . ¡Funciona a las mil maravillas!

Si mantiene su listaVer toda la actividad, puede hacer un mListView.isItemChecked(position) en el método getView() . Y ellos fijan el color de fondo dependiendo del resultado.

¿Has probado android:state_selected="true" ?

tratar

  android:background="?android:attr/activatedBackgroundIndicator" 

😉

  • ¿Cómo se determinan los valores de identificador de recursos en Android?
  • Obtener Id de recurso de ImageView
  • ¿Hay una manera de cargar arbitrariamente recursos en tiempo de ejecución en Android?
  • Android: carga la fuente personalizada en la tarjeta SD
  • Cambio de locale: ¿Forzar la actividad a recargar recursos?
  • Eclipse Android no limpia, no actualiza los recursos
  • Con los recursos predeterminados en la carpeta dibujable (tamaño MDPI), ¿cuál es el punto de la carpeta drawable-mdpi?
  • Recurso no encontrado de android no encontrado excepción
  • Tamaños de imagen de Android
  • Android obtiene una lista de colores de los recursos
  • ¿Agregar nuevas líneas a un recurso de texto en Android?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.