From 6ba147ef15c4b66d287558e58578b63efcc0a6b8 Mon Sep 17 00:00:00 2001 From: Sascha Huth Date: Wed, 4 Apr 2018 15:18:32 +0100 Subject: [PATCH] fix animation issue when adapter is used --- README.md | 2 +- sequencelayout/build.gradle | 4 +- .../sequencelayout/SequenceLayout.kt | 95 ++++++++++--------- 3 files changed, 52 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index 503b4b7..6e4d47d 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ And then the actual library dependency to your module's `build.gradle`: ```groovy dependencies { - compile 'com.github.transferwise:sequence-layout:1.0.5' + implementation 'com.github.transferwise:sequence-layout:1.0.6' } ``` diff --git a/sequencelayout/build.gradle b/sequencelayout/build.gradle index ea642fa..2e70b73 100644 --- a/sequencelayout/build.gradle +++ b/sequencelayout/build.gradle @@ -11,8 +11,8 @@ android { defaultConfig { minSdkVersion 19 targetSdkVersion 27 - versionCode 5 - versionName "1.0.5" + versionCode 6 + versionName "1.0.6" archivesBaseName = "com.transferwise.sequencelayout-${versionName}" } diff --git a/sequencelayout/src/main/java/com/transferwise/sequencelayout/SequenceLayout.kt b/sequencelayout/src/main/java/com/transferwise/sequencelayout/SequenceLayout.kt index dba6cd0..4de861f 100644 --- a/sequencelayout/src/main/java/com/transferwise/sequencelayout/SequenceLayout.kt +++ b/sequencelayout/src/main/java/com/transferwise/sequencelayout/SequenceLayout.kt @@ -65,6 +65,7 @@ public class SequenceLayout(context: Context?, attrs: AttributeSet?, defStyleAtt private var progressForegroundColor: Int = 0 public fun start() { + removeCallbacks(animateToActive) viewTreeObserver.addOnGlobalLayoutListener(this) } @@ -107,6 +108,7 @@ public class SequenceLayout(context: Context?, attrs: AttributeSet?, defStyleAtt * Replaces all contained [com.transferwise.sequencelayout.SequenceStep]s with those provided and bound by the adapter */ public fun setAdapter(adapter: SequenceAdapter) where T : Any { + stop() removeAllSteps() val count = adapter.getCount() for (i in 0 until count) { @@ -159,62 +161,60 @@ public class SequenceLayout(context: Context?, attrs: AttributeSet?, defStyleAtt lastOffset = totalDotOffset } - val layoutParams = progressBarBackground.layoutParams as MarginLayoutParams - layoutParams.topMargin = firstOffset + 4.toPx() //TODO dynamic dot size - layoutParams.height = lastOffset - firstOffset + val backgroundLayoutParams = progressBarBackground.layoutParams as MarginLayoutParams + backgroundLayoutParams.topMargin = firstOffset + 4.toPx() //TODO dynamic dot size + backgroundLayoutParams.height = lastOffset - firstOffset progressBarBackground.requestLayout() - val layoutParams2 = progressBarForeground.layoutParams as MarginLayoutParams - layoutParams2.topMargin = firstOffset + 4.toPx() //TODO dynamic dot size - layoutParams2.height = lastOffset - firstOffset + val foregroundLayoutParams = progressBarForeground.layoutParams as MarginLayoutParams + foregroundLayoutParams.topMargin = firstOffset + 4.toPx() //TODO dynamic dot size + foregroundLayoutParams.height = lastOffset - firstOffset progressBarForeground.requestLayout() } - private fun animateToActive() { + private val animateToActive = { progressBarForeground.visibility = VISIBLE progressBarForeground.pivotY = 0f progressBarForeground.scaleY = 0f val activeStepIndex = stepsWrapper.children().indexOfFirst { it is SequenceStep && it.isActive() } - if (activeStepIndex == -1) { - return - } + if (activeStepIndex != -1) { + val activeDot = dotsWrapper.getChildAt(activeStepIndex) + val activeDotTopMargin = (activeDot.layoutParams as LayoutParams).topMargin + val progressBarForegroundTopMargin = (progressBarForeground.layoutParams as LayoutParams).topMargin + val scaleEnd = (activeDotTopMargin + (activeDot.measuredHeight / 2) - progressBarForegroundTopMargin) / + progressBarBackground.measuredHeight.toFloat() - val activeDot = dotsWrapper.getChildAt(activeStepIndex) - val activeDotTopMargin = (activeDot.layoutParams as LayoutParams).topMargin - val progressBarForegroundTopMargin = (progressBarForeground.layoutParams as LayoutParams).topMargin - val scaleEnd = (activeDotTopMargin + (activeDot.measuredHeight / 2) - progressBarForegroundTopMargin) / - progressBarBackground.measuredHeight.toFloat() - - progressBarForeground - .animate() - .setStartDelay(resources.getInteger(R.integer.sequence_step_duration).toLong()) - .scaleY(scaleEnd) - .setInterpolator(LinearInterpolator()) - .setDuration(activeStepIndex * resources.getInteger(R.integer.sequence_step_duration).toLong()) - .setUpdateListener({ - val animatedOffset = progressBarForeground.scaleY * progressBarBackground.measuredHeight - dotsWrapper - .children() - .forEachIndexed { i, view -> - if (i > activeStepIndex) { - return@forEachIndexed - } - val dot = view as SequenceStepDot - val dotTopMargin = (dot.layoutParams as LayoutParams).topMargin - - progressBarForegroundTopMargin - - (dot.measuredHeight / 2) - if (animatedOffset >= dotTopMargin) { - if (i < activeStepIndex && !dot.isEnabled) { - dot.isEnabled = true - } else if (i == activeStepIndex && !dot.isActivated) { - dot.isActivated = true + progressBarForeground + .animate() + .setStartDelay(resources.getInteger(R.integer.sequence_step_duration).toLong()) + .scaleY(scaleEnd) + .setInterpolator(LinearInterpolator()) + .setDuration(activeStepIndex * resources.getInteger(R.integer.sequence_step_duration).toLong()) + .setUpdateListener({ + val animatedOffset = progressBarForeground.scaleY * progressBarBackground.measuredHeight + dotsWrapper + .children() + .forEachIndexed { i, view -> + if (i > activeStepIndex) { + return@forEachIndexed + } + val dot = view as SequenceStepDot + val dotTopMargin = (dot.layoutParams as LayoutParams).topMargin - + progressBarForegroundTopMargin - + (dot.measuredHeight / 2) + if (animatedOffset >= dotTopMargin) { + if (i < activeStepIndex && !dot.isEnabled) { + dot.isEnabled = true + } else if (i == activeStepIndex && !dot.isActivated) { + dot.isActivated = true + } } } - } - }) - .start() + }) + .start() + } } private fun getRelativeTop(child: View, parent: ViewGroup): Int { @@ -224,6 +224,11 @@ public class SequenceLayout(context: Context?, attrs: AttributeSet?, defStyleAtt return offsetViewBounds.top } + private fun stop() { + removeCallbacks(animateToActive) + viewTreeObserver.removeOnGlobalLayoutListener(this) + } + override fun addView(child: View, index: Int, params: ViewGroup.LayoutParams) { if (child is SequenceStep) { if (child.isActive()) { @@ -244,10 +249,8 @@ public class SequenceLayout(context: Context?, attrs: AttributeSet?, defStyleAtt if (stepsWrapper.childCount > 0) { setProgressBarHorizontalOffset() placeDots() - post({ - animateToActive() - viewTreeObserver.removeOnGlobalLayoutListener(this) - }) + viewTreeObserver.removeOnGlobalLayoutListener(this) + post(animateToActive) } } } \ No newline at end of file