¿Cómo declaro un elemento de la interfaz de usuario de Android usando XML?
xml
android
user-interface
Casebash
fuente
fuente
Respuestas:
La Guía para desarrolladores de Android tiene una sección llamada Creación de componentes personalizados . Desafortunadamente, la discusión de los atributos XML solo cubre declarar el control dentro del archivo de diseño y no manejar los valores dentro de la inicialización de la clase. Los pasos son los siguientes:
1. Declarar atributos en
values\attrs.xml
Observe el uso de un nombre no calificado en la
declare-styleable
etiqueta. Los atributos de Android no estándar comoextraInformation
deben tener su tipo declarado. Las etiquetas declaradas en la superclase estarán disponibles en subclases sin tener que volver a declararlas.2. Crear constructores
Como hay dos constructores que usan una
AttributeSet
inicialización, es conveniente crear un método de inicialización separado para que los constructores llamen.R.styleable.MyCustomView
es unint[]
recurso autogenerado donde cada elemento es la ID de un atributo. Los atributos se generan para cada propiedad en el XML agregando el nombre del atributo al nombre del elemento. Por ejemplo,R.styleable.MyCustomView_android_text
contiene elandroid_text
atributo paraMyCustomView
. Los atributos se pueden recuperar delTypedArray
uso de variasget
funciones. Si el atributo no está definido en el definido en el XML,null
se devuelve. Excepto, por supuesto, si el tipo de retorno es primitivo, en cuyo caso se devuelve el segundo argumento.Si no desea recuperar todos los atributos, es posible crear esta matriz manualmente. La ID para los atributos estándar de Android están incluidos
android.R.attr
, mientras que los atributos para este proyecto están incluidosR.attr
.Tenga en cuenta que usted debe no usar nada en
android.R.styleable
, según este hilo se puede cambiar en el futuro. Todavía está en la documentación, ya que es útil ver todas estas constantes en un solo lugar.3. Úselo en archivos de diseño como
layout\main.xml
Incluya la declaración del espacio de nombres
xmlns:app="http://schemas.android.com/apk/res-auto"
en el elemento xml de nivel superior. Los espacios de nombres proporcionan un método para evitar los conflictos que a veces ocurren cuando diferentes esquemas usan los mismos nombres de elementos (consulte este artículo para obtener más información). La URL es simplemente una forma de identificar esquemas de forma única: en realidad no es necesario alojar nada en esa URL . Si parece que esto no está haciendo nada, es porque en realidad no necesita agregar el prefijo del espacio de nombres a menos que necesite resolver un conflicto.Haga referencia a la vista personalizada con el nombre completo.
Muestra de Android LabelView
Si desea un ejemplo completo, mire la muestra de vista de etiqueta de Android.
LabelView.java
attrs.xml
custom_view_1.xml
Esto está contenido en un
LinearLayout
atributo con un espacio de nombres:xmlns:app="http://schemas.android.com/apk/res-auto"
Enlaces
fuente
Gran referencia ¡Gracias! Una adición a esto:
Si tiene un proyecto de biblioteca incluido que ha declarado atributos personalizados para una vista personalizada, debe declarar el espacio de nombres de su proyecto, no el de la biblioteca. P.ej:
Dado que la biblioteca tiene el paquete "com.example.library.customview" y el proyecto de trabajo tiene el paquete "com.example.customview", entonces:
No funcionará (muestra el error "error: no se encontró un identificador de recurso para el atributo 'newAttr' en el paquete 'com.example.library.customview'"):
Trabajará:
fuente
xmlns:app="http://schemas.android.com/apk/res-auto"
Vea el comentario 57 en 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 Android Studio y Gradle. De lo contrario (por ejemplo, algunas versiones de Eclipse) generalmente terminaría enlib/[your package name]
. iehttp://schemas.android.com/apk/lib/[your package name]
Adición a la respuesta más votada.
getStyledAttributes ()
Quiero agregar algunas palabras sobre el uso de getStyledAttributes (), cuando creamos una vista personalizada usando android: xxx atributos predefinidos. Especialmente cuando usamos TextAppearance.
Como se mencionó en "2. Crear constructores", la vista personalizada obtiene AttributeSet en su creación. Uso principal que podemos ver en el código fuente de TextView (API 16).
¿Qué podemos ver aquí?
obtainStyledAttributes(AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes)
El conjunto de atributos se procesa por tema de acuerdo con la documentación. Los valores de los atributos se compilan paso a paso. Los primeros atributos se llenan del tema, luego los valores se reemplazan por los valores del estilo y, finalmente, los valores exactos de XML para la instancia de vista especial reemplazan a otros.
Matriz de atributos solicitados:
com.android.internal.R.styleable.TextView
es una matriz ordinaria de constantes. Si estamos solicitando atributos estándar, podemos construir esta matriz manualmente.
Lo que no se menciona en la documentación: orden de los elementos TypedArray de resultados.
Cuando se declara una vista personalizada en attrs.xml, se generan constantes especiales para los índices de atributos. Y podemos extraer los valores de esta manera:
a.getString(R.styleable.MyCustomView_android_text)
. Pero para el manualint[]
no hay constantes. Supongo que getXXXValue (arrayIndex) funcionará bien.Y otra pregunta es: "¿Cómo podemos reemplazar las constantes internas y solicitar atributos estándar?" Podemos usar los valores de android.R.attr. *.
Entonces, si queremos usar el atributo TextAppearance estándar en una vista personalizada y leer sus valores en el constructor, podemos modificar el código de TextView de esta manera:
Donde se define CustomLabel:
Tal vez, estoy equivocado de alguna manera, pero la documentación de Android en getStyledAttributes () es muy pobre.
Componente de interfaz de usuario estándar extendido
Al mismo tiempo, solo podemos extender el componente de interfaz de usuario estándar, utilizando todos sus atributos declarados. Este enfoque no es tan bueno, porque TextView, por ejemplo, declara muchas propiedades. Y será imposible implementar la funcionalidad completa en anular onMeasure () y onDraw ().
Pero podemos sacrificar la reutilización teórica de componentes personalizados. Diga "Sé exactamente qué características usaré" y no comparta código con nadie.
Entonces podemos implementar constructor
CustomComponent(Context, AttributeSet, defStyle)
. Después de llamarsuper(...)
tendremos todos los atributos analizados y disponibles a través de métodos getter.fuente
Parece que Google ha actualizado su página de desarrollador y ha agregado varios entrenamientos allí.
Uno de ellos se ocupa de la creación de vistas personalizadas y se puede encontrar aquí.
fuente
Muchas gracias por la primera respuesta.
En cuanto a mí, solo tuve un problema con eso. Al inflar mi vista, tuve un error: java.lang.NoSuchMethodException: MyView (Context, Attributes)
Lo resolví creando un nuevo constructor:
Espero que esto ayude!
fuente
Puede incluir cualquier archivo de diseño en otro archivo de diseño como-
aquí los archivos de diseño en la etiqueta de inclusión son otros archivos de diseño .xml en la misma carpeta res.
fuente