ti-enxame.com

Como funciona o "? Android: attr / enabledBackgroundIndicator"?

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:background atributo do meu XML de layout de linha para "?android:attr/activatedBackgroundIndicator".

Como a configuração desse trabalho funciona?

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

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

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

Intuitivamente, isso significa definir o plano de fundo para alguns desenháveis.

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

Para ser mais preciso, significa "definir o atributo de segundo plano com o que o atributo" enabledBackgroundIndicator "" se refere no tema atual .

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

Basicamente, enabledBackgroundIndicator não é um drawable real, mas uma referência a um drawable . Então, onde está realmente definido o atributo "enableBackgroundIndictor"?

É definido no 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, fará a declaração da seguinte maneira:

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

attrs.xml é onde você declara todos os atributos que mais tarde usará em seu view xml. Observe que estamos declarando o atributo e seu tipo e não 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 em uso . Por exemplo, aqui estão as definições dos temas Tema, Tema.Light, Tema.Holo, Tema.Holo.Light, 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 misteriosos desenhos. 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 desenho 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 plano de fundo transparente e se o estado for "state_activated", então o nosso drawable é "list_selector_background_selected".

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

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

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

217
numan salati

Eu me perguntava isso também em um ponto. Uma grande quantidade dos recursos Android parece ser uma caixa preta e não pode vê-los diretamente. Posso estar sentindo falta deles em algum lugar, mas não consigo encontrá-los na fonte do SDK Aqui está o que eu sei.

  • Android:background pegará um drawable.
  • A sintaxe está no estilo

    Deve ser uma referência a outro recurso, no formato "@ [+] [package:] type: name" ou a um atributo de tema no formulário "? [Package:] [type:] name"

Nesse caso, o ? significa olhar para um tema no pacote Android e é do tipo attr onde o nome é activatedBackgroundIndicator.

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

Uma lista de propriedades Android attr _ pode ser encontrada em R.attr

  • activatedBackgroundIndicator é um drawable definido em Android 3.0+ como

    Drawable usado como pano de fundo para itens ativados.

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

13
Kirk

Esta é uma forma de anexar um valor de um tema. Tecnicamente, o valor não é conhecido durante a compilação de recursos porque os valores do tema podem não ser conhecidos nesse momento. Em vez disso, o valor é resolvido no tempo de execução com base no tema real extraído de (mais comumente) ContextThemeWrapper.

Isso fornece uma maneira de reutilizar valores de recursos. Não estou falando sobre desempenho aqui, mas sobre organização e manutenção. O atributo age como se fosse uma variável com a promessa de manter 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 fundo da janela, obtém o drawable real de um tema, fornecendo um atributo escolhido como chave. Isso permite você substituir o valor desse atributo. Você simplesmente precisa:

  1. Crie seu próprio tema (que é apenas um nome sofisticado para um recurso de "estilo"), geralmente 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 como descrito na pergunta. A sintaxe geral das referências a atributos de tema é descrita aqui: Referenciando atributos de estilo . Você também encontrará um exemplo e uma descrição de todo o mecanismo.

Editar

Uma coisa que deve ser notada são os nomes dos atributos reais e sua existência em várias versões da 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 com a finalidade de estilizar o 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 parecido com as classes e suas assinaturas - você usa a classe LocationManager para obter o último local do dispositivo porque você sabe de alguma fonte (tutoriais, referências, guias oficiais, etc.) qual é o objetivo desta classe. Da mesma forma, os nomes dos atributos e seus propósitos são (às vezes bem, às vezes miseravelmente) definidos na documentação Android Platform.

5
andr

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

Um recurso de atributo de estilo permite que você faça referência ao valor de um atributo no tema atualmente aplicado. A referência a um atributo de estilo permite personalizar a aparência dos elementos da interface do usuário, estilizando-os para corresponder às variações padrão fornecidas pelo tema atual, em vez de fornecer um valor codificado. A referência a um atributo de estilo diz essencialmente: "use o estilo definido por esse atributo, no tema atual".

Para fazer referência a um atributo de estilo, a sintaxe do nome é quase idêntica ao formato normal do recurso, 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 Guia da API Acessando recursos

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

? [<nome do pacote>:] [<tipo de recurso> /] <nome do recurso>

2
Teng-pao Yu