Como funciona “? Android: attr / enabledBackgroundIndicator”?

86

Eu estava procurando como destacar um item selecionado em uma lista ao exibir uma barra de ação contextual para a seleção, e a solução que encontrei foi definir o android:backgroundatributo do meu xml de layout de linha como "?android:attr/activatedBackgroundIndicator".

Como funciona essa configuração?

  1. qual é o mecanismo envolvido?
  2. o que significam os elementos de sintaxe como "?", "attr", "enabledBackgroundIndicator"?
  3. onde está definido o significado de "enabledBackgroundIndicator"?
jrharshath
fonte

Respostas:

221

Se você está com humor forense, aqui está como cavar e descobrir o que está acontecendo.

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

Intuitivamente, isso significa definir o plano de fundo para algum drawable.

Mas vamos decompor isso ainda mais para ver como chegamos ao nosso drawable misterioso.

Para ser mais preciso, significa "definir o atributo background para o que o atributo" enabledBackgroundIndicator " se refere no tema atual .

Se você entendeu a parte "refere-se ao tema atual", basicamente entendeu tudo o que está acontecendo por trás das capas.

Basicamente, activateBackgroundIndicator não é um drawable real, mas uma referência a um drawable . Então, onde o atributo "activateBackgroundIndictor" é realmente definido?

Está definido em seu diretório sdk em um nome de arquivo attrs.xml . Por exemplo:

path_to_android_sdk / platform / android-17 / data / res / values ​​/ attrs.xml

Se você abrir esse arquivo, terá a declaração da seguinte forma:

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

attrs.xml é onde você declara todos os atributos que mais tarde usará em seu xml de exibição. Observe que estamos declarando o atributo e seu tipo e não realmente atribuindo um valor aqui .

O valor real é atribuído em themes.xml . Este arquivo está localizado em:

path_to_android_sdk / platform / android-17 / data / res / values ​​/ themes.xml

Se você abrir esse arquivo, verá as múltiplas definições, dependendo do tema que estiver usando . Por exemplo, aqui estão as definições para os temas chamados Tema, Tema.Luz, Tema.Holo, Tema.Holo.Luz, respectivamente:

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

Agora temos nossos drawables misteriosos. Se você escolher o primeiro, ele será definido na pasta drawable em:

path_to_android_sdk / platform / android-17 / data / res / drawable / enabled_background.xml

Se você abrir esse arquivo, verá a definição do drawable, que é importante para entender o que está acontecendo.

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

Aqui estamos definindo um drawable com dois estados - o estado padrão é apenas o fundo transparente e se o estado for "state_activated", então nosso drawable é "list_selector_background_selected".

consulte este link para obter informações básicas sobre drawables e estados.

"list_selector_background_selected" é um arquivo png de 9 patch localizado na pasta drawable-hdpi.

Agora você pode ver porque definimos enabledBackgroundIndicator como uma referência em vez de vincular diretamente ao arquivo de drawable - ele permite que você escolha o drawable certo dependendo do seu tema.

Numan Salati
fonte
3
Uma resposta para governar todos eles. Então, basicamente, se alguém fizesse um XML com os mesmos seletores, ele poderia fazer seu próprio "enabledBackgroundIndicator"?
Gee.E
1
exatamente - você pode redefini-lo em seu theme.xml customizado b / c como um atributo de referência.
numan salati
Essa resposta me ajudou a descobrir como definir um drawable personalizado em meu item de lista de gaveta de navegação.
Tastybrownies
Este é um ótimo recurso para começar a trabalhar em selectortrabalhos personalizados usando drawables. Depois de ler isso, usei o Style Attribute Docs para preencher as peças restantes.
Maurizio
1
Você pode fornecer um exemplo de como substituir esse indicador de plano de fundo? O meu não funciona: / <style name = "AppTheme" parent = "Theme.AppCompat.Light.DarkActionBar"> <item name = "android: activateBackgroundIndicator"> @ drawable / activate_background </item> </style> activate_background.xml : <selector xmlns: android = " schemas.android.com/apk/res/android "> <item android: state_activated = "true" android: drawable = "@ color / yellow" /> <item android: drawable = "@ android: color / transparent "/> </selector>
vandus
13

Eu também me perguntei isso em um ponto. Uma grande quantidade de recursos do Android parecem ser uma caixa preta e não podem ser vistos diretamente. Posso estar perdendo-os em algum lugar, mas não consigo encontrá-los no código-fonte do SDK. Aqui está o que eu sei.

  • android:background terá um drawable.
  • A sintaxe está no estilo

    Deve ser uma referência a outro recurso, no formato "@ [+] [pacote:] tipo: nome" ou a um atributo de tema no formato "? [Pacote:] [tipo:] nome"

Neste caso o ?significa olhar para um tema em pacote androide é do tipo attronde está o nome activatedBackgroundIndicator.

Você também deve conseguir acessar isso no code-behind com android.R.attr.activatedBackgroundIndicator.

Uma lista de attrpropriedades do Android pode ser encontrada em R.attr

  • activatedBackgroundIndicator é um drawable definido no Android 3.0+ como

    Drawable usado como fundo para itens ativados.

É basicamente um item padrão definido no sistema operacional. Não consigo encontrar na fonte do Android, mas aqui está um link para a documentação. enabledBackgroundIndicator

Kirk
fonte
5

Esta é uma forma de atribuir um valor a um tema. O valor é tecnicamente desconhecido durante a compilação de recursos porque os valores do tema podem não ser conhecidos nesse ponto. Em vez disso, o valor é resolvido no tempo de execução com base no tema real obtido (mais comumente) ContextThemeWrapper.

Isso fornece uma maneira de reutilizar os valores dos recursos. Não estou falando de desempenho aqui, mas sim de organização e manutenção. O atributo atua como se fosse uma variável com a promessa de que conterá um valor real no tempo de execução.

Essa abordagem também permite maior personalização - em vez de codificar o valor de, por exemplo, drawable de plano de fundo da janela, ele obtém o drawable real de um tema, fornecendo um atributo escolhido como chave. Isso permite que você substitua o valor desse atributo. Você simplesmente precisa:

  1. Crie seu próprio tema (que é apenas um nome extravagante para um recurso de "estilo"), mais comumente derivado de um dos temas padrão.
  2. Forneça seu próprio valor para o atributo em questão.

A plataforma usará automaticamente seu valor, desde que você tenha especificado seu tema para uma atividade ou aplicativo. Você faz isso conforme descrito na pergunta. A sintaxe geral das referências de atributo de tema é descrita aqui: Atributos de estilo de referência . Você também encontrará um exemplo e uma descrição de todo o mecanismo lá.

Editar

Uma coisa que deve ser observada são os nomes reais dos atributos e sua existência em várias versões de plataforma. É bastante comum que novos atributos sejam introduzidos nas próximas versões da plataforma - por exemplo, alguns foram adicionados na versão 3.0 para fins de estilização da ActionBar.

Você deve tratar os nomes de atributos como parte da API - em outras palavras, eles fazem parte do contrato que você tem permissão para usar. Isso é muito semelhante às classes e suas assinaturas - você usa LocationManagerclasse com o propósito de obter a localização do último dispositivo porque sabe de alguma fonte (tutoriais, referências, guias oficiais, etc.) qual é o propósito desta classe. Da mesma forma, os nomes dos atributos e sua finalidade são (às vezes bem, às vezes miseravelmente) definidos na documentação da plataforma Android.

andr
fonte
2

Atualização: Há uma versão mais detalhada disponível no Guia da API, então eu gostaria de citá-la.

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 diz essencialmente, "use o estilo que é definido por este atributo, no tema atual."

Para fazer referência a um atributo de estilo, a sintaxe do nome é quase idêntica ao formato de recurso normal, mas em vez do símbolo de arroba (@), use um ponto de interrogação (?) E a parte do tipo de recurso é opcional. Por exemplo: `

Resposta Original:

numan salati já ofereceu uma resposta perfeita, mas não abordou o "?" sintaxe. Aqui está uma citação do API Guide Accessing Resources

Para fazer referência a um atributo de estilo, a sintaxe do nome é quase idêntica ao formato de recurso normal, mas em vez do símbolo de arroba (@), use um ponto de interrogação (?) E a parte do tipo de recurso é opcional. Por exemplo:

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

Teng-pao Yu
fonte