Android: interfaz de usuario personalizada con atributos personalizados

113

Sé que es posible crear un elemento de IU personalizado (a través de View o una extensión de elemento de IU específica). Pero, ¿es posible definir nuevas propiedades o atributos para los elementos de la interfaz de usuario recién creados (me refiero a no heredados, pero completamente nuevos para definir un comportamiento específico que no puedo manejar con propiedades o atributos predeterminados)

por ejemplo, elemento mi elemento personalizado:

<com.tryout.myCustomElement
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:text="Element..."
   android:myCustomValue=<someValue>
/>

Entonces, ¿es posible definir MyCustomValue ?

Gracias

Waypoint
fuente
Hola, aquí tienes un buen artículo sobre los atributos personalizados en Android - amcmobileware.org/android/blog/2016/09/11/custom-attributes
Arkadiusz Cieśliński
Eche un vistazo a mi respuesta a esta pregunta relacionada.
Helios

Respuestas:

258

Si. Breve guía:

1. Cree un atributo XML

Cree un nuevo archivo XML dentro /res/values/attrs.xml, con el atributo y su tipo

<?xml version="1.0" encoding="UTF-8"?>
<resources>
    <declare-styleable name="MyCustomElement">
        <attr name="distanceExample" format="dimension"/>
    </declare-styleable>
</resources>

Básicamente, debe configurar uno <declare-styleable />para su vista que contenga todos sus atributos personalizados (aquí solo uno). Nunca encontré una lista completa de posibles tipos, así que supongo que debes buscar en la fuente uno. Los tipos que conozco son referencia (a otro recurso), color, booleano, dimensión, flotante, entero y cadena . Son bastante autoexplicativos

2. Utilice los atributos en su diseño.

Eso funciona de la misma manera que lo hizo anteriormente, con una excepción. Su atributo personalizado necesita su propio espacio de nombres XML.

<com.example.yourpackage.MyCustomElement
   xmlns:customNS="http://schemas.android.com/apk/res/com.example.yourpackage"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:text="Element..."
   customNS:distanceExample="12dp"
   />

Muy claro.

3.Haz uso de los valores que te pasan

Modifique el constructor de su vista personalizada para analizar los valores.

public MyCustomElement(Context context, AttributeSet attrs) {
    super(context, attrs);

    TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyCustomElement, 0, 0);
    try {
        distanceExample = ta.getDimension(R.styleable.MyCustomElement_distanceExample, 100.0f);
    } finally {
        ta.recycle();
    }
    // ...
}

distanceExamplees una variable miembro privada en este ejemplo. TypedArrayTengo muchas otras cosas para analizar otros tipos de valores.

Y eso es. Utilice el valor analizado en su Viewpara modificarlo, por ejemplo, úselo onDraw()para cambiar el aspecto en consecuencia.

uthark
fuente
7
Solo tenga en cuenta sobre TypedArray. Asegúrese de llamar a reciclaje () cuando haya terminado con ellos.
zskalnik
Aquí puede encontrar una buena lista github.com/android/platform_frameworks_base/blob/master/core/…
yahya
¿El IDE (eclipse, por ejemplo) completa automáticamente las claves / valores de los atributos personalizados?
AlikElzin-kilaka
23
para las compilaciones de Gradle que debe usar http://schemas.android.com/apk/res-autoal declarar el espacio de nombres personalizado
Dori
2
En el paso 3, simplemente puede usar String initialText = attrs.getAttributeValue("http://schemas.android.com/apk/res-auto", "initialText");donde attr es el AttributeSet que se pasa en el constructor y 'initialText' es su nombre de atributo personalizado
kosiara - Bartosz Kosarzycki
21

En su carpeta res / values, cree attr.xml. Allí puedes definir tus atributos:

<declare-styleable name="">
    <attr name="myCustomValue" format="integer/boolean/whatever" />
</declare-styleable>

Cuando desee usarlo en su archivo de diseño, debe agregar

xmlns:customname="http://schemas.android.com/apk/res/your.package.name"

y luego puedes usar el valor con customname:myCustomValue=""

María Neumayer
fuente
esta no es la respuesta, la pregunta es cómo cambiar programáticamente de Java
Fazal
-11

Si puedes, solo usa la <resource>etiqueta.
Me gusta esto:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="CodeFont" parent="@android:style/TextAppearance.Medium">
        <item name="android:layout_width">fill_parent</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:textColor">#00FF00</item>
        <item name="android:typeface">monospace</item>
    </style>
</resources>

enlace del sitio web oficial

Frank Cheng
fuente
Gracias por responder. Pero en el recurso, veo el uso de valores predeterminados "android:". Mi punto es, ¿puedo tener, por ejemplo, android: phoneNameSelected = "true" como parámetro de mi elemento de IU personalizado?
Waypoint