"?android:attr/activatedBackgroundIndicator"如何工作?

jrh*_*ath 82 android

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

如何设置这个工作呢?

  1. 涉及的机制是什么?
  2. 像"?","attr","activatedBackgroundIndicator"这样的语法元素是什么意思?
  3. "activatedBackgroundIndicator"的含义在哪里定义?

num*_*ati 217

如果您处于法医心情,那么如何挖掘并了解正在发生的事情.

android:background="?android:attr/activatedBackgroundIndicator"?
Run Code Online (Sandbox Code Playgroud)

直观地说,这意味着将背景设置为一些可绘制的.

但是让我们进一步分解,看看我们如何得到我们神秘的绘画.

确切地说,它意味着"将background属性设置为当前主题中属性"activatedBackgroundIndicator" 引用的内容.

如果您理解"在当前主题中引用"部分,您基本上已经理解了封面背后发生的一切.

基本上,activatedBackgroundIndicator不是一个实际的drawable,而是一个drawable的引用.那么"activateBackgroundIndictor"属性实际定义在哪里?

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

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

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

<attr name="activatedBackgroundIndicator" format="reference" />
Run Code Online (Sandbox Code Playgroud)

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

实际值在themes.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>
Run Code Online (Sandbox Code Playgroud)

现在我们有了神秘的绘图.如果你选择第一个,它在drawable文件夹中定义:

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

如果您打开该文件,您将看到drawable的定义,这对于了解正在发生的事情非常重要.

<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>
Run Code Online (Sandbox Code Playgroud)

这里我们定义了一个有两种状态的drawable - 默认状态只是透明背景,如果状态是"state_activated",那么我们的drawable是"list_selector_background_selected".

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

"list_selector_background_selected"是一个9补丁png文件,位于drawable-hdpi文件夹中.

现在您可以看到为什么我们将activatedBackgroundIndicator定义为引用而不是直接链接到可绘制文件 - 它允许您根据主题选择正确的drawable.

  • 一个答案就是统治他们.所以基本上如果要用相同的选择器制作XML,他可以创建自己的"activatedBackgroundIndicator"吗? (3认同)

Kir*_*irk 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

    Drawable用作激活项目的背景.

它基本上只是操作系统中定义的标准项.我似乎无法在Android源代码中找到,但这里是文档的链接.activatedBackgroundIndicator


and*_*ndr 5

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

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

这种方法还允许更大的自定义 - 而不是硬编码例如窗口背景drawable的值,它从主题获得实际的drawable,提供选择的属性作为键.这允许覆盖该属性的值.你只需要:

  1. 创建自己的主题(这只​​是"样式"资源的一个奇特的名称),最常见的是默认主题之一.
  2. 为相关属性提供您自己的值.

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

编辑

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

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