86

我正在寻找如何在显示选择的上下文操作栏时突出显示列表中的选定项目,我找到的解决方案是将android:background我的行布局 xml 的属性设置为"?android:attr/activatedBackgroundIndicator".

但是如何设置呢?

  1. 所涉及的机制是什么?
  2. “?”、“attr”、“activatedBackgroundIndicator”等语法元素是什么意思?
  3. “activatedBackgroundIndicator”的含义在哪里定义?
4

4 回答 4

221

如果您有法医的心情,这里是如何挖掘并找出正在发生的事情。

android:background="?android:attr/activatedBackgroundIndicator"?

直观地说,这意味着将背景设置为某个可绘制对象。

但是让我们进一步分解它,看看我们如何得到我们神秘的可绘制对象。

准确地说,它的意思是“将背景属性设置为当前主题中属性“activatedBackgroundIndicator”所指的内容

如果你理解了“在当前主题中所指”的部分,那么你基本上已经了解了幕后发生的一切。

基本上,activatedBackgroundIndicator 不是实际的可绘制对象,而是对可绘制对象的引用。那么“activateBackgroundIndictor”属性实际定义在哪里呢?

它在您的 sdk 目录中的文件名attrs.xml中定义。例如:

path_to_android_sdk/platforms/android-17/ data/res/values/attrs.xml

如果您打开该文件,您将声明如下:

<attr name="activatedBackgroundIndicator" format="reference" />

attrs.xml 是您声明稍后将在视图 xml 中使用的所有属性的位置。请注意,我们是在声明属性及其类型,而不是在此处实际分配值

实际值在theme.xml中分配。该文件位于:

path_to_android_sdk/platforms/android-17/ data/res/values/themes.xml

如果您打开该文件,您将看到多个定义,具体取决于您使用的主题。例如,这里分别是主题名称 Theme、Theme.Light、Theme.Holo、Theme.Holo.Light 的定义:

<item name="activatedBackgroundIndicator">@android:drawable/activated_background</item>
<item name="activatedBackgroundIndicator">@android:drawable/activated_background_light</item>
<item name="activatedBackgroundIndicator">@android:drawable/activated_background_holo_dark</item>
<item name="activatedBackgroundIndicator">@android:drawable/activated_background_holo_light</item>

现在我们有了神秘的drawables。如果您选择第一个,它将在可绘制文件夹中定义:

path_to_android_sdk/platforms/android-17/ data/res/drawable/activated_background.xml

如果您打开该文件,您将看到可绘制对象的定义,这对于理解正在发生的事情很重要。

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_activated="true" android:drawable="@android:drawable/list_selector_background_selected" />
    <item android:drawable="@color/transparent" />
</selector>

这里我们定义了一个有两种状态的drawable——默认状态只是透明背景,如果状态是“state_activated”,那么我们的drawable就是“list_selector_background_selected”。

有关可绘制对象和状态的背景信息,请参阅此链接。

“list_selector_background_selected”是一个 9 补丁 png 文件,位于 drawable-hdpi 文件夹中。

现在您可以看到为什么我们将 activateBackgroundIndicator 定义为参考而不是直接链接到可绘制文件 - 它允许您根据主题选择正确的可绘制对象。

于 2013-04-10T05:49:20.250 回答
13

有一次我也想知道这一点。大量的Android资源就像一个黑匣子,无法直接看到。我可能在某个地方错过了它们,但我在 SDK 源代码中找不到它们。这是我所知道的。

  • android:background将需要一个drawable。
  • 语法是风格

    必须是对另一个资源的引用,格式为“@[+][package:]type:name”或格式为“?[package:][type:]name”的主题属性

在这种情况下,?表示查看包中的主题,android并且它是attr名称所在的类型activatedBackgroundIndicator

您也应该能够在代码隐藏中访问它android.R.attr.activatedBackgroundIndicator

attr可以在R.attr找到Android 属性列表

  • activatedBackgroundIndicator是 Android 3.0+ 中定义的可绘制对象

    Drawable 用作激活项目的背景。

它基本上只是操作系统中定义的标准项目。我似乎无法在 Android 源代码中找到,但这里是文档的链接。激活背景指示器

于 2013-02-21T17:16:54.077 回答
5

这是从主题中附加价值的一种形式。在资源编译期间该值在技术上是未知的,因为此时可能不知道主题值。相反,该值是在运行时根据取自 (最常见) 的实际主题解析的ContextThemeWrapper

这提供了一种重用资源值的方法。我在这里不是在谈论性能方面,而是在组织和维护方面。该属性就像一个变量一样,承诺它将在运行时保存一个实际值。

这种方法还允许更大程度的定制——而不是硬编码窗口背景可绘制对象的值,而是从主题中获取实际可绘制对象,提供选择的属性作为键。这使您可以覆盖该属性的值。您只需要:

  1. 创建您自己的主题(这只​​是“样式”资源的一个花哨名称),最常见的是从默认主题之一派生。
  2. 为相关属性提供您自己的值。

如果您为活动或应用程序指定了主题,平台将自动使用您的值。你这样做就像问题中描述的那样。主题属性引用的一般语法在此处描述:引用样式属性。您还将在那里找到整个机制的示例和描述。

编辑

应该注意的一件事是实际属性名称及其在各种平台版本中的存在。在下一个平台版本中引入新属性是相当普遍的 - 例如,一些在 3.0 版中添加用于 ActionBar 样式。

您应该将属性名称视为 API 的一部分——换句话说,它们是您被允许使用的合同的一部分。这与类及其签名非常相似 - 您使用LocationManager类来获取最后一个设备位置,因为您从某些来源(教程、参考、官方指南等)知道此类的目的是什么。同样,属性名称及其用途(有时很好,有时很糟糕)在 Android 平台文档中定义。

于 2013-02-21T17:32:59.290 回答
2

更新:API 指南提供了更详细的版本,所以我想引用它。

样式属性资源允许您引用当前应用主题中的属性值。引用样式属性允许您通过设置样式以匹配当前主题提供的标准变体来自定义 UI 元素的外观,而不是提供硬编码的值。引用样式属性本质上是说,“在当前主题中使用由该属性定义的样式。”

要引用样式属性,名称语法几乎与普通资源格式相同,但使用问号 (?) 代替 at 符号 (@),并且资源类型部分是可选的。例如:`

原答案:

numan salati已经提供了一个完美的答案,但它没有解决“?” 句法。这是来自 API Guide Accessing Resources的引述

要引用样式属性,名称语法几乎与普通资源格式相同,但使用问号 (?) 代替 at 符号 (@),并且资源类型部分是可选的。例如:

?[<package_name>:][<resource_type>/]<resource_name>

于 2016-06-08T07:02:40.797 回答