android / codelab-constraint-layout

Constraint Layout Codelab
https://codelabs.developers.google.com/codelabs/constraint-layout/
Apache License 2.0
471 stars 242 forks source link

2.0.0-beta4 onTransitionCompleted is not always called #80

Open wrozwad opened 4 years ago

wrozwad commented 4 years ago

On low ends devices there's sometimes a issue when "onTransitionCompleted" are not called.

fun MotionLayout.playTransitions(
        @IdRes val transitionSetStartId: Int,
        @IdRes val transitionSetEndId: Int
) {
    setTransitionListener(object : TransitionListener {
        override fun onTransitionCompleted(motionLayout: MotionLayout, currentId: Int) {
            //do sth
        }
        override fun onTransitionStarted(motionLayout: MotionLayout, startId: Int, endId: Int) {}
        override fun onTransitionChange(motionLayout: MotionLayout, startId: Int, endId: Int, progress: Float) {}
        override fun onTransitionTrigger(motionLayout: MotionLayout, triggerId: Int, positive: Boolean, progress: Float) {}
    })
    setTransition(transitionSetStartId, transitionSetEndId)
    transitionToEnd()
}

I found that the issue is in MotionLayout.evaluate(force: boolean) function. When we start this function with state:

mKeepAnimating == false
mInTransition == true
force == false
mTransitionGoalPosition == 1.0
mTransitionLastPosition == 0.0

Most of the time we have at least one step between evaluate() call but sometimes there's a possibility when deltaPos > 1 but mTransitionLastTime == 0. In that situation mCurrentState == mEndState so we never set newState = true when at the end we have mNeedsFireTransitionCompleted |= newState :/

Some logs:

02-12 15:29:15.509 D: onMeasure(), mNeedsFireTransitionCompleted == false
02-12 15:29:15.533 D: evaluate() false || true && (false || 1.0 != 0.0<true>)
02-12 15:29:15.534 D: position = 1.0605366, mTransitionLastPosition = 0.0, deltaPos = 1.0605366, currentTime = 306336801535810, mTransitionLastTime = 0.0, mTransitionDuration = 0.6
02-12 15:29:15.534 D: dir = 1.0 (1.0 > 0.0 && 1.0605366 >= 1.0 <true> || 1.0 <= 0.0 && 1.0605366 <= 1.0 <false>), <position = this.mTransitionGoalPosition>
02-12 15:29:15.536 D: position = 1.0 [>= 1.0], mCurrentState = 2131296397
02-12 15:29:15.537 D: mCurrentState = 2131296397, mEndState = 2131296397
jcmontesmartos commented 4 years ago

I have the same issue...I can reproduce it in beta3 & beta4

wrozwad commented 4 years ago

I created an official issue. You can starred it there: https://issuetracker.google.com/issues/149423772