有人能解释一下attr吗?

91

我正在查看Honeycomb Gallery示例代码(这里),在尝试在我的应用中添加操作项时,我遇到了以下代码:

<item android:id="@+id/camera"
    android:title="Camera"
    android:icon="?attr/menuIconCamera"
    android:showAsAction="ifRoom" />

?attr让我感到困惑。能否有人解释一下这是在做什么?这与可绘制对象有什么关系?我在Google上找不到任何有用的信息。另外,是否有属性列表或图库可以用于图标,而不仅仅是menuIconCamera

谢谢。

编辑: 我再看看,发现attrs.xml长这样:

<resources>
<declare-styleable name="AppTheme">
    <attr name="listDragShadowBackground" format="reference" />
    <attr name="menuIconCamera" format="reference" />
    <attr name="menuIconToggle" format="reference" />
    <attr name="menuIconShare" format="reference" />
</declare-styleable>

很遗憾,这让我更加困惑了。这是做什么用的?

6个回答

65

?attr/menuIconCamera的值意味着将使用当前主题中menuIconCamera属性中的图标。

themes.xml文件中必须分配一个可绘制的值给menuIconCamera属性。如果有两个具有不同属性值的主题,则实际图标取决于当前使用的主题。

attrs.xml文件用于定义自定义属性。没有此定义,编译器将把未知属性视为错误。


1
你说得很对,<item name="menuIconCamera">@drawable/ic_menu_camera_holo_light</item>。非常感谢。我看到ic_menu_camera_holo_light是一个本地的drawable。3.x没有像2.x那样内置公共图标吗? - FuegoFingers
我不认为这与Android版本有任何关联。这只是一种使属性依赖于所选择的主题的方法。 - Michael

52

3
提供的链接非常有帮助,谢谢! - sven
3
非常有帮助,但您仍应发布该链接的主要部分。 - gustavohenke
1
这是链接文章中最有用的部分:“样式属性资源允许您引用当前应用主题中属性的值。引用样式属性允许您通过将其样式化以匹配当前主题提供的标准变体,而不是提供硬编码值来自定义UI元素的外观。引用样式属性基本上表示“使用由此属性在当前主题中定义的样式”。 - bigtex777

25

我知道这篇文章很老,但我认为下面的解释将有助于初学者更容易地理解它。

所以通俗来说,

someAttribute="?attr/attributeName" 的意思是 -

someAttribute的值设置为当前主题中attributeName的值

在设置工具栏样式时会经常遇到这种情况。

<style name="AppTheme" parent="@style/Theme.AppCompat.Light.NoActionBar">
        <item name="colorPrimary">@color/primary_color</item>
       //some more stuff here
</style>
<!-- custom toolbar style -->
<style name="myToolbar" parent="Widget.AppCompat.Toolbar">
      <item name="android:background">?attr/colorPrimary</item>
     //some code here
</style>

因为?attr/colorPrimary在当前主题(AppTheme)中指向@color/primary_color,所以android:background的值将被设置为@color/primary_color


17

非常抱歉,我的英语不好。但是我知道这个问题:

android:icon="?attr/menuIconCamera" 希望使用

attrs.xml

<resources>
    <declare-styleable name="AppTheme">
        <attr name="listDragShadowBackground" format="reference" />
        <attr name="menuIconCamera" format="reference" />
        <attr name="menuIconToggle" format="reference" />
        <attr name="menuIconShare" format="reference" />
    </declare-styleable>
</resources>

styles.xml

<style name="AppTheme.Light" parent="@android:style/Theme.Holo.Light">
        <item name="android:actionBarStyle">@style/ActionBar.Light</item>
        <item name="android:windowActionBarOverlay">true</item>
        <item name="listDragShadowBackground">@android:color/background_light</item>
        <item name="menuIconCamera">@drawable/ic_menu_camera_holo_light</item> //this....
        <item name="menuIconToggle">@drawable/ic_menu_toggle_holo_light</item>
        <item name="menuIconShare">@drawable/ic_menu_share_holo_light</item>
    </style>

使用 @drawable/ic_menu_camera_holo_light


4

3
似乎没有任何文献提到的一件事是,'<包名>'是声明资源的完整包名。更具体地说,它不是XML命名空间前缀,尽管语法可能表明了这一点。例如,要引用由appcompat库声明的attr,请使用android.support.v7.appcompat: - Stop Harming the Community

4
这篇博客非常详细地介绍了如何引用当前主题下定义的样式属性值: https://trickyandroid.com/android-resources-and-style-attributes-cheatsheet/
  • 当你看到 ? 符号时,意味着我们正在尝试引用一个样式属性值,这个值可能会因当前主题而异。在每个特定的主题中,我们都可以覆盖这个属性值,因此不需要更改 XML 布局,只需要应用正确的主题。

  • 当你看到 @ 符号时,我们引用实际的资源值(颜色、字符串、尺寸等)。该资源应该具有实际值。在这种情况下,我们确切地知道我们正在处理哪个值。

以下是一个示例:
    <style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

    <style name="LauncherButton" parent="TextAppearance.AppCompat.Medium">
        <item name="android:textColor">?colorAccent</item>
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:layout_centerHorizontal">true</item>
        <item name="android:textAllCaps">false</item>
    </style>

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