有人可以解释attr吗?


89

我正在查看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>

不幸的是,这令我更加困惑。这是在做什么

Answers:


64

?attr/menuIconCamera值表示menuIconCamera将使用当前主题属性的图标。

必须menuIconCamerathemes.xml文件中的某处为该属性分配一个可绘制对象。如果有两个具有不同属性值的主题,则实际图标将取决于当前使用的主题。

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


1
您说得对,<item name =“ menuIconCamera”> @ drawable / ic_menu_camera_holo_light </ item>,非常感谢。我看到ic_menu_camera_holo_light是本地可绘制对象。3.x是否没有像2.x那样内置的公共图标?
FuegoFingers 2011年

我认为这与Android版本无关。这只是使属性依赖于所选主题的一种方法。
迈克尔

51

?attr:语法用于访问当前主题的属性。请参见引用样式属性


3
提供的链接非常非常有帮助。谢谢!
sven

3
很有帮助,但您仍应发布该链接的主要部分。
gustavohenke

1
这是链接文章中最有用的部分:'样式属性资源允许您在当前应用的主题中引用属性的值。通过引用样式属性,您可以通过对UI元素进行样式设置以匹配当前主题提供的标准变体来自定义UI元素的外观,而不是提供硬编码的值。引用样式属性本质上说,“在当前主题中使用此属性定义的样式。”
bigtex777,2016年

24

我知道这篇文章很旧,但是我认为以下说明将有助于初学者轻松理解。

所以用外行的话来说

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>

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


16

我的英语不好,对不起。但是我知道这个问题

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

这用于引用样式属性。见R.attr

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

引用样式属性


3
似乎没有任何地方记录的一件事是,“ <package_name>”是声明资源的任何内容的完整包名称。更具体地说,它不是XML名称空间前缀,即使语法可能会建议这样做。例如,要引用由appcompat库声明的attr,请使用android.support.v7.appcompat:
停止危害社区2014年

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>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.