Android: mantenga el elemento de ListView resaltado una vez que se ha hecho clic en uno

Así que tengo una actividad con 2 widgets ListView , cuando seleccionas un valor en el primero, el segundo se rellena con valores relacionados con la selección en el primer ListView . Esta mecánica funciona sin problemas, pero ahora quiero que las opciones del usuario permanezcan resaltadas. He leído una buena cantidad de preguntas relacionadas con este tema y parece que hay una gran cantidad de formas en que uno puede lograr esto, pero después de probar unas 4 o 5 de ellas todavía no puedo lograr que funcione.

Lo tengo trabajando en el segundo ListView usando el android:listSelector="#CCCCCC" Atributo XML, pero parece que se borró una vez que se introdujo un OnItemClickListener en la mezcla (como el que uso en mi primer ListView ).

Hasta ahora, esto es lo que tengo:

Custom OnItemClickListener Encontré varias respuestas sobre este tema (lo modifiqué ligeramente para que cargue mi información en el segundo ListView):

 private class ItemHighlighterListener implements OnItemClickListener { private View oldSelection = null; public void clearSelection() { if(oldSelection != null) { oldSelection.setBackgroundColor(android.R.color.transparent); } } public void onItemClick(AdapterView parent, View view, int pos, long id) { clearSelection(); oldSelection = view; view.setBackgroundDrawable(view.getContext().getResources().getDrawable(R.drawable.list_selector)); loadClubs(mXMLPortalOptions.getRegion(pos).getId()); mClubList.setAdapter(new ArrayAdapter(getApplicationContext(), R.layout.list_item_white, mClubs)); } } 

Aquí está mi archivo list_selector.xml :

          

El método (OnItemClick) se llama y se ejecuta, pero el fondo de mi ListItem permanece del mismo color: /

No puedo creer que esta simple tarea haya resultado tan complicada.

Si he omitido el código que podría ser útil o si mi pregunta carece de detalles, siéntase libre de señalarlo y haré todo lo posible para explicarme.

Coloque una variable de posición para el elemento seleccionado. Cambie la posición en el método onItemClicked() . Compruebe la posición seleccionada en List Adapter dentro de getView() y configure el fondo para el elemento seleccionado.

 public class TestAdapter extends BaseAdapter { private Context context; private ArrayList testList; private int selectedIndex; private int selectedColor = Color.parseColor("#1b1b1b"); public TestAdapter(Context ctx, ArrayList testList) { this.context = ctx; this.testList = testList; selectedIndex = -1; } public void setSelectedIndex(int ind) { selectedIndex = ind; notifyDataSetChanged(); } @Override public int getCount() { return testList.size(); } @Override public Object getItem(int position) { return testList.get(position); } @Override public long getItemId(int position) { return position; } private class ViewHolder { TextView tv; } @Override public View getView(int position, View convertView, ViewGroup parent) { View vi = convertView; ViewHolder holder; if(convertView == null) { vi = LayoutInflater.from(context).inflate(R.layout.test_list_item, null); holder = new ViewHolder(); holder.tv = (TextView) vi; vi.setTag(holder); } else { holder = (ViewHolder) vi.getTag(); } if(selectedIndex!= -1 && position == selectedIndex) { holder.tv.setBackgroundColor(Color.BLACK); } else { holder.tv.setBackgroundColor(selectedColor); } holder.tv.setText("" + (position + 1) + " " + testList.get(position).getTestText()); return vi; } } 

Ahora configure la variable selectedIndex cuando se hace clic en un elemento de la lista.

 public class TestActivity extends Activity implements OnItemClickListener { // Implemented onItemClickListener @Override public void onItemClick(AdapterView< ?> parent, View view, int position, long id) { adapter.setSelectedIndex(position); } } 

Para ampliar la gran solución de Shaiful, es posible que no hagas que la suya funcione en tu situación.

Si está utilizando tenga su código todo en public void onListItemClick(ListView l, View v, int index, long id) , si está utilizando fragmentos y tiene que declarar una interfaz en lugar de implementar OnListItemClickListener, o lo que sea que está causando su IDE generar errores, es posible que tenga que acceder a variables y métodos estáticamente.

 public static int selectedPosition = 0; ArrayAdapter adapter = null; @Override public void onListItemClick(ListView l, View v, int index, long id) { super.onListItemClick(l, v, index, id); selectedPosition = index; Your_adapter.setSelectedIndex(selectedPosition); adapter.notifyDataSetChanged(); } 

Y en Your_adapter:

 private static int selectedIndex; //public Your_adapter... public static void setSelectedIndex(int ind) { selectedIndex = ind; } @Override public View getView(int position, View convertView, ViewGroup parent) { WellHolder holder = null; if (null == convertView) { //set up your "holder" } if (position == selectedIndex) { convertView.setBackgroundColor(convertView.getResources().getColor(R.color.cyan)); } else { convertView.setBackgroundColor(convertView.getResources().getColor(R.color.silver)); } return convertView; } 

Algunas otras diferencias son que no tiene que inicializar ninguna variable como “0” o “-1” y se llama a notifyDataSetChanged () en su actividad.

Una vez más, gracias por tu solución @Shaiful. Ciertamente me ayudó a ahorrar tiempo tratando de obtener lo que está predeterminado en iOS para trabajar con Android, todo mientras evito selector / item / focused / pressed / etc.

Me enfrenté a un problema similar. Esa es mi solución:

Primero agrega selector de lista personalizado a tu vista de lista:

  

Dentro de listselector.xml:

 < ?xml version="1.0" encoding="utf-8"?>    

Y finalmente un bg.xml dibujable con el color de su destaque:

 < ?xml version="1.0" encoding="utf-8"?>    

lv.setSelector(R.drawable.highlighter);

poner una imagen highlighter.png en una carpeta dibujable
forma más sencilla de resaltar el elemento seleccionado en la vista de lista.

Lo estaba buscando hace dos semanas y el resultado es que no es posible con un selector dibujable. Para obtener más información, lea esta publicación en Android Developers Blog: Modo táctil

En resumen: solo cuando su dedo está en la pantalla, se selecciona el elemento.

Otra posibilidad es guardar qué elemento se selecciona en var y pintar diferente usando su adaptador personalizado como dice Shaiful.

 //create a list_itemselectorin drawable folder //you will get the list item selected background color change once you select //the item               //create a list in layout folder  

// Y ver la salida.

Creo que la mejor y más fácil solución es esta. No necesita configurar ningún android:listSelector en el ListView o hacer ningún cambio en el adaptador. Ni siquiera necesita llamar a setSelection(position) en OnItemClickListener ya que se maneja automáticamente.

  1. Establecer en su ListView:

     android:choiceMode="singleChoice" 
  2. Establecer el fondo del elemento de la lista en sí:

     android:background="?android:attr/activatedBackgroundIndicator" 
  3. Eso es.

De esta forma obtendrás un comportamiento predeterminado del sistema. Así es como se hace en el diseño predeterminado de android.R.layout.simple_list_item_activated_1 .

Si puede usar un drawable para mostrar listItem Highlighted, entonces debe usar el siguiente código:

 listView.setSelector(R.drawable.bg_image); 

Funciona.

Hay una solución completamente XML completa, que funcionó para mí. En primer lugar, defina XML-drawable con el código del selector en el que el estado “normal” corresponderá al estado visual “seleccionado sin comprimir” de un elemento de la lista, y el state_pressed = verdadero al estado visual “presionado”. Ejemplo del archivo “custom_item_selector.xml”, que se asemeja a la selección Holo blue:

 < ?xml version="1.0" encoding="utf-8"?>                   

(también puede establecer el estado enfocado allí). En segundo lugar, aplique este xml-drawable como ListSegs listSelector y configure su choiceMode deseado:

  

Eso es todo. Permite definir diferentes estados visuales para elementos “simplemente seleccionados” y “seleccionados por presión”, por ejemplo, haciendo que los elementos sean más shinys en la prensa.

Para mantener los elementos de la lista (selección múltiple) resaltados, al hacer clic (activar), siga los pasos.

1. Configure el fondo para mostrar el diseño del elemento como dibujable.

  < ?xml version="1.0" encoding="utf-8"?>       

2. selector dibujable

 < ?xml version="1.0" encoding="utf-8"?>     

3. Listview establece el modo de elección múltiple

getListView (). setChoiceMode (ListView.CHOICE_MODE_MULTIPLE);

Cuando se presiona : enter image description here

Debajo de la imagen se muestra, cuando el usuario seleccionó varios elementos de la lista.

Cuando se activa : enter image description here

Para resumir esta publicación y tal vez ayudar a otra persona en el futuro, sugiero la respuesta 🙂

Primero, necesitamos crear el archivo res/drawable/list_item_background.xml con los siguientes contenidos:

 < ?xml version="1.0" encoding="utf-8"?>     

Especifique sus recursos dibujables, por supuesto. Y también puede agregar otros con diferentes estados como state_pressed , state_focused , etc.

Entonces, debemos establecer el parámetro de background para nuestro elemento de lista personalizado elemento ViewGroup ( ViewGroup res/layout/list_item_layout.xml ) de esta manera:

 android:background="@drawable/list_item_background" 

El siguiente paso es modificar nuestra clase Adapter personalizada. Aquí está el siguiente fragmento de código:

 public class CustomAdapter extends BaseAdapter { private List items; private LayoutInflater itemInflater; private int selectedIndex; // add this public CustomAdapter(Context c, List items) { this.items = items; this.itemInflater = LayoutInflater.from(c); selectedIndex = -1; // add this } /* add this */ public void setSelectedIndex(int index) { selectedIndex = index; notifyDataSetChanged(); } /* other adapter's stuff */ @Override public View getView(int position, View convertView, ViewGroup parent) { if(convertView == null) { convertView = itemInflater.inflate(R.layout.list_item_layout, parent, false); } // add this convertView.setActivated(selectedIndex != -1 && position == selectedIndex); /* do some stuff */ return convertView; } } 

Finalmente, deberíamos llamar al método del adaptador setSelectedIndex(position) el método onItemClick(...) de AdapterView.OnItemClickListener .

 public class YourActivity extends Activity implements AdapterView.OnItemClickListener { private CustomAdapter mCustomAdapter; /* activity implementation */ @Override public void onItemClick(AdapterView< ?> parent, View view, int position, long id) { mCustomAdapter.setSelectedIndex(position); } } 

Ahora, podemos estar satisfechos con los elementos de la lista adecuada destacando 🙂

PD: si queremos habilitar el modo de opción múltiple en nuestra lista, listView la siguiente cadena en nuestra clase de actividad donde se listView instancia de listView :

 listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); 

Por lo tanto, obtendremos los elementos múltiples adecuados resaltados.

– Espero que esto ayude a cualquiera 🙂