ListView项目选择状态不起作用

时间:2011-06-01 17:33:32

标签: android listview android-layout

所以我有一个ListView,我想改变每个项目背景和文本的颜色。此ListView位于ListFragment中。我的代码使onCreateView中的布局膨胀,并使newView中每个项目的布局膨胀。

android:state_pressed="true"工作正常,每当我按下一个项目时,背景会变为该颜色。但是当选择项目时,bg颜色或文本颜色都没有变化,即使我在选择器中定义了一个带有android:state_selected="true"的项目。

编辑:我正在使用SDK级别11(Android 3.0)和摩托罗拉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>

4 个答案:

答案 0 :(得分:46)

答案是使用android:state_activated="true"状态,而不是“选定”状态。更多相关信息:ListFragment Item Selected Background

答案 1 :(得分:2)

支持所有API级别的最佳解决方案是为列表项View实现可检查功能,这意味着列表项布局的顶视图必须实现Checkable接口(在我的情况下,它)是TextView,但同样可以应用于ViewGroupLinearLayout)。当您点击列表项时,ListView调用setChecked方法,我们会更改View的状态以使用android:state_checked="true"选择器。与列表视图android:choiceMode="singleChoice"一起,它将只选择一个项目。

诀窍是覆盖onCreateDrawableState方法并在此处为drawables设置检查状态。请参阅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>

答案 2 :(得分:1)

不要忘记为布局设置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>

答案 3 :(得分:0)

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