Animation is skipping frames in Android AnimatorSet

28 Views Asked by At

I'm trying to animate the width of a rectangle from 0dp to 12dp, pause for a while, then animate it back to 0dp using AnimatorSet and ScheduledExecutorService (I need to use one because I need to stop and restart the animation at will). The animation time for each phase is different, so I can't use reverse unfortunately.

For some reason I don't understand, the animation to shrink the width back down to 0dp is completely skipped. Does anyone know what I might be doing wrong?

MainActivity.kt

class MainActivity : AppCompatActivity() {

    private lateinit var knobCenterAnimatorSet: Animator
    private lateinit var knobCenterView: View
    private val executor = Executors.newSingleThreadScheduledExecutor()
    private val animator = Runnable {
        mainExecutor.execute {
            knobCenterAnimatorSet.start()
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        knobCenterView = findViewById(R.id.knob_center)

        knobCenterAnimatorSet = AnimatorSet().apply {
            val widthExpander = ObjectAnimator.ofInt(knobCenterView.width, 24)
            widthExpander.duration = resources.getInteger(R.integer.stretch_transition_time).toLong()
            widthExpander.addUpdateListener {
                knobCenterView.layoutParams.width = it.animatedValue as Int
                knobCenterView.requestLayout()
            }

            val delay = ObjectAnimator.ofFloat(knobCenterView, ALPHA, 1F)
            delay.duration = resources.getInteger(R.integer.stretch_transition_time).toLong()

            val widthContractor = ObjectAnimator.ofInt(knobCenterView.width, 0)
            widthContractor.duration = resources.getInteger(R.integer.shrink_transition_time).toLong()
            widthContractor.addUpdateListener {
                knobCenterView.layoutParams.width = it.animatedValue as Int
                knobCenterView.requestLayout()
            }

            playSequentially(widthExpander, delay, widthContractor)
        }

        startAnimation()
    }

    private fun startAnimation() {
        executor.scheduleAtFixedRate(
            animator,
            1500,
            1500,
            TimeUnit.MILLISECONDS
        )
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipChildren="false">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:orientation="horizontal">

        <View
            android:id="@+id/knob_center"
            android:layout_width="0dp"
            android:layout_height="48dp"
            android:background="@drawable/background_center"
            android:layout_gravity="center"/>
    </LinearLayout>
</FrameLayout>

enter image description here

0

There are 0 best solutions below