Creación de nuevos atributos XML

La forma más recomendable de crear una vista en Android es en XML. Trabajando de esta forma podemos usar el editor visual de layouts para diseñar de forma rápida interfaces de usuario. Todas las vistas creadas en el proyecto son añadidas a la paleta de vistas dentro de Custom & Library Views. Y podremos usarlas igual que el resto de vistas.

Además, vamos a poder añadir atributos XML a las nuevas vistas para poder configurarlas en fase de diseño. Resulta muy sencillo; no tienes más que seguir el siguiente ejercicio:

Ejercicio paso a paso: Añadiendo atributos XML.

1.    Abre el proyecto EditTextTuneado. Crea un nuevo fichero res/values/attrs.xml con el siguiente código:

<?xml version="1.0" encoding="utf-8"?>

<resources>   

     <declare-styleable name="EditTextTuneado">

        <attr name="dibujarRayas" format="boolean" />

        <attr name="posicionNumeros" format="enum">

           <enum name="derecha" value="0"/>

           <enum name="izquierda" value="1"/>

           <enum name="sin_numeros" value="2"/>

        </attr>

        <attr name="colorNumeros"  format="color" />

        <attr name="tamanyoNumeros"  format="dimension" />

    </declare-styleable>

</resources>

Para declarar un grupo de atributos que podrán ser aplicados a una vista se utiliza la etiqueta <declare-styleable>, donde hay que indicar un nombre. Por convención se utiliza el mismo nombre que el de la vista a la que se aplica, aunque el nombre podría ser diferente. Se han definido 4 atributos de 4 formatos diferentes. Existen otros formatos, como «string»,«integer»…

2.     Añade las líneas subrayadas al fichero res/layout/activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools=http://schemas.android.com/tools

    xmlns:nuevos="http://schemas.android.com/apk/res/com.example.
    edittexttuneado
"              

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context=".MainActivity" >

 

 <com.example.edittexttuneado.EditTextTuneado

     android:layout_width="fill_parent"

     android:layout_height="wrap_content"

     android:text="curso de Android\nSegunda línea\nTercera línea"

     android:textAppearance="?android:attr/textAppearanceLarge"

     android:typeface="monospace"

     nuevos:dibujarRayas="true"

     nuevos:posicionNumeros="izquierda"

     nuevos:tamanyoNumeros="16dp"

     nuevos:colorNumeros="#FF0000" />

</RelativeLayout>

Para no tener que escribir cada vez el URI del espacio de nombres se ha utilizado la directiva xmls. Puedes utilizar el alias que quieras; pero el URI al espacio de nombres ha de ser tal y como se muestra, terminando con el nombre del paquete.

3.     Para aplicar los atributos definidos introduciremos el siguiente código en el constructor de la vista:

TypedArray a = context.getTheme().obtainStyledAttributes(attrs,                                                                                           R.styleable.EditTextTuneado, 0, 0);

try{

   dibujarRayas= a.getBoolean(
             R.styleable.EditTextTuneado_dibujarRayas, true);

   posicionNumeros= a.getInteger(

             R.styleable.EditTextTuneado_posicionNumeros, 0);

   switch(posicionNumeros) {

   case0:

      pincel.setTextAlign(Paint.Align.RIGHT);

      break;

   case1:

      pincel.setTextAlign(Paint.Align.LEFT);

      break;

   }

   int colorNumeros = a.getColor(

                          R.styleable.EditTextTuneado_colorNumeros, Color.BLACK);

   pincel.setColor(colorNumeros);

   float tamanyoNumeros = a.getDimension(

                          R.styleable.EditTextTuneado_tamanyoNumeros, 12*densidad);

   pincel.setTextSize(tamanyoNumeros);

} finally {

   a.recycle();

}

Como puedes ver se utiliza la clase TypedArraypara leer los atributos introducidos. Resulta conveniente liberar la memoria de este objeto una vez utilizado (a.recycle()). Para asegurarnos que en caso de error se libera igualmente, se ha utilizado una sección try/finally. Se comienza leyendo la variable global dibujaRayasindicando el atributo correspondiente y el valor por defecto. Se hace un proceso parecido con el resto de los atributos. Estos atributos modifican alguna propiedad de pincel.

4.     Declara las siguientes variables al comienzo de la clase:

private boolean dibujarRayas;

private int posicionNumeros;

5.  Añade al final del método onDraw()el código que se indica:

@Override

protected void onDraw(Canvas canvas) {

   …  

   for (int linea = 0; linea < getLineCount(); linea++) {

      int lineaBase = getLineBounds(linea, rect);

      if (dibujarRayas) {

         canvas.drawLine(rect.left, lineaBase+2, rect.right,

                                                                                              lineaBase+2, pincel);

      }

      switch (posicionNumeros) {

      case0:

         canvas.drawText(""+ (linea+1), getWidth()-2, lineaBase,pincel);

         break;

      case1:

         canvas.drawText(""+ (linea+1), 2, lineaBase,      pincel);

         break;

      }

   }

   super.onDraw(canvas);

}

6.     Verifica el resultado.

Preguntas de repaso:   Atributos XML.