CLASE 03

Custom Views

Contenido

  • CustomView

  • Escuchando Eventos

  • Atributos Propios

  • Styling

  • Press & Hold

  • Custom Toast

CUSTOM VIEW

Custom View

Si bien el SDK de Android viene con una gran variedad de elmentos para conformar nuestra aplicación, puede ser que llegado un punto sea necesario que creemos nuestra propia Vista (recordar que las Vistas son los elementos visuales que componen nuestra app).

A veces puede ser porque necesitamos un comportamiento que no está disponible o simplemente porque vamos a re-utilizar varias veces el mismo esquema y de esa manera nos ahorramos tiempo de desarrollo y testing.

Custom View

Hay dos formas de crear una vista, una es totalmente desde cero y la otra extendiendo de otra vista.

En esta clase vamos a crear una vista, extendiendo de otra. Y particularmente vamos a extender de un layout y vamos a usar otras vistas ya a disposición para crear nuestra propia vista. Y la vista que vamos a crear es como la siguiente:

Custom View

Dijimos que ibamos a extender de una vista ya existente. Y que ibamos a componer nuestra vista de otras vistas también disponibles.

 

¿Se dan cuenta cuáles son las que vamos a usar?

Creemos el layout!

Custom View

Si vamos a usar un RelativeLayout, ¿Por qué no usamos ese ViewGroupo como padre del layout y usamos merge?

Porque si lo hicieramos nos quedaría una vista que tiene como único hijo a un RelativeLayout, en cambio con Merge, quitamos del medio a ese RelativeLayout innecesario y ahora cada una de las "sub"-vistas son hijos directos de nuestra vista

Custom View

Comencemos extendiendo de un RelativeLayout y definiendo el constructor.

Principalmente, toda vista tiene 2 constructores uno para el XML y otra para JAVA. Es decir, uno para crear un elemento en el layout y otro para crearlo desde el código. Por hoy sólo vamos a ver la del XML.

 

Dentro del constructor lo que se debe hacer es inicializar la vista, generalmente con el método init() y es ahí donde se infla el layout y se toma referencia a sus elementos

Custom View

El método init(Context) debe:

  • inflar el layout

 

  • Tomar referencia a los elementos que la componen desde la baseView

 

  • Definir el compartamiento de los botones

 

http://sebasira.com.ar/cursos/android-experto/imagen_mas.png

http://sebasira.com.ar/cursos/android-experto/imagen_menos.png

baseView = inflate(mContext, R.layout.selector_valor, this);

Custom View

Nuestra vista no es sólo un elemento visual, sino que tiene un comportamiento que debemos definirle.

Siendo que se trata de un selector de valor, sería interesante que tuviera:

  • Posibilidad de setear el valor
  • Posibilidad obtener el valor
  • Valor máximo y mínimo
  • Posibilidad cambiarle la etiqueta

 

Y finalmente los métodos para cada botón

Custom View

Con eso ya podemos hacer uso de nuestra propia vista!

 

Tengan en cuenta que las vistas propias (custom) requieren el uso del nombre completo de la misma en el XML.

 

Hagamos una app de prueba donde podamos testearla, con todas sus funciones

ESCUCHANDO EVENTOS

Escuchando Eventos

Seria bueno poder notificarnos cuando el valor cambia. Para eso, es necesario que definamos un "escuchador" (listener) para esos eventos.

 

Para ello, primero debemos crear una interface.

public interface OnValueChange {
    void OnValueChange();
}

Escuchando Eventos

La interface define el comportamiento y debemos implementar ese comportamiento en nuestra propia vista.

Además, debemos:

  • Definir un objeto para el listener de ese evento
  • Setear el listener (callback)
  • Implementar el método
  • Lanzar el evento cuando sea necesario

 

Luego definimos la acción que queremos que suceda cuando ocurre el evento, al igual que lo hacemos con el onClick de un botón

Escuchando Eventos

public void setOnValueChange_listener(OnValueChange cb){
    this.onValueChange_listener = cb;
}

@Override
public void OnValueChange() {
    if (null != this.onValueChange_listener){
        this.onValueChange_listener.OnValueChange();
    }
}

ATRIBUTOS PROPIOS

Atributos Propios

Una funcionalidad muy útil de las vistas es poder definirle los atributos desde el XML. Nosotros podemos agregarle atributos propios a nuestras vistas.

Los mismos se definen en un archivo XML (values) como el siguiente:

<?xml version="1.0" encoding="UTF-8"?>
<resources>
    <declare-styleable name="SelectorValor">
        <attr name="label" format="string"/>
    </declare-styleable>
</resources>

Atributos Propios

Luego al inicializar debemos setear los valores que se hayan establecido en el XML. 

TypedArray ta = mContext.obtainStyledAttributes(attrs, R.styleable.SelectorValor, 0, 0);
try {
    String label = ta.getString(R.styleable.SelectorValor_label);
    txtLabel.setText(label);
} finally {
    ta.recycle();
}

STYLING

Styling

Otro detalle importante es trabajar sobre la visualización de la vista, para enriquecer la experiencia de usuario.

Una de las cosas que podríamos hacer es mostrar cuando el botón está presionado.

Nuevamente, y al igual que la clase anterior, podemos hacer esto con un selector.

 

 

 

http://sebasira.com.ar/cursos/android-experto/imagen_mas_presionado.png

http://sebasira.com.ar/cursos/android-experto/imagen_menos_presionado.png

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@drawable/imagen_menos_presionado" />
    <item android:drawable="@drawable/imagen_menos" />
</selector>

PRESS & HOLD

Press & Hold

Se trata de un selector de valor, y una funcionalidad interesante es que pueda mantenerse apretado el boton (hold) e ir incrementando/decrementando el valor. 

Para ello, vamos a reaccionar frente a dos eventos:

 

  • OnLongClick
  • OnTouch (con acciones ACTION_UP y ACTION_CANCEL de MotionEvent)

 

Con ellos vamos a determinar cuando se mantiene presionado y cuan se libera.

Press & Hold

Luego, vamos a lanzar una acción que va a correr en segundo plano y que va a estar ligada al hilo de UI (UI Thread). Eso se logra con un Handler

Handler handler = new Handler();

Y luego los Runnables. Un Runnable nos permite ejecutar su tarea run en un hilo separado al hilo principal

private class AutoIncrementador implements Runnable {
    @Override
    public void run() {
        if(botonMasPresionado){
            incrementarValor();
            handler.postDelayed( new AutoIncrementador(), REPEAT_INTERVAL_MS);
        }
    }
}

Press & Hold

Para ejecutar alguno de estos runnables, debemos postearlo en el handler. Ahi se crea como un pool y se van ejecutando las tareas posteadas

handler.post(new AutoIncrementador());

CUSTOM TOAST

Custom Toast

Vamos a ver como customizar un Toast... Es muy sencillo, sólo basta con definir un layout (una vista), inflarla y setearle esa vista a nuestro Toast

LayoutInflater inflater = getLayoutInflater();
ViewGroup customLayout = (ViewGroup) findViewById(R.id.custom_toast_layout);
View toastLayout = inflater.inflate(R.layout.custom_toast, customLayout);

Toast toast = new Toast(getApplicationContext());
toast.setDuration(Toast.LENGTH_LONG);
toast.setView(toastLayout);
toast.show();

Gracias!

No dejen de consultar cualquier duda que surja

sebasira@gmail.com

www.sebasira.com.ar

Android Experto - Clase 03

By Ing. Sebastian M. Irazabal

Android Experto - Clase 03

  • 617