2011-06-01 24 views
20

Tengo un ListView y quiero cambiar el color de los elementos de fondo y de texto. Este ListView está dentro de un ListFragment. Mi código infla el diseño en el onCreateView e infla el diseño de cada elemento en el newView.ListView Item Selected State no funciona

El android:state_pressed="true" funciona correctamente, cada vez que presiono un elemento, el fondo cambia a ese color. Pero al seleccionar un elemento, ni el color bg ni el color del texto cambian, aunque he definido un elemento con android:state_selected="true" en el selector.

Editar: Estoy usando SDK nivel 11 (Android 3.0) y un Motorola Xoom.

El diseño de lista fragmento:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="vertical"> 
    <ListView 
     android:id="@android:id/list" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent"/> 
</LinearLayout> 

El diseño de lista de elementos:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:orientation="vertical" 
    android:padding="25dp" 
    android:background="@drawable/list_item_bg_selector"> 
    <TextView android:id="@+id/form_title" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:textSize="@dimen/text_size_xlarge" 
     android:textStyle="bold" 
     android:textColor="@drawable/list_item_text_selector" /> 
    <TextView android:id="@+id/form_subtitle" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:textSize="@dimen/text_size_medium" 
     android:textStyle="normal" 
     android:layout_marginTop="5dp" 
     android:textColor="@drawable/list_item_text_selector" /> 
</LinearLayout> 

El selector de fondo:

<?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/white" /> 
    <item 
     android:state_selected="true" 
     android:drawable="@drawable/list_item_bg_selected" /> 
    <item 
     android:drawable="@color/list_bg" /> 
</selector> 

El selector de texto:

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

@Snicolas No creo que la pregunta está relacionada con éste, ni siquiera estoy usando colores semitransparentes – aromero

Respuesta

46

La respuesta es usar el estado android:state_activated="true", en lugar del estado "seleccionado". Más sobre esto aquí: ListFragment Item Selected Background

+0

se puede comprobar mi pregunta aquí, por favor, creo que se puede responder a ella :) http://stackoverflow.com/questions/14644517/xml-background-dont-change-when-i-usetablet Tahnks –

+0

No funciona para mí. ¿Puedes publicar un ejemplo XML dibujable para los estados? –

+9

android: state_activated funciona solo para API v11 y más – zest

0

@Andrew S: Junto con el uso del estado activado en el selector, el estado activado debe establecerse en falso para el caso predeterminado como se muestra en el código del selector a continuación.

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

No se olvide de establecer clickable="true" para el diseño. Esto resolvió mi problema.

lista Diseño de material:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:background="@drawable/list_item_bg_selector" 
     android:clickable="true" > 

     <TextView 
      android:id="@+id/tvNewsPreviewTitle" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:maxLines="3" 
      android:ellipsize="end" 
      android:textSize="@dimen/news_preview_title_textsize" 
      android:textStyle="bold" /> 
    </RelativeLayout> 

selector de fondo:

<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
     <item android:state_pressed="true" > 
      <shape android:shape="rectangle"> 
       <stroke android:width="1dp" android:color="@color/black" /> 
       <gradient android:startColor="@color/white" android:endColor="@color/white" /> 
      </shape> 
     </item> 
     <item> 
      <shape android:shape="rectangle"> 
       <stroke android:width="1dp" android:color="@color/holo_gray_darker" /> 
       <gradient android:startColor="@color/holo_gray_bright" android:endColor="@color/holo_gray_bright" /> 
      </shape> 
     </item> 
    </selector> 
2

La mejor solución con el apoyo de todos los niveles de la API es implementar característica comprobable para el elemento de la lista View que significa que la vista desde arriba de su diseño de elemento de lista tiene que implementar la interfaz Checkable (en mi caso fue TextView, pero lo mismo se puede aplicar en las clases ViewGroup como LinearLayout). Al hacer clic en un elemento de la lista, el ListView llama al método setChecked y allí cambiamos el estado de la vista para usar el selector android:state_checked="true". Junto con la vista de lista android:choiceMode="singleChoice", seleccionará solo un elemento.

El truco es anular el método onCreateDrawableState y establecer el estado de verificación para los modelos. Vea el ejemplo de SelectableTextView abajo. Después de llamar al setChecked, el estado verificado se almacena y se llama refreshDrawableState.

Ejemplo de SelectableTextView:

package com.example.widget.SelectableTextView; 

import android.annotation.TargetApi; 
import android.content.Context; 
import android.os.Build; 
import android.util.AttributeSet; 
import android.widget.Checkable; 
import android.widget.TextView; 

public class SelectableTextView extends TextView implements Checkable { 
    private static final int[] CHECKED_STATE_SET = { 
        android.R.attr.state_checked 
    }; 

    private boolean mChecked; 

    public SelectableTextView(Context context) { 
     super(context); 
    } 

    public SelectableTextView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public SelectableTextView(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
    } 

    @TargetApi(Build.VERSION_CODES.LOLLIPOP) 
    public SelectableTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 
     super(context, attrs, defStyleAttr, defStyleRes); 
    } 

    @Override 
    public void setChecked(boolean checked) { 
     if (mChecked != checked) { 
      mChecked = checked; 
      refreshDrawableState(); 
     } 
    } 

    @Override 
    public boolean isChecked() { 
     return mChecked; 
    } 

    @Override 
    public void toggle() { 
     setSelected(!mChecked); 
    } 

    @Override 
    protected int[] onCreateDrawableState(int extraSpace) { 
     final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); 
     if (isChecked()) { 
      mergeDrawableStates(drawableState, CHECKED_STATE_SET); 
     } 
     return drawableState; 
    } 
} 

Ejemplo de selectable_list_item.xml diseño:

<?xml version="1.0" encoding="utf-8"?> 
<com.example.widget.SelectableTextView xmlns:android="http://schemas.android.com/apk/res/android" 
      xmlns:tools="http://schemas.android.com/tools" 
      android:id="@android:id/text1" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:textColor="@color/list_item_selector_foreground" 
      android:background="@drawable/list_item_selector_background" 
      tools:text="Item 1"/> 

Ejemplo de list_item_selector_foreground.xml:

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <!-- checked --> 
    <item android:color="@color/list_item_text_active" android:state_checked="true"/> 

    <item android:color="@color/list_item_text"/> 
</selector> 

Ejemplo de list_item_selector_background.xml:

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

    <item android:drawable="@color/list_item_background"/> 
</selector> 
Cuestiones relacionadas