Diseñar una IU es solo una parte de la creación de una vista personalizada. También debes Haz que tu vista responda a la entrada del usuario de una manera que se parezca mucho a la real que estás imitando.
Haz que los objetos de tu app actúen como lo hacen los objetos reales. Por ejemplo, no dejes que las imágenes de tu app desaparecen y vuelven a aparecer en otro lugar, ya que los objetos en el mundo real no hagan eso. En cambio, mueve tus imágenes de un lugar a con el otro.
Los usuarios perciben un comportamiento o una sensación incluso sutiles en una interfaz y reaccionan mejor a sutilezas que imitan el mundo real. Por ejemplo, cuando los usuarios deslizan un objeto de IU, les dan una sensación de inercia al comienzo que retrasa el movimiento. Al final del movimiento, dales una sensación de momentum que lleva el objeto más allá del lanzamiento.
En esta página, se muestra la manera de usar las funciones del framework de Android para agregar estos comportamientos del mundo real a tu vista personalizada.
Puedes encontrar más información relacionada en Descripción general de los eventos de entrada y Animación de la propiedad descripción general.
Cómo controlar los gestos de entrada
Al igual que muchos otros marcos de trabajo de la IU, Android admite un modelo de evento de entrada. Usuario
acciones se convierten en eventos que activan devoluciones de llamada, y puedes anular el
de llamadas para personalizar la respuesta de tu app al usuario. La entrada más común
evento en el sistema Android es el táctil, que activa
onTouchEvent(android.view.MotionEvent)
Anula este método para controlar el evento, como se indica a continuación:
Kotlin
override fun onTouchEvent(event: MotionEvent): Boolean { return super.onTouchEvent(event) }
Java
@Override public boolean onTouchEvent(MotionEvent event) { return super.onTouchEvent(event); }
Los eventos táctiles por sí solos no son particularmente útiles. IU táctiles modernas
definen las interacciones en términos de gestos como tocar, tirar, empujar,
deslizar y hacer zoom. Para convertir eventos táctiles sin procesar en gestos, Android
proporciona
GestureDetector
Para crear un GestureDetector
, pasa una instancia de una clase.
que implementa
GestureDetector.OnGestureListener
Si solo quieres procesar algunos gestos, puedes extender
GestureDetector.SimpleOnGestureListener
en lugar de implementar GestureDetector.OnGestureListener
interfaz de usuario. Por ejemplo, este código crea una clase que extiende
GestureDetector.SimpleOnGestureListener
y anulaciones
onDown(MotionEvent)
Kotlin
private val myListener = object : GestureDetector.SimpleOnGestureListener() { override fun onDown(e: MotionEvent): Boolean { return true } } private val detector: GestureDetector = GestureDetector(context, myListener)
Java
class MyListener extends GestureDetector.SimpleOnGestureListener { @Override public boolean onDown(MotionEvent e) { return true; } } detector = new GestureDetector(getContext(), new MyListener());
Ya sea que uses o no GestureDetector.SimpleOnGestureListener
,
implementar siempre un
onDown()
que muestre true
. Esto es necesario porque todos los gestos
comienza con un mensaje onDown()
. Si devuelves false
de onDown()
, como
Si GestureDetector.SimpleOnGestureListener
lo hace, el sistema supone que
quieres ignorar el resto del gesto y los demás métodos de
No se llama a GestureDetector.OnGestureListener
. Solo devolución
false
de onDown()
si quieres ignorar un mensaje completo
gesto.
Después de implementar GestureDetector.OnGestureListener
y crear
una instancia de GestureDetector
, puedes usar tu
GestureDetector
para interpretar los eventos táctiles que recibes en
onTouchEvent()
Kotlin
override fun onTouchEvent(event: MotionEvent): Boolean { return detector.onTouchEvent(event).let { result -> if (!result) { if (event.action == MotionEvent.ACTION_UP) { stopScrolling() true } else false } else true } }
Java
@Override public boolean onTouchEvent(MotionEvent event) { boolean result = detector.onTouchEvent(event); if (!result) { if (event.getAction() == MotionEvent.ACTION_UP) { stopScrolling(); result = true; } } return result; }
Cuando pasas a onTouchEvent()
un evento táctil que no
reconoce como parte de un gesto, muestra false
. Luego, puedes ejecutar
tu propio código personalizado de detección de gestos.
Crear movimientos físicamente posibles
Los gestos son una forma poderosa de controlar los dispositivos con pantalla táctil, pero pueden ser sean contradictorios y difíciles de recordar, a menos que produzcan resultados creíbles.
Por ejemplo, supongamos que quieres implementar un gesto de deslizamiento horizontal que establece el elemento dibujado en la vista que gira alrededor de su eje vertical. Este gesto tiene sentido si la IU responde moviéndose rápidamente en la dirección del lanzamiento, y luego se vuelve más lenta, como si el usuario empujara un volante y lo hiciera girar.
La documentación sobre cómo
animar un pergamino
brinda una explicación detallada sobre cómo implementar tu propio Scoll
el comportamiento de los usuarios. Pero simular la sensación de un volante no es trivial. Mucha física
y matemáticas para que un modelo de volante funcione correctamente. Afortunadamente,
Android proporciona clases auxiliares para simular este y otros comportamientos. El
Scroller
es la base para controlar los gestos de desplazamiento tipo volante.
Para iniciar un lanzamiento, llama
fling()
con la velocidad inicial y los valores mínimos y máximos de x y de y
valores del lanzamiento. Para el valor de velocidad, puedes usar el valor calculado por
GestureDetector
Kotlin
fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean { scroller.fling( currentX, currentY, (velocityX / SCALE).toInt(), (velocityY / SCALE).toInt(), minX, minY, maxX, maxY ) postInvalidate() return true }
Java
@Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { scroller.fling(currentX, currentY, velocityX / SCALE, velocityY / SCALE, minX, minY, maxX, maxY); postInvalidate(); return true; }
La llamada a fling()
configura el modelo físico para el lanzamiento.
gesto. Luego, actualiza el Scroller
llamando a
Scroller.computeScrollOffset()
a intervalos regulares. computeScrollOffset()
actualiza el
El estado interno del objeto Scroller
lee la hora actual y
usando el modelo físico para calcular la posición y y x en ese
tiempo. Llamada
getCurrX()
y
getCurrY()
para recuperar estos valores.
La mayoría de las vistas pasan x e y del objeto Scroller
.
posiciones directamente en
scrollTo()
Este ejemplo difiere un poco: utiliza la posición x de desplazamiento actual
para configurar el ángulo de rotación de la vista.
Kotlin
scroller.apply { if (!isFinished) { computeScrollOffset() setItemRotation(currX) } }
Java
if (!scroller.isFinished()) { scroller.computeScrollOffset(); setItemRotation(scroller.getCurrX()); }
La clase Scroller
calcula las posiciones de desplazamiento por ti, pero
no aplica automáticamente esas posiciones a tu vista. Aplicar coordenadas nuevas
con suficiente frecuencia para que la animación de desplazamiento se vea fluida. Hay dos maneras de
haz lo siguiente:
- Llama para forzar un nuevo diseño
postInvalidate()
después de llamar afling()
. Esta técnica requiere que de desplazamiento de Compute enonDraw()
y llamar apostInvalidate()
cada vez que se desplace el desplazamiento cambios. - Configura un
ValueAnimator
para animar durante el lanzamiento y agregar un objeto de escucha para procesar actualizaciones de animaciones llamandoaddUpdateListener()
Esta técnica permite animar propiedades de unView
Cómo hacer que tus transiciones sean fluidas
Los usuarios esperan que una IU moderna realice una transición fluida entre estados: elementos de la IU un fundido de entrada y salida en lugar de aparecer y desaparecer, y los movimientos que comienzan y terminar sin problemas, en lugar de iniciarse y detenerse abruptamente. Android animación de propiedades de Terraform facilita las transiciones fluidas.
Para usar el sistema de animación, cada vez que una propiedad cambia lo que afecta tu
la apariencia de la vista, no cambies la propiedad directamente. En cambio, usa
ValueAnimator
para realizar el cambio. En el siguiente ejemplo,
modificar el componente secundario seleccionado en la vista hace que todo el
o la vista rotativa para que el puntero de selección esté centrado.
ValueAnimator
cambia la rotación durante un período de varios cientos.
en lugar de establecer de inmediato
el nuevo valor de rotación.
Kotlin
autoCenterAnimator = ObjectAnimator.ofInt(this, "Rotation", 0).apply { setIntValues(targetAngle) duration = AUTOCENTER_ANIM_DURATION start() }
Java
autoCenterAnimator = ObjectAnimator.ofInt(this, "Rotation", 0); autoCenterAnimator.setIntValues(targetAngle); autoCenterAnimator.setDuration(AUTOCENTER_ANIM_DURATION); autoCenterAnimator.start();
Si el valor que quieres cambiar es uno de los View
base
propiedades, hacer la animación es aún más fácil porque las vistas tienen una
ViewPropertyAnimator
que está optimizado para la animación simultánea de múltiples propiedades, como en
siguiente ejemplo:
Kotlin
animate() .rotation(targetAngle) .duration = ANIM_DURATION .start()
Java
animate().rotation(targetAngle).setDuration(ANIM_DURATION).start();