棚の上のAndroidのアニメーション(パート3.「低レベル」アニメーション)

パート1.基本的なアニメーション

パート2.複雑なアニメーション

パート3.「低レベル」アニメーション

パート4.遷移アニメーション

パート5.アニメーションを操作するためのライブラリ



前のパートで説明したすべての方法は便利で便利ですが、多数のオブジェクトをアニメーション化する必要がある場合、それらは適切ではない可能性があります。 このパートでは、非常に多くのオブジェクトを操作し、プログラム的に複雑なアニメーションを作成する方法を見ていきます。



パート3.「低レベル」アニメーション



1.キャンバスビューでの描画



画像



最初にonDraw



方法は、 View



オブジェクトのonDraw



メソッドで描画することです。 このメソッドは、 onDraw



をオーバーライドし、最後にpostInvalidateOnAnimation()



を呼び出すだけで実装されます。



この例では、 drawable



はx軸に沿って移動します。



 override fun onDraw(canvas: Canvas) { super.onDraw(canvas) x += resources.getDimension(R.dimen.speed) drawable.setBounds(x, y, x + size, y + size) drawable.draw(canvas) postInvalidateOnAnimation() }
      
      





上記のスノーフレークの例では、もう少しコードが必要です。 個々のスノーフレークの状態を個別に保存する必要があります。



コードを見せてください!
 class SnowAnimation : View { ... private lateinit var snowflakes: Array<Snowflake> override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) { snowflakes = Array(10, { Snowflake(right - left, bottom - top, context.getDrawable(R.drawable.snowflake), resources.getDimension(R.dimen.max_snowflake_size), resources.getDimension(R.dimen.max_snowflake_speed)) }) } override fun onDraw(canvas: Canvas) { super.onDraw(canvas) snowflakes.forEach { it.update() it.draw(canvas) } postInvalidateOnAnimation() } }
      
      





 internal class Snowflake(private val containerWidth: Int, private val containerHeight: Int, private val drawable: Drawable, private val maxSize: Float, private val maxSpeed: Float) { private var size: Double = 0.0 private var speed: Double = 0.0 private var x: Double = 0.0 private var y: Double = 0.0 init { reset() } private fun reset() { size = Math.random() * maxSize / 2 + maxSize / 2 speed = Math.random() * maxSpeed / 2 + maxSpeed / 2 y = -size; x = Math.random() * containerWidth } fun update() { y += speed if (y > containerHeight) { reset() } } fun draw(canvas: Canvas?) { if (canvas == null) { return } drawable.setBounds(x.toInt(), y.toInt(), (x + size).toInt(), (y + size).toInt()) drawable.draw(canvas) } }
      
      







アプリケーション:





利点:





短所:





2. Canvas SurfaceViewでの描画



次のアニメーションステップの計算にかなりの時間がかかる場合はどうなりますか? それでも最初の方法を使用して、計算を別のストリームに転送できます。 ただし、これでもアニメーションが100%滑らかになることはありません。 UIスレッドには、アニメーション以外のものを読み込むことができます。



Androidでは、 SurfaceView



コンポーネントを使用して、レンダリングのメインループを取り除くことができます。 また、メインサイクルに縛られなくなったため、計算とレンダリングのフローを維持する必要があります。 SurfaceView



は、ストリームを開始および停止できるコールバックを提供します。 ストリームでは、計算の最後にアニメーションを描画します。



同じスノーフレークアニメーションの実装は次のようになります。



コードを見せてください!
 class MySurfaceView : SurfaceView, SurfaceHolder.Callback { ... private lateinit var drawThread: DrawThread; init { holder.addCallback(this) } override fun surfaceCreated(holder: SurfaceHolder) { //    surface drawThread = DrawThread(getHolder(), context, measuredWidth, measuredHeight) drawThread.start() } override fun surfaceDestroyed(holder: SurfaceHolder) { var retry = true //    surface drawThread.cancel(); //          , ,   .            . while (retry) { try { drawThread.join() retry = false } catch (e: InterruptedException) { } } } } internal class DrawThread(private val surfaceHolder: SurfaceHolder, context: Context, width: Int, height: Int) : Thread() { private var snowflakes: Array<Snowflake> private var cancelled: Boolean = false init { snowflakes = Array(10, { Snowflake(width, height, context.getDrawable(R.drawable.snowflake), context.resources.getDimension(R.dimen.max_snowflake_size), context.resources.getDimension(R.dimen.max_snowflake_speed)) }) } override fun run() { while (!cancelled) { // canvas    var canvas: Canvas? = surfaceHolder.lockCanvas() try { //   onDraw  View      ,         ,    . canvas?.drawColor(Color.WHITE) snowflakes.forEach { it.update() it.draw(canvas) } } finally { if (canvas != null) { // canvas   surfaceHolder.unlockCanvasAndPost(canvas) } } } } fun cancel() { cancelled = true } }
      
      







アプリケーション:





利点:





短所:





3. OpenGL



画像

キャンバスと同様に、OpenGL APIを使用して描画できます。 写真の立方体よりも複雑なものを考えた場合、たとえばlibgdxのように、何らかのエンジンの方向を見る必要があります。 残念ながら、基本的な例でもここではかなりのスペースを占有するため、この短いプレビューのみに限定します。



アプリケーション:





利点:





短所:





ここですべての例を見て勉強できます



All Articles