9

He publicado el mismo problema un par de veces, pero aún no se ha resuelto. Tengo un ListFragment y quiero resaltar el elemento seleccionado en la lista. Me han dado sugerencias para usar un "selector". No entiendo cómo usar este selector. Mi clase es ListFragment:Resalte el elemento seleccionado en "ListFragment"?

// Create an adapter with list of stores and populate the list with 
     // values 
     ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), 
       android.R.layout.simple_list_item_1, StoreList); 
     setListAdapter(adapter); 
     mDbHelper.close(); 
    } 

    /* 
    * (non-Javadoc) 
    * 
    * Handles the event when an item is clicked on left pane, performs action 
    * based on the selection in left pane 
    * 
    * @see android.app.ListFragment#onListItemClick(android.widget.ListView, 
    * android.view.View, int, long) 
    */ 
    @Override 
    public void onListItemClick(ListView l, View v, int position, long id) { 
     String selectedStore = (String) getListAdapter().getItem(position); 
     DetailFragment fragment = (DetailFragment) getFragmentManager() 
       .findFragmentById(R.id.detailFragment); 
     if (fragment != null && fragment.isInLayout()) { 
      v.setBackgroundColor(getResources().getColor(R.color.BLUE)); 
      // passes selectedStore to detail fragment 
      fragment.setText(selectedStore); 

      // getItemList(selectedStore); 

     } 

Usando setBackground establece el color de forma permanente, pero quiero que desaparezca cuando se selecciona otro elemento. Entiendo cómo usar un selector en un ListView pero en mi caso si no he definido ningún xml para el Listview, ¿cómo usaré un "selector"? Estoy usando android.R.layout.simple_list_item_1 que está predefinido.

+1

El concepto de "selección" en Android para un 'ListView' es para usar con almohadillas en D, trackballs, teclas de flecha y otros dispositivos señaladores. En las tabletas, existe un concepto relacionado de una fila "activada", diseñada para resaltar el último elemento intervenido desde la pantalla táctil, para proporcionar contexto para algo adyacente a él (por ejemplo, patrón de detalles maestros). – CommonsWare

Respuesta

4

No estaba obteniendo lo que quería, así que seguí excavando y se me ocurrió una solución "barata" que podría no ser la mejor práctica pero cumple su función. Quería que el elemento se resaltara cuando se seleccionara y el color desaparecería cuando se seleccionara otro elemento de listFragment. Esto es lo que funcionó para mí que define una estática View V; e inicializados que V = new View(getActivity()); A continuación, dentro de mi

onListItemClick (ListView l, Ver v, posición int, long ID)

  V.setBackgroundResource(0); 
      v.setBackgroundResource(R.color.BLUE); 
      V = v; 
+2

Podría incluso llamarlo mala práctica en lugar de "no la mejor práctica"; almacenar una vista, que guarda una referencia a la actividad, en un objeto estático. Perdiendo la actividad. – NickL

+3

Tendrá un problema cuando la lista crezca más que la pantalla. Porque la misma vista se reutilizará para elementos previamente ocultos, cuando se muestran y, por lo tanto, algunos de ellos se pueden mostrar como "seleccionados". – Stefan

+0

@Stefan Tengo ese problema. ¿Sabes cómo arreglar eso? http://stackoverflow.com/questions/31442067/list-item-wont-stay-selected-despite-setting-necessary-properties – MacaronLover

6

Desde su ListView, llame al setChoiceMode(ListView.CHOICE_MODE_SINGLE). Luego, cada vez que desee resaltar un elemento seleccionado, llame al setItemChecked(index, true).

+4

Esto no funciona si usa un adaptador personalizado con un diseño de elemento de lista personalizado. – Mehmed

4

Intenté lo mismo y no encontré ninguna solución. Lo que en realidad hacemos está usando este código para establecer el oyente:

listView.setOnItemClickListener(new AdapterView.OnItemClickListener(){ 
    public void onItemClick(AdapterView<?> parent, View view, int position, long id){ 
     list_adapter.setSelectedPosition(position); 
     listView.invalidate(); 
    } 
}); 

donde el adaptador lista define los siguientes métodos públicos

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    View rowView = GuiBuilder.createHeroListItemView(heroes.get(position),getContext(),parent,false); 
    if(position == selected_pos){ 
     rowView.setBackgroundColor((rowView.getResources().getColor(R.color.list_item_selected_color))); 
    } 
    return rowView; 
} 

public void setSelectedPosition(int selected_pos){ 
    this.selected_pos = selected_pos; 
} 

public int getSelectedPosition(){ 
    return selected_pos; 
} 

Es decir, puedo cambiar el fondo del elemento de lista mediante programación. Por otra parte, para evitar el efecto de parpadeo cuando se hace clic en el elemento de la lista que no define ningún selector para el estado presionado

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:state_focused="true" 
     android:drawable="@drawable/list_item_focused_color" /> 
    <item android:drawable="@drawable/list_item_default_color" /> 
</selector> 

Esto funciona como se pretende para mí. No encontré ninguna solución mejor, ya que setSelected (true) no funciona en elementos de la lista.

+0

Se ve bien, lo probaré y le contaré lo que encontré. –

7

El siguientes trabajado para mí para:

res/color/menu_highlight.xml

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item 
    android:state_pressed="true" 
    android:drawable="@color/red" /> 
    <item 
    android:state_selected="true" 
    android:drawable="@color/red" /> 
    <item 
    android:drawable="@color/white" /> 
</selector> 

res/valores/colors.xml:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
<color name="white">#FFFFFF</color> 
<color name="red">#FF0000</color> 
</resources> 

res/layout/menuitem.xml :: (XML para cada elemento de la lista)

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_height="wrap_content" 
    android:layout_width="fill_parent"> 
    <TextView 
     android:id="@+id/textmenu" 
     android:layout_height="wrap_content" 
     android:text="text" 
     android:textColor="#FFFFFF" 
     android:background="@color/menu_highlight" 
     android:visibility="visible" 
     android:layout_width="fill_parent" /> 
</LinearLayout> 

último , en la clase ListFragment, agregue View previous y agregue el siguiente código a la función onlistitemclick ..(Mencionado en ListFragment: highlight selected row)

public class MenuListFragment extends ListFragment{ 

View previous; 

@Override 
    public void onListItemClick(ListView l, View v, int position, long id) { 
     super.onListItemClick(l, v, position, id); 
     //Logic to highlight selected item 
     previous.setSelected(false); 
     v.setSelected(true); 
     previous=v; 
    } 

}  
+0

Parece que sufrirá del mismo problema que Stefan mencionó en la respuesta aceptada: tendrá un problema cuando la lista crece más grande que la pantalla. Porque la misma vista se reutilizará para elementos previamente ocultos, cuando se muestran y, por lo tanto, algunos de ellos se pueden mostrar como "seleccionados". –

0

código i

getListView().setItemChecked(0, true); 

después

setListAdapter(oAdapter); 

bloque de código

0

Algo similar al tipo-a1pha pero con los selectores, una vez que tenga la view puede ver.setSelected (true) y eso agregaría el estilo que ha definido en y nuestro selector necesita quitar la bandera una vez que se realiza la acción.

3

Esto funcionó muy bien para mí en el ListFragment, pero creo que funciona solo para Android 4.0 y superior. He creado un diseño simple para el elemento de la lista con android:background="?android:attr/activatedBackgroundIndicator (en el caso de Android por debajo de 4,0 que necesita para ceate el similar en dibujables):

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="?android:attr/listPreferredItemHeight" 
android:gravity="center_vertical" 
android:background="?android:attr/activatedBackgroundIndicator" 
android:orientation="horizontal" > 

<TextView 
    android:id="@+id/list_item_text" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:ellipsize="end" 
    android:singleLine="true" 
    android:textAppearance="?android:attr/textAppearanceListItemSmall" 
    android:gravity="center_vertical" 
    android:layout_margin="@dimen/double_view_margin" /> 

Y entonces, crear un simple ArrayAdapter el uso de este disposición y establecer el modo de elegir a una sola:

final ArrayAdapter<String> labelsAdapter = new ArrayAdapter<String>(getActivity(), R.layout.item_simple_list_item, R.id.list_item_text, labels); 

setListAdapter(labelsAdapter); 

getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); 

Después de eso puede hightlight el elemento necesario con setItemChecked método:

@Override 
public void onListItemClick(final ListView l, final View v, final int position, final long id) { 
    getListView().setItemChecked(position, true); 
} 
+0

Si no invalida 'onListItemClick', entonces' ListFragment' establecerá automáticamente ese elemento como marcado. O simplemente asegúrate de llamar a 'super.onListItemClick (...)'. – Gautam

Cuestiones relacionadas