Подтвердить что ты не робот

Элемент ListView выбранный Состояние не работает

Итак, у меня есть ListView, и я хочу изменить цвет каждого элемента фона и текста. Этот ListView находится внутри ListFragment. Мой код раздувает макет в onCreateView и раздувает макет каждого элемента в newView.

android:state_pressed="true" работает нормально, всякий раз, когда я нажимаю один элемент, фон меняется на этот цвет. Но при выборе элемента ни цвет, ни цвет текста не изменяется, хотя я определил элемент с android:state_selected="true" в селекторе.

Изменить: я использую SDK уровня 11 (Android 3.0) и Motorola Xoom.

Макет фрагмента списка:

<?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>

Макет элемента списка:

<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>

Фоновый переключатель:

<?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>

Селектор текста:

<?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>
4b9b3361

Ответ 1

Ответ заключается в использовании состояния android:state_activated="true" вместо состояния "выбрано". Подробнее об этом здесь: ListFragment Item Selected Background

Ответ 2

Лучшим решением с поддержкой всех уровней API является реализация функции Checkable для элемента списка View, что означает, что верхний вид макета элемента списка должен реализовывать интерфейс Checkable (в моем случае это был TextView, но то же самое можно применить к классам ViewGroup, таким как LinearLayout). Когда вы нажимаете на элемент списка, метод ListView call setChecked и там мы меняем состояние представления, чтобы использовать селектор android:state_checked="true". Вместе со списком android:choiceMode="singleChoice" он выберет только один элемент.

Трюк состоит в том, чтобы переопределить метод onCreateDrawableState и установить здесь проверочное состояние для чертежей. См. Пример SelectableTextView ниже. После вызова setChecked проверенное состояние сохраняется и называется refreshDrawableState.

Пример 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;
    }
}

Пример макета selectable_list_item.xml:

<?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"/>

Пример 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>

Пример 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>

Ответ 3

Не забудьте установить clickable="true" для макета. Это решило мою проблему.

Макет списка:

<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 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>

Ответ 4

@Andrew S: Наряду с использованием активированного состояния в селекторе, активированное состояние должно быть установлено на false для случая по умолчанию, как показано ниже в селекторном коде.

<?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>