【问题标题】:ListSelector applies to the entire listListSelector 适用于整个列表
【发布时间】:2010-02-02 11:02:26
【问题描述】:

我有一个像这样的列表选择器的简单列表。

<ListView android:id="@+id/list" android:layout_width="fill_parent"
    android:layout_height="fill_parent" android:layout_below="@+id/round"
    android:listSelector="#99000000" android:clickable="true" android:cacheColorHint="#00000000" android:background="#00000000">
</ListView>

如您所见 android:listSelector="#99000000" 但“黑色 alpha”颜色应用于整个列表,而不是所选项目。


这就是我现在拥有的,但整个列表仍然变黑

::listview_background.xml

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

::colors.xml

<resources>
    <drawable name="list_normal">#96FFFFFF</drawable>
    <drawable name="list_active">#66000000</drawable>
    <drawable name="list_pressed">#CA000000</drawable>
</resources>

::我列表中的 xml 标签

android:listSelector="@drawable/listview_background"

【问题讨论】:

  • 我应该将选择器的文件放在哪个文件夹中?
  • 在 HoneyComb 之前的所有版本中都有一个错误,它将列表选择器 color 应用于整个列表背景。 Check out my answer to another question 了解更多详情。使用图像作为背景不是问题,因此可以使用以下所有解决方法。

标签: android


【解决方案1】:

我遇到了同样的问题,在查看其中一个平台可绘制 XML 文件时,我注意到一种方法可以通过在 XML 中创建形状来消除仅为颜色创建图像文件的需要。

例如,而不是:

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

做:

<item android:state_focused="true">
    <shape>
        <solid android:color="#66000000" />
    </shape>
</item>

除了创建一个纯色的drawable之外,它的形状是灵活的,类似于一个简单的矢量对象。所有细节都可以在这里找到:http://developer.android.com/guide/topics/resources/drawable-resource.html#Shape

【讨论】:

  • 是的!谢谢,我见过的唯一答案实际上解决了上述问题而无需解决它。
  • 为什么这不是解决方法?它仍然避免直接使用纯色资源,这是其他解决方法的工作。
  • 我不知道使用十六进制颜色值如何将不同问题的解决方案变成解决方法,但如链接文档中所述,您也可以使用颜色资源。 &lt;solid android:color="@color/list_active" /&gt;
  • 简单有效,很不错!
【解决方案2】:

我遇到了同样的问题。我有一个自定义背景图像,我不想制作该背景图像的变体,因为要表示所有不同的状态会很乏味。

所以我想做一件显而易见的事情,有一个半透明的栏覆盖在焦点列表项的顶部,当用户点击“输入”键或其他任何东西时,它会闪烁到按下的覆盖颜色,这是更多引人注目且更不透明。

解决方案是远离任何引用 listSelector 中颜色的 @color 或 @drawable。我创建了两个 3x3 像素的 .png 文件。每个都与伽马层一起保存。在我的情况下,它是两种相同的颜色,每种颜色在 Gimp 中混合,颜色层上的透明度不同。所以当你选择一个项目时,你会得到一个 25% 颜色的叠加层,当你按下它时,你会得到一个 50% 颜色的 png。我把它们作为 bg_list_item_pressed.png 和 bg_list_item_highlighted.png 放在我的drawables中

然后我将列表选择器设置为:

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

  <!-- Selected --> 
  <item 
    android:state_focused="true" 
    android:state_pressed="false" 
    android:drawable="@drawable/bg_list_item_highlighted" /> <!--  @drawable/tab_focus -->

  <!-- Pressed -->
  <item 
    android:state_pressed="true" 
    android:drawable="@drawable/bg_list_item_pressed" /> <!--  @drawable/tab_press -->

</selector> 

然后我在我的布局 xml 中将我的 listSelector 属性添加到我的 ListView:

android:listSelector="@drawable/list_selector"
android:drawSelectorOnTop="true"

现在它完全按照我想要的方式工作。包括使用方向键选择一行,然后回车点击。准确地获取突出显示和随后的压制颜色。

【讨论】:

  • 问题仍然存在:为什么我们不能将 ColorDrawable 用于单一状态?创建一个 3px 的图像来表示一种颜色只是一种解决方法,而不是一个合适的解决方案。
【解决方案3】:

如果您要为列表中的每个项目设置行布局,我就是这样做的。请注意设置为 listSelector 的透明值。 (为简洁起见,我删除了 colors.xml。)

ma​​in.xml

<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent">
  <ListView
    android:id="@android:id/list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:listSelector="#00000000"/>
</LinearLayout>

row.xml

<FrameLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/row"
  android:layout_width="fill_parent"
  android:layout_height="?android:attr/listPreferredItemHeight"
  android:background="@drawable/list_selector">
  ...
</FrameLayout>

list_selector.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="#66FFFFFF" />
    <item android:drawable="#FF666666"/> 
</selector>

【讨论】:

  • 这应该是公认的答案,因为它不依赖于某些“解决方法像素”。
  • 斯文·雅各布斯你知道的!
【解决方案4】:

贾克斯,

我试图弄清楚为什么我的整个列表都在更改设置 listSelector 的颜色,并发现这正是它应该做的,即我们正在为整个列表设置颜色,而不是为是我们想要的。

这是您想要执行的操作: 我假设您在 XML 中定义了一个 ListView。对于这个 ListView,我假设您正在使用某种适配器来设置呈现数据。同样对于这个适配器,您正在使用一些在 XML 中定义的行视图。您要做的是像这样设置此行元素的背景:

<?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="horizontal"
    android:background="@drawable/textview_selector">
        <TextView       android:id="@+id/textForList"
        android:layout_height="fill_parent"
        android:layout_width="wrap_content"
        android:padding="10sp"  />
</LinearLayout>

这是我存储在drawable中的textview_selector.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="@drawable/teal" />
    <item android:drawable="@drawable/white" />
</selector>

希望对你有帮助

【讨论】:

  • 这很好,但我发现它不像我预期的那样工作,因为适配器视图不确定接下来要关注哪个视图(大概只有适配器知道)。当然,必须在某个地方记录库存 ListView 的工作方式,因为它比我的代码快得多,所以我想使用它
【解决方案5】:

列表选择器是一个StateListDrawable — 它包含对列表可能处于的每个状态的多个可绘制对象的引用,例如选中、聚焦、按下、禁用...

在您的情况下,通过设置单一颜色,列表为每个状态绘制 #9000。

您需要如上所述定义一个StateListDrawable,其XML 类似于以下内容。这是您在 android:listSelector 属性中设置的内容。

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

或者,要为应用程序中的所有列表设置相同的列表选择器,您可以覆盖 Widget.ListView 主题中的选择器:

<style name="Widget.ListView" parent="Widget.AbsListView">
  <item name="android:listSelector">@drawable/my_custom_selector</item>
</style>

【讨论】:

    【解决方案6】:

    你并不总是需要创建一个图像,你可以定义一个形状

    <?xml version="1.0" encoding="utf-8"?>
    

    <item android:state_focused="true" android:state_pressed="false">
         <shape android:shape="rectangle">
             <solid android:color="#40000000"/>
         </shape>
    </item>
    <item android:state_pressed="true">
         <shape android:shape="rectangle">
             <solid android:color="#80000000"/>
         </shape>
    </item>
    

    【讨论】:

    • 我认为这比埃里克的回答要好得多。这样你就不会用无用的资源把你的项目弄得一团糟。
    猜你喜欢
    • 2022-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-22
    • 1970-01-01
    • 1970-01-01
    • 2012-10-12
    相关资源
    最近更新 更多