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