Componentes compuestos

Anuncio
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Interfaz de Usuario en
Dispositivos móviles.
Android Avanzado
Personalización de componentes
© 2014-2015 Escuela Politécnica Superior
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Puntos a tratar
1. Componentes compuestos
Nuevas vistas a partir de agrupaciones de vistas
2. Componentes propios
Crear nuevas vistas desde cero
3. Modificar vistas existentes
Extender la funcionalidad de vistas existentes
IUDM
© 2014-2015 Escuela Politécnica Superior
2
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Componentes compuestos
• Conjunto de vistas tratadas de forma atómica.
• Por ejemplo: Agrupar un campo de edición y un botón para que
al pulsar se borre el texto.
• Pasos para crear un componente compuesto:
1. Crear un layout de forma normal con las vistas a agrupar.
2. Crear una clase Java que extienda un ViewGroup (normalmente un
layout).
3. Asignar el layout XML que hemos creado a nuestra clase Java.
4. Utilizar el componente compuesto de forma normal (pero a partir del
espacio de nombres de la aplicación).
IUDM
© 2014-2015 Escuela Politécnica Superior
3
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Componentes compuestos
• Paso 1: Crear el Layout del componente compuesto en
los recursos de la aplicación.
• Ejemplo: <?xml version="1.0" encoding="utf­8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<EditText
android:id="@+id/editText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<Button
android:id="@+id/button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Borrar"
/>
</LinearLayout>
IUDM
© 2014-2015 Escuela Politécnica Superior
4
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Componentes compuestos
• Paso 2: crear una Subclase de ViewGroup (normalmente
un layout)
• Esqueleto de la subclase:
public class MiComponente extends LinearLayout {
public MiComponente(Context context) {
super(context);
}
public MiComponente(Context context, AttributeSet atts) {
super(context, atts);
}
}
IUDM
© 2014-2015 Escuela Politécnica Superior
5
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Componentes compuestos
• Paso 3: Asignar el layout XML a nuestro componente:
public class EdicionBorrable extends LinearLayout {
EditText editText;
Button button;
public EdicionBorrable(Context context) {
super(context);
// Creamos la interfaz a partir del layout
String infService = Context.LAYOUT_INFLATER_SERVICE;
LayoutInflater li;
li = (LayoutInflater)getContext().getSystemService(infService);
li.inflate(R.layout.edicion_borrable, this, true);
// Obtenemos las referencias a las vistas hijas
editText = (EditText)findViewById(R.id.editText);
button = (Button)findViewById(R.id.button);
}
}
IUDM
© 2014-2015 Escuela Politécnica Superior
6
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Componentes compuestos
• Paso 3.1:
• Añadir funcionalidad definiendo manejadores de eventos de
manera habitual.
• Ejemplo: borrar el contenido del cuadro de edición al pulsar el
botón.
button.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
editText.setText("");
}
});
IUDM
© 2014-2015 Escuela Politécnica Superior
7
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Componentes compuestos
• Paso 4. Uso: incluir el componente en una actividad
• Añadido como una vista cualquiera
• Añadir espacio de nombres al nombre del componente
<?xml version="1.0" encoding="utf­8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<es.ua.jtech.android.compuestos.EdicionBorrable
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
IUDM
© 2014-2015 Escuela Politécnica Superior
8
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Componentes compuestos
• Otra opción: definir el layout mediante código
public EdicionBorrable(Context context) { // CONSTRUCTOR
super(context);
// Cambiamos la orientación del layout a vertical
setOrientation(LinearLayout.VERTICAL);
// Creamos las vistas hijas
editText = new EditText(getContext());
button = new Button(getContext());
button.setText("Borrar");
// Colocamos estas vistas en el control compuesto
int lHeight = LayoutParams.WRAP_CONTENT;
int lWidth = LayoutParams.FILL_PARENT;
addView(editText, new LinearLayout.LayoutParams(lWidth, lHeight));
addView(button, new LinearLayout.LayoutParams(lWidth, lHeight));
}
IUDM
© 2014-2015 Escuela Politécnica Superior
9
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Puntos a tratar
1. Componentes compuestos
Nuevas vistas a partir de agrupaciones de vistas
2. Componentes propios
Crear nuevas vistas desde cero
3. Modificar vistas existentes
Extender la funcionalidad de vistas existentes
IUDM
© 2014-2015 Escuela Politécnica Superior
10
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Componentes propios
• Creación de nuevas vistas desde cero
• Subclase de View
• Sobrecarga de onDraw
public class MiVista extends View {
public MiVista(Context context) {
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Definir como dibujar el componente
} }
IUDM
© 2014-2015 Escuela Politécnica Superior
11
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Componentes propios: lienzo y pincel
• El método onDraw recibe un Canvas
• Encapsula el contexto gráfico de la vista
• Para dibujar algunos elementos es necesario definir
propiedades del pincel (Paint)
• Color, grosor, etc.
• Ejemplo:
Paint p = new Paint();
p.setColor(Color.RED);
• Tras definir sus propiedades, podemos utilizarlo para dibujar
elementos usando métodos de la clase Canvas
IUDM
© 2014-2015 Escuela Politécnica Superior
12
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Componentes propios: lienzo y pincel
• Propiedades pincel:
• Color plano: setARGB y setColor
• Gradientes y shaders: shaders de gradiente (LinearShader,
RadialShader, SweepShader), mapa de bits (BitmapShader),
combinación de shaders (ComposeShader)
Paint p = new Paint();
p.setColor(Color.RED);
p.setARGB(0, 255, 0, 0);
p.setShader(new RadialGradient(centerX, centerY, radius,
color0, color1, Shader.TileMode.MIRROR));
IUDM
© 2014-2015 Escuela Politécnica Superior
13
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Componentes propios: lienzo y pincel
• Propiedades pincel:
• Máscaras: suavizado (BlurMaskFilter) o relieve
(EmbossMaskFilter)
• Se aplican con setMaskFilter
IUDM
© 2014-2015 Escuela Politécnica Superior
14
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Componentes propios: lienzo y pincel
• Propiedades pincel:
• Sombras: efectos de sombras con setShadowLayer
• Filtros de color: setColorFilter (alterar color original)
• Estilo de figura: indicar con setStyle que se dibuje sólo el trazo,
el relleno, o ambos
Paint p = new Paint();
p.setStyle(Style.STROKE);
p.setStyle(Style.FILL);
p.setStyle(Style.FILL_AND_STROKE);
IUDM
© 2014-2015 Escuela Politécnica Superior
15
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Componentes propios: lienzo y pincel
• Propiedades pincel:
• Estilo del trazo
•
•
•
•
IUDM
Grosor del trazo: setStrokeWidth
El tipo de línea: setPathEffect
Uniones en polilíneas: setStrokeJoint
Forma de las terminaciones: setStrokeCap
© 2014-2015 Escuela Politécnica Superior
16
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Componentes propios: lienzo y pincel
• Propiedades pincel:
• Antialiasing: setAntiAlias(bool)
• Dithering: evitamos cambios bruscos de color para gradientes en
dispositivos con poca densidad de color con setDither(bool)
• Modo de transferencia: setXferMode
Permite dibujar solamente sobre zonas con un determinado color.
IUDM
© 2014-2015 Escuela Politécnica Superior
17
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Componentes propios: lienzo y pincel
• Propiedades lienzo (Canvas):
• Área de recorte: clipRect
• Área de recorte no rectangular: clipPath
• Transformaciones geométricas: translate, scale, rotate, skew,
setMatrix
• Almacenar y restaurar propiedades: save y restore
IUDM
© 2014-2015 Escuela Politécnica Superior
18
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Componentes propios: lienzo y pincel
• Primitivas geométricas del lienzo (Canvas):
• Puntos: drawPoint
• Líneas: drawLine
• Polilíneas: drawPath
• Objeto de la clase Path compuesto de segmentos
•
•
•
•
•
•
IUDM
Rectángulos: drawRect
Rectángulos con bordes redondeados: drawRoundRect
Círculos: drawCircle
Óvalos: drawOval
Arcos: drawArc
Todo el lienzo: drawColor o drawARGB
© 2014-2015 Escuela Politécnica Superior
19
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Componentes propios: lienzo y pincel
• Ejemplo (polilínea y rectángulo)
Paint paint = new Paint();
paint.setStyle(Style.FILL);
paint.setStrokeWidth(5);
paint.setColor(Color.BLUE);
Path path = new Path();
path.moveTo(50, 130);
path.lineTo(50, 60);
path.lineTo(30, 80);
canvas.drawPath(path, paint);
canvas.drawRect(new RectF(180, 20, 220, 80), paint);
IUDM
© 2014-2015 Escuela Politécnica Superior
20
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Cadenas de texto
• Dibujado de texto a partir de Canvas
• Normal: drawText
• Posición de cada carácter: drawPosText
• A lo largo de una ruta (Path): drawTextOnPath
• Propiedades de Paint para texto
• setTypeFace, setTextSize, setTextScaleX, setTextSkewX,
setUnderlineText, setStrikeThruText, setFakeBoldText,
setTextAlign, y cualquier otro efecto aplicado al resto de contornos
Paint ptexto = new Paint();
ptexto.setTypeface(Typeface.SANS_SERIF);
ptexto.setTextSize(10);
ptexto.setTextAlign(Align.CENTER);
canvas.drawText("Hola Mundo", posX, posY, ptexto);
IUDM
© 2014-2015 Escuela Politécnica Superior
21
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Componentes propios: otros elementos
• Imágenes: drawBitmap
• Objetos Bitmap
• Un Bitmap se puede crear a partir de una imagen, de un recurso
drawable, de un array de píxeles o vacíos.
Bitmap img = BitmapFactory.decodeResource(
getResources(), R.drawable.image_file);
• Drawables: método draw de la clase Drawable
Drawable d = getResources().getDrawable(R.drawable.resource);
d.draw( canvas );
IUDM
© 2014-2015 Escuela Politécnica Superior
22
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Medición del componente
IUDM
•
Además de sobrecargar onDraw es conveniente sobrecargar
onMeasure
•
Invocado por el sistema para asignar un tamaño al elemento antes
de asignarlo al layout
•
Para cada dimensión (altura y anchura) se reciben dos
parámetros:
• Tamaño: tamaño en píxeles solicitado
• Modo: EXACTLY, AT_MOST, UNSPECIFIED
•
Antes de finalizar onMeasure es necesaria una llamada a
setMeasuredDimension(width, height)
© 2014-2015 Escuela Politécnica Superior
23
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Medición del componente
• Ejemplo:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width = DEFAULT_SIZE; int height = DEFAULT_SIZE;
...
• width y height: las podemos declarar como miembros de la clase
para acceder a ellas desde onDraw. O también podemos usar:
this.getMeasuredWidth() y this.getMeasuredHeight()
IUDM
© 2014-2015 Escuela Politécnica Superior
24
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Medición del componente
• Ejemplo (continuación):
...
switch(widthMode) {
case MeasureSpec.EXACTLY:
width = widthSize;
break;
case MeasureSpec.AT_MOST:
if(width > widthSize) {
width = widthSize;
}
break;
}
...
IUDM
© 2014-2015 Escuela Politécnica Superior
25
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Medición del componente
• Ejemplo (continuación):
...
switch(heightMode) {
case MeasureSpec.EXACTLY:
height = heightSize;
break;
case MeasureSpec.AT_MOST:
if(height > heightSize) {
height = heightSize;
}
break;
}
this.setMeasuredDimension(width, height);
}
IUDM
© 2014-2015 Escuela Politécnica Superior
26
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Atributos propios
• Permiten parametrizar determinados elementos de
nuestras vistas
• En XML: declarar nuevo atributo
• Declaración en /res/values/attrs.xml
<?xml version="1.0" encoding="utf­8"?>
<resources>
<declare­styleable name="Grafica">
<attr name="percentage" format="integer"/>
</declare­styleable>
</resources>
• En código: Obtener valor de los atributos
IUDM
© 2014-2015 Escuela Politécnica Superior
27
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Atributos propios
• Obtener al valor del atributo desde el código:
public class GraficaView extends View {
private float mPorcentaje = 25;
public GraficaView(Context context) {
super(context);
}
public GraficaView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.init(attrs);
}
public GraficaView(Context context, AttributeSet attrs) {
super(context, attrs);
this.init(attrs);
}
private void init(AttributeSet attrs) {
TypedArray ta = this.getContext().obtainStyledAttributes(attrs,
R.styleable.Grafica);
this.mPorcentaje = ta.getInt(R.styleable.Grafica_percentage, 0);
}
}
IUDM
© 2014-2015 Escuela Politécnica Superior
28
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Atributos propios
• Uso: En el layout de la actividad:
<?xml version="1.0" encoding="utf­8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/es.ua.jtech.android.grafica"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<es.ua.jtech.android.grafica.GraficaView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:percentage="60"
/>
</LinearLayout>
IUDM
© 2014-2015 Escuela Politécnica Superior
29
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Actualización del contenido
• Forzar redibujado: método invalidate de View
miVista.invalidate();
• Es posible usarlo para realizar animaciones
• Para alto rendimiento
• Hilos, temporizadores
• SurfaceView
IUDM
© 2014-2015 Escuela Politécnica Superior
30
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Puntos a tratar
1. Componentes compuestos
Nuevas vistas a partir de agrupaciones de vistas
2. Componentes propios
Crear nuevas vistas desde cero
3. Modificar vistas existentes
Extender la funcionalidad de vistas existentes
IUDM
© 2014-2015 Escuela Politécnica Superior
31
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Modificar vistas existentes
• Alternativa simple para la creación de vistas propias
• Permite ahorrar mucho código
• Basado en:
• Herencia de la vista en la que nos queremos basar
• Extender su funcionalidad añadiendo nuevos métodos
• Modificar su comportamiento sobrecargando
IUDM
© 2014-2015 Escuela Politécnica Superior
32
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Un TextView extendido
• Primer paso: subclase de la clase que queremos
modificar
• Esqueleto:
public class MiTextView extends TextView {
public MiTextView (Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public MiTextView (Context context) {
super(context);
}
public MiTextView (Context context, AttributeSet attrs) {
super(context, attrs);
}
}
IUDM
© 2014-2015 Escuela Politécnica Superior
33
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
Un TextView extendido
• Siguiente paso: sobrecarga manejadores
@Override
public void onDraw(Canvas canvas) {
// Primero dibujamos en el canvas bajo el texto...
// ... luego mostramos el texto de la manera habitual
// haciendo uso de la clase base...
super.onDraw(canvas);
// ... y por último dibujamos cosas sobre el texto
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent keyEvent) {
// Primero realizamos las acciones que sean oportunas
// según la tecla pulsada... // ...y a continuación hacemos también uso de la clase base
return super.onKeyDown(keyCode, keyEvent);
}
IUDM
© 2014-2015 Escuela Politécnica Superior
34
Experto
en Desarrollo
de Aplicaciones
para Dispositivos
Móviles
Máster
Universitario
en Desarrollo
de Software
para Dispositivos Móviles
¿Preguntas...?
IUDM
© 2014-2015 Escuela Politécnica Superior
35
Descargar