Drawable选择器在Jelly Bean中无法工作

13
我在ListView的每一项中都有一个可绘制选择器作为背景,以突出显示选定的行。在Ice Cream Sandwich中一切都运行良好,但在Jelly Bean中似乎无法工作。找不到任何文档说明可能导致它停止工作并需要执行什么操作来修复它。
我的意思是当我在ListView中单击一行时,该项的背景颜色不会变成@color/blue颜色,但在ICS中会变成。以下是我使用的选择器代码(listing_selector.xml):
<selector xmlns:android="http://schemas.android.com/apk/res/android" >

   <item android:state_focused="true" android:drawable="@color/blue" />

   <item android:state_pressed="true" android:drawable="@color/blue" />

   <item android:state_activated="true" android:drawable="@color/blue_selected" />  

   <item android:state_selected="true" android:drawable="@color/blue_selected" />

   <item android:drawable="@android:color/transparent" />

</selector>

这是ListView项的布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"  
    android:layout_height="fill_parent" 
    android:orientation="horizontal"
    android:background="@color/listing_selector"    
>

    <TextView 
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true" 
    />

</RelativeLayout>

这是蓝色资源:

<resources>
    <color name="blue">#ff33b5e5</color>       
</resources>

更新 1:

尝试将选择器从color文件夹移动到drawable文件夹,并将代码更新为以下内容:

android:background="@drawable/listing_selector"

更新2:

此外,在ListView上,尝试添加了这个:

    <ListView android:id="@android:id/list"
        android:layout_width="wrap_content"  
        android:layout_height="fill_parent" 
        android:listSelector="@drawable/listing_selector"   
    />

更新3:

我本以为是我的代码有问题,但是我已经从ListViewonListItemClick中删除了所有的代码,但是selector仍然无法正常工作。

更新4:

我已经缩小范围到state_selected或者state_activated无法正常工作,而state_pressed似乎可以正常工作。

更新5:

我认为我误解了,我不认为选择器被识别了。我把内置的ListView高亮显示错认为我的选择器。我现在在想这可能与我的项目设置有关。我将选择器放在库类中。也许ICS和JB之间发生了一些变化,但是将选择器移动到我的应用程序的项目中似乎没有解决它。

更新6:

好吧,在更多的抓狂之后,我又把范围缩小到state_selectedstate_activated不能被识别,因为改变state_pressed的颜色确实有效,这意味着我的选择器正在被识别。根据评论,似乎是我的应用程序特定的问题,因为其他人已经能够在Jelly Bean中使用选择器。

还有一件有趣的事情是,更改默认状态下的drawable值并没有被识别。我认为将其更改为颜色会导致列表更改为该颜色,但实际上并没有发生。

另外,在ICS中也无法正常工作。

更新7:

经过更多的抓狂之后,我发现长按菜单项会导致该项的颜色被更改。而单击某个项目仍然不起作用。甚至不确定这意味着什么。

最终更新:

我放弃了,我删除了选择器,只是在点击时刷新ListView并记住点击的位置,并从代码中对其进行高亮显示。虽然不是理想的解决方案,但不值得为修复它而付出努力。


假设您的Android依赖项已显示,项目设置应与此问题无关...这基本上是Eclipse强制要求您执行的操作。有关drawable与color的提示,请在res/color中使用android:color进行xml选择器,在res/drawable中使用android:drawable进行xml选择器。对于您所拥有的内容,与其作为颜色而不是可绘制对象使用,可能没有理由。颜色隐含具有完全不透明度,因此#ff33b5e5与#33b5e5相同。 - syklon
1
我遇到了同样的问题,最终像你一样采用了暴力解决方法(对api17进行排除),通过跟踪选定的项目并在getView下设置它们的背景(我本来就是为了选择屏幕外的项目而这样做的)。然后在onListItemClick下调用适配器的notifyDataSetChanged()。如果这个方法能够更加简洁就好了,但事实并非如此!希望这个问题能够得到解决。 - logray
@haythemsouissi 我从未找到解决方案。不幸的是,我仍在使用手动选择ListView中的项目的蛮力方法。但我没有听到任何关于它的抱怨,所以这是一个可行的,虽然不理想的解决方案。 - Kris B
我在这里找到了答案:https://dev59.com/am3Xa4cB1Zd3GeqPkfJZ#14954329 我认为这也可能解决你的问题。 - haythem souissi
啊,我确实设置了那个值。我得尝试把它移除掉。谢谢!我甚至有一段时间前将这个问题转发给了 Google+ 上的 Android 专家,但是没有得到回复。我知道这肯定是某个缺陷,因为它不工作毫无道理。 - Kris B
显示剩余5条评论
6个回答

2

好的,我认为这是与您的选择器有关的问题。尝试删除state_focused和state_activated。您可以尝试使用以下选择器:

<!-- Disabled State -->
<item
    android:state_enabled = "false"
    android:state_focused = "true"
    android:state_pressed = "true"
    android:drawable="@android:color/transparent">
</item>
<item
    android:state_enabled = "false"
    android:state_focused = "true"
    android:drawable="@android:color/transparent">
</item>

<!-- Pressed State -->
<item
    android:state_pressed = "true"
    android:state_focused = "true">
    <shape>
        <solid android:color="@color/blue"/>
    </shape>
</item>
<item
    android:state_pressed = "true"
    android:state_focused = "false">
    <shape>
        <solid android:color="@color/blue"/>
    </shape>
</item>

<!-- Normal State -->
<item
    android:drawable="@android:color/transparent">
</item>

我发现需要使用形状对象,而不是android:drawable,因为在ICS之前的手机上,整个列表将会被突出显示,而不仅仅是按下的列表项。
您也可以添加state_selected代码,但我不确定它将如何使用。请查看Jelly Bean的默认选择器代码,以了解它们使用的状态:list_selector_background.xml

1

listing_selector.xml 必须位于 res/drawable 文件夹中,并将您的 RelativeLayout 的 android:background 属性设置为以下内容:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"  
    android:layout_height="fill_parent" 
    android:orientation="horizontal"
    android:background="@drawable/listing_selector"    
>

listing_selector.xml 移动到 res/drawable 文件夹中,但仍然无法正常工作。 - Kris B
@KrisB K_Anas强调了这一行:@drawable/listing_selector - Sherif elKhatib
@SherifelKhatib 不太确定你的意思。我把 listing_selector.xml 移动到了 res/drawable 目录下,并将代码行从 android:background="@color/listing_selector" 改为了 android:background="@drawable/listing_selector"。我还有什么遗漏吗? - Kris B
@KrisB 嗯,我以为你错过了那行代码(因为你的评论)。你能试着删除这行代码并将listSelector添加到你的ListView中吗? - Sherif elKhatib
@SherifelKhatib 是的,我也试过了,没有用。我会更新我的原始帖子,让它更加清晰明了。 - Kris B
@SherifelKhatib 我已经缩小到 state_selectedstate_activated 不起作用,而 state_pressed 似乎是有效的。 - Kris B

1
我不能说为什么它在一个版本中可以工作而在另一个版本中无法工作,但我有一个替代方案。

将您的颜色定义为资源中的可绘制对象。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <drawable name="blue">#00F</drawable>
    ...
</resources>

请在您的选择器中使用此颜色可绘制对象。
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@drawable/blue" />
    ...
    ...
</selector>

试一下这个,然后告诉我。


1

来自API文档

注意:请记住,Android会应用与对象当前状态匹配的状态列表中的第一项。因此,如果列表中的第一项不包含上述任何状态属性,则它将始终被应用,这就是为什么您的默认值应该始终在最后(如下面的示例所示)。

因此,请尝试根据建议的顺序重新排列选择器的状态。在您的情况下,应该是这样的:

<selector xmlns:android="http://schemas.android.com/apk/res/android" >
   <item android:state_pressed="true" android:drawable="@color/blue" />
   <item android:state_focused="true" android:drawable="@color/blue" />
   <item android:state_selected="true" android:drawable="@color/blue_selected" />
   <item android:state_activated="true" android:drawable="@color/blue_selected" />  
   <item android:drawable="@android:color/transparent" />
</selector>

0

这是一个非常老的问题,但我仍然支持Jellybean,并且我注意到为了使背景选择器起作用,我需要做一些特定的事情。如果我有一个带有背景可绘制物的视图组,并且我需要在其上使用选择器颜色,则需要按照以下顺序进行操作:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/my_drawable_button"/>

my_drawable_button现在必须引用一个选择器:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/primary_background_pressed"
        android:state_pressed="true" />
    <item android:drawable="@drawable/primary_background"
        android:state_enabled="true" />
    <item android:drawable="@drawable/primary_background_disabled"
        android:state_enabled="false" />
</selector>

primary_background.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners android:radius="8dp" />
    <solid android:color="@color/secondary" />
</shape>

其它的与颜色不同。这是一大堆代码去做一些非常基本的事情,但我发现在Jellybean上这是唯一的解决方案。
未来的API级别允许您在可绘制的实心本身上指定颜色选择器,消除4个文件: post api 21:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/purple">
    <item>
        <shape android:shape="rectangle">
            <corners android:radius="8dp" />
            <solid android:color="@color/button_selector" />
        </shape>
    </item>
</ripple>

button_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/gray" android:state_enabled="false"/>
    <item android:color="@color/secondary"/>
</selector>

0

我认为它运行良好!!

你的选择器XML文件代码:

<?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">

        <item android:drawable="@color/gray" android:state_focused="true"/>
        <item android:drawable="@color/gray" android:state_pressed="true"/>
        <item android:drawable="@color/orange" android:state_activated="true"/>
        <item android:drawable="@color/orange" android:state_selected="true"/>
        <item android:drawable="@color/orange"/>

    </selector>

现在在res文件夹下创建一个名为values-v16的文件夹,然后将这个颜色文件放进去。
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <color name="gray">#4f4f4f</color>
    <color name="orange">#e26c0e</color>

</resources>

然后是列表视图:

<ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_marginTop="20dp"
        android:listSelector="@drawable/listing_selector" >
</ListView>

希望这个能够正常工作!已在4.1版本上进行了测试。


我发现的唯一区别是将颜色文件放置在values-v16下面。 - Chandrashekhar
谢谢,我的项目设置可能有问题,所以我认为在Jelly Bean中没有任何改变。不过还需要进一步解决。 - Kris B

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接