Estoy tratando de animar un ImageView con una lista de imágenes, iterándolas rápidamente, para que cree la impresión de una animación. Lamentablemente, da la alerta: ¡Omitió 391 cuadros! La aplicación puede estar haciendo demasiado trabajo en su subproceso principal.
Esta es mi actividad principal que implementa la interfaz de Animator.
override fun onCreate(savedInstanceState: Bundle?) { GlobalScope.launch { show(Action.Idle) } }
Mi función Animator show () (ejecuta Runnables con android.os.Handler):
fun show(action: Action){ getHandler().removeCallbacksAndMessages(null) when (action) { Action.MoveRight -> getHandler().post(getRight()) Action.MoveUp -> getHandler().post(getUp()) Action.MoveDown -> getHandler().post(getDown()) Action.MoveLeft -> getHandler().post(getLeft()) Action.Idle -> getHandler().post(idle()) } }
Mi función inactiva (anim.idle es una matriz de Ints/Drawables):
fun idle() = object : Runnable{ override fun run() { val anim = getAnimation() repeat(anim.idle!!.size){ getActivity().runOnUiThread { binding.figure.setImageResource(anim.idle[it]) binding.figure.invalidate() } Thread.sleep(500) } getHandler().postDelayed(this,5000) } }
Si bien no creo que pueda cambiar una vista adjunta a la interfaz de usuario desde un hilo de fondo, puede crear/editar vistas en un hilo de fondo (lo hago mucho)
Entonces, una posible solución podría ser crear mediante programación una serie de ImageViews en segundo plano. Entonces podría ser posible medirlos con los mismos parámetros que la interfaz de usuario en el subproceso de fondo, ya que la medición puede ser costosa (no estoy seguro de si se volverán a medir cuando se agreguen a la interfaz de usuario)
Luego, en el subproceso de la interfaz de usuario, su ciclo add
y remove
Vistas de la vista principal.
Finalmente resolví este problema. El controlador y la devolución de llamada parecían causar este problema. Lo cambié por un tiempo y ahora todo funciona bien.
Puede usar AnimationDrawable
para que ImageView
muestre una secuencia de imágenes, consulte también la guía para animar gráficos dibujables
En pocas palabras, declaras un recurso dibujable animation-list
y lo configuras como el fondo de View
(o primer plano, según tus requisitos). A continuación, puede obtener AnimationDrawable
de View
en tiempo de ejecución y usarlo para iniciar la animación.
En mi pequeño ejemplo, utilicé algunos dibujos vectoriales con diferentes matices.
para crear la animation-list
en res/drawable/colored_androids.xml :
<?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false"> <item android:drawable="@drawable/ic_android_blue_24dp" android:duration="250"/> <item android:drawable="@drawable/ic_android_mint_24dp" android:duration="250"/> <item android:drawable="@drawable/ic_android_green_24dp" android:duration="250"/> <item android:drawable="@drawable/ic_android_mint_24dp" android:duration="250"/> </animation-list>
Mi Activity
tiene un campo para AnimationDrawable
private lateinit var coloredAndroidsAnimation: AnimationDrawable
y en onCreate()
se requieren las siguientes líneas para la configuración:
findViewById<ImageView>(R.id.iv_animated).apply { setBackgroundResource(R.drawable.colored_androids) coloredAndroidsAnimation = background as AnimationDrawable setOnClickListener{ coloredAndroidsAnimation.start() } }