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!
- Obtener la ruta del recurso de Android
- Descargar y reemplazar archivos de recursos de Android
- ¿Por qué Android aapt eliminar la extensión de archivo .gz de los activos?
- ¿Eclipse no está contento con una sola carpeta?
- Cómo encontrar View from string en vez de R.id
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?
- ¿Cuál es el estado de los idiomas de Right To Left en Android?
- Android ¿Es posible definir un mapa en un archivo XML?
- ¿Ayuda a analizar resources.arsc?
- Recuento de elementos en la carpeta dibujable que comienzan con una cadena específica
- ¿Hay un punto que tiene res / drawable-ldpi en android?
- Android ImageButton setImageResource de la variable
- . \ key.p12: abierto fallido: ENOENT (No hay tal archivo o directorio)
- Configuración de un icono de notificación de Android en una URL remota
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"
😉