Alguém pode explicar o attr?

90

Estou olhando para o código de amostra da Galeria Honeycomb ( aqui ) e encontrei o código a seguir ao tentar adicionar itens de ação em meu próprio aplicativo:

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

O ?attrestá me deixando confuso. Alguém pode explicar o que isso está fazendo? Como isso está relacionado a um drawable? Não consigo encontrar nenhuma boa informação no Google. Também existe uma lista ou galeria de atributos que podemos usar para ícones em vez de apenas menuIconCamera?

obrigado

Edit: Eu olhei mais um pouco e descobri que attrs.xml se parece com isto:

<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>

Infelizmente, isso torna tudo ainda mais confuso para mim. O que isso está fazendo?

FuegoFingers
fonte

Respostas:

65

O ?attr/menuIconCameravalor significa que um ícone de menuIconCameraatributo do tema atual será usado.

Deve haver um drawable atribuído ao menuIconCameraatributo em algum lugar do themes.xmlarquivo. Se houver dois temas com valores diferentes desse atributo, o ícone real dependerá do tema que está sendo usado atualmente.

O attrs.xmlarquivo é usado para definir atributos personalizados. Sem essa definição, o compilador tratará atributos desconhecidos como errôneos.

Michael
fonte
1
você está exatamente certo, <item name = "menuIconCamera"> @ drawable / ic_menu_camera_holo_light </item>, Muito obrigado. Vejo que ic_menu_camera_holo_light é um drawable local. 3.x não tem ícones públicos integrados como 2.x tinha?
FuegoFingers
Não acho que esteja de alguma forma conectado à versão do Android. Essa é apenas uma maneira de tornar os atributos dependentes de um tema escolhido.
Michael,
51

A ?attr:sintaxe é usada para acessar os atributos do tema atual. Consulte os atributos de estilo de referência .

Peter Knego
fonte
3
O link fornecido foi muito, muito útil. Obrigado!
sven
3
Muito útil, mas você ainda deve postar as partes principais desse link.
gustavohenke
1
Esta foi a parte mais útil do artigo vinculado: 'Um recurso de atributo de estilo permite que você faça referência ao valor de um atributo no tema aplicado atualmente. Fazer referência a um atributo de estilo permite que você personalize a aparência dos elementos da IU, estilizando-os para corresponder às variações padrão fornecidas pelo tema atual, em vez de fornecer um valor embutido no código. Referenciar um atributo de estilo essencialmente diz, "use o estilo que é definido por este atributo, no tema atual." '
bigtex777
24

Sei que esta postagem é muito antiga, mas acho que a explicação a seguir ajudará os iniciantes a entendê-la facilmente.

Então, em termos leigos,

someAttribute="?attr/attributeName" significa -

defina o valor de someAttribute para qualquer valor de attributeName no tema atual

Um exemplo comum ocorre na estilização de uma barra de ferramentas

<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>

Aqui, o valor de android:backgroundserá definido como @color/primary_colorporque ?attr/colorPrimaryse refere a @color/primary_colorno tema atual (AppTheme)

Sziraqui
fonte
17

Meu inglês não é bom, desculpe. Mas eu conheço esta questão

android:icon="?attr/menuIconCamera" quer usar

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>

usar @drawable/ic_menu_camera_holo_light

alvorecer
fonte
4

Isso é para referenciar atributos de estilo. veja R.attr

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

Atributos de estilo de referência

Michele
fonte
3
Uma coisa que não parece estar documentada em lugar nenhum é que '<package_name>' é o nome completo do pacote de tudo o que declarou o recurso. Mais especificamente, não é um prefixo de namespace XML, embora a sintaxe possa sugerir isso. Por exemplo, para se referir a um attr declarado pela biblioteca appcompat, use android.support.v7.appcompat:.
Pare de prejudicar a comunidade
4

Esta postagem do blog faz um trabalho incrível repassando como referenciar valores para atributos de estilo que são definidos no tema atual: https://trickyandroid.com/android-resources-and-style-attributes-cheatsheet/

  • Quando você vê a ?notação - significa que estamos tentando fazer referência a um atributo de estilo - um valor que pode variar dependendo do tema atual. Em cada tema específico, podemos substituir esse atributo, para que o layout XML não precise ser alterado e o tema correto precise ser aplicado.

  • Quando você vê a @notação - referenciamos o valor real do recurso (cor, string, dimensão, etc). Este recurso deve ter um valor real. Nesse caso, sabemos exatamente com qual valor estamos lidando.

Aqui está um exemplo:

    <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>
Nazmul Idris
fonte