Componentes compuestos
Transcripción
Componentes compuestos
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="utf8"?> <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="utf8"?> <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="utf8"?> <resources> <declarestyleable name="Grafica"> <attr name="percentage" format="integer"/> </declarestyleable> </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="utf8"?> <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