Como declaro um elemento da interface do usuário do Android usando XML?
xml
android
user-interface
Casebash
fonte
fonte
Respostas:
O Android Developer Guide possui uma seção chamada Building Custom Components . Infelizmente, a discussão dos atributos XML abrange apenas declarar o controle dentro do arquivo de layout e não lidar com os valores dentro da inicialização da classe. Os passos são os seguintes:
1. Declarar atributos em
values\attrs.xml
Observe o uso de um nome não qualificado na
declare-styleable
tag. Atributos do Android não padrão, comoextraInformation
necessidade de ter seu tipo declarado. As tags declaradas na superclasse estarão disponíveis nas subclasses sem precisar ser redeclaradas.2. Crie construtores
Como existem dois construtores que usam um
AttributeSet
para inicialização, é conveniente criar um método de inicialização separado para os construtores chamarem.R.styleable.MyCustomView
é umint[]
recurso gerado automaticamente , em que cada elemento é o ID de um atributo. Os atributos são gerados para cada propriedade no XML anexando o nome do atributo ao nome do elemento. Por exemplo,R.styleable.MyCustomView_android_text
contém oandroid_text
atributo paraMyCustomView
. Os atributos podem ser recuperadosTypedArray
usando váriasget
funções. Se o atributo não estiver definido no definido no XML,null
será retornado. Exceto, é claro, se o tipo de retorno for um primitivo; nesse caso, o segundo argumento será retornado.Se você não deseja recuperar todos os atributos, é possível criar essa matriz manualmente.O ID para os atributos padrão do Android está incluído
android.R.attr
, enquanto os atributos deste projeto estãoR.attr
.Observe que você não deve usar nada
android.R.styleable
, pois esse segmento pode mudar no futuro. Ainda está na documentação, pois é útil visualizar todas essas constantes em um único local.3. Use-o em arquivos de layout, como
layout\main.xml
Inclua a declaração do espaço para nome
xmlns:app="http://schemas.android.com/apk/res-auto"
no elemento xml de nível superior. Os espaços para nome fornecem um método para evitar conflitos que às vezes ocorrem quando esquemas diferentes usam os mesmos nomes de elemento (consulte este artigo para obter mais informações). O URL é simplesmente uma maneira de identificar esquemas exclusivamente - nada precisa ser hospedado nesse URL . Se isso não parece estar fazendo nada, é porque você realmente não precisa adicionar o prefixo do espaço para nome, a menos que precise resolver um conflito.Faça referência à visualização customizada usando o nome completo.
Amostra Android LabelView
Se você quiser um exemplo completo, veja a amostra de exibição de rótulo do Android.
LabelView.java
attrs.xml
custom_view_1.xml
Isso está contido em um
LinearLayout
com um atributo de espaço para nome:xmlns:app="http://schemas.android.com/apk/res-auto"
Ligações
fonte
Ótima referência. Obrigado! Uma adição a ele:
Se houver um projeto de biblioteca incluído que tenha declarado atributos personalizados para uma exibição personalizada, você deverá declarar o namespace do projeto, não o da biblioteca. Por exemplo:
Dado que a biblioteca possui o pacote "com.example.library.customview" e o projeto de trabalho possui o pacote "com.example.customview", então:
Não funcionará (mostra o erro "erro: nenhum identificador de recurso encontrado para o atributo 'newAttr' no pacote 'com.example.library.customview'"):
Funcionará:
fonte
xmlns:app="http://schemas.android.com/apk/res-auto"
Ver comentário 57 em code.google.com/p/android/issues/detail?id=9656Suspicious namespace: Did you mean http://schemas.android.com/apk/res-auto
res-auto
porque estamos usando o Android Studio e o Gradle. Caso contrário (por exemplo, algumas versões do Eclipse), geralmente terminarialib/[your package name]
. iehttp://schemas.android.com/apk/lib/[your package name]
Além da resposta mais votada.
getStyledAttributes ()
Quero adicionar algumas palavras sobre o uso de obtençãoStyledAttributes (), quando criamos uma exibição personalizada usando atributos predefinidos android: xxx. Especialmente quando usamos TextAppearance.
Como foi mencionado em "2. Criando Construtores", a visualização customizada obtém o AttributeSet na sua criação. Uso principal que podemos ver no código fonte do TextView (API 16).
O que podemos ver aqui?
obtainStyledAttributes(AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes)
O conjunto de atributos é processado por tema, de acordo com a documentação. Os valores dos atributos são compilados passo a passo. Os primeiros atributos são preenchidos a partir do tema, os valores são substituídos pelos valores do estilo e, finalmente, os valores exatos do XML para a instância de exibição especial substituem outros.
Matriz de atributos solicitados -
com.android.internal.R.styleable.TextView
É uma matriz comum de constantes. Se estamos solicitando atributos padrão, podemos construir essa matriz manualmente.
O que não é mencionado na documentação - ordem dos elementos TypedArray do resultado.
Quando a visualização customizada é declarada em attrs.xml, constantes especiais para índices de atributos são geradas. E podemos extrair valores desta maneira:
a.getString(R.styleable.MyCustomView_android_text)
. Mas para o manualint[]
não há constantes. Suponho que getXXXValue (arrayIndex) funcione bem.E outra pergunta é: "Como podemos substituir constantes internas e solicitar atributos padrão?" Podemos usar android.R.attr. * Valores.
Portanto, se quisermos usar o atributo TextAppearance padrão no modo de exibição personalizado e ler seus valores no construtor, podemos modificar o código do TextView desta maneira:
Onde CustomLabel está definido:
Talvez eu esteja enganado de alguma maneira, mas a documentação do Android em obtençãoStyledAttributes () é muito ruim.
Estendendo o componente padrão da interface do usuário
Ao mesmo tempo, podemos apenas estender o componente padrão da interface do usuário, usando todos os seus atributos declarados. Essa abordagem não é tão boa, porque o TextView, por exemplo, declara muitas propriedades. E será impossível implementar a funcionalidade completa no onMeasure () e noDraw () substituídos.
Mas podemos sacrificar a ampla reutilização teórica do componente personalizado. Diga "Eu sei exatamente quais recursos vou usar" e não compartilhe código com ninguém.
Então podemos implementar o construtor
CustomComponent(Context, AttributeSet, defStyle)
. Após a chamadasuper(...)
, todos os atributos serão analisados e disponibilizados pelos métodos getter.fonte
Parece que o Google atualizou sua página de desenvolvedor e adicionou vários treinamentos lá.
Um deles trata da criação de visualizações personalizadas e pode ser encontrado aqui
fonte
Muito obrigado pela primeira resposta.
Quanto a mim, tive apenas um problema com isso. Ao inflar minha visão, tive um bug: java.lang.NoSuchMethodException: MyView (Context, Attributes)
Eu resolvi isso criando um novo construtor:
Espero que isso ajude!
fonte
Você pode incluir qualquer arquivo de layout em outro arquivo de layout, como
aqui, os arquivos de layout na tag include são outros arquivos de layout .xml na mesma pasta res.
fonte