Skip to content

Instantly share code, notes, and snippets.

@karishmaagr
Created March 12, 2021 12:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save karishmaagr/3951280e309f1b06595ab1c09fee97e8 to your computer and use it in GitHub Desktop.
Save karishmaagr/3951280e309f1b06595ab1c09fee97e8 to your computer and use it in GitHub Desktop.
package com.example.sampleonboardinganimation
import android.animation.*
import android.content.Context
import android.os.Bundle
import android.util.TypedValue
import android.view.Gravity
import android.view.View
import android.view.animation.AccelerateDecelerateInterpolator
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.core.content.ContextCompat
import androidx.transition.*
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.layout_loading_progress_with_icon_and_text.view.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val lp1 = tv_ob_title.layoutParams as ConstraintLayout.LayoutParams
val statusBarHeight = getStatusBarHeight(this)
lp1.topMargin += statusBarHeight
tv_ob_title.layoutParams = lp1
fl_progress_1.tv_ob_loading.text = 1.toString()
fl_progress_2.tv_ob_loading.text = 2.toString()
fl_progress_3.tv_ob_loading.text = 3.toString()
setupUi(DataUtils(this).getData())
}
private fun setupUi(data: OnboardingUiDataModel?, animate: Boolean = true) {
val uiModel = data ?: kotlin.run {
return
}
tv_ob_title.text = "Setting up HealthifyMe for Karishma"
fl_progress_1.visibility = View.VISIBLE
fl_progress_2.visibility = View.VISIBLE
fl_progress_3.visibility = View.VISIBLE
val lastAction: (() -> Unit) = {
hideText(tv_ob_title, animate)
hideText(tv_progress_1_2, animate)
hideText(tv_progress_2_2, animate)
hideText(tv_progress_3_2, animate) {
// Animation to translate view to top
val constraintSet = ConstraintSet()
constraintSet.clone(
this,
R.layout.activity_onboarding_loading_animate_3
)
val transition = AutoTransition()
transition.duration = if (animate) 700 else 0
transition.interpolator = interpolator
transition.addListener(object : TransitionListenerAdapter() {
override fun onTransitionStart(transition: Transition) {
super.onTransitionStart(transition)
showTextPostAnimation(uiModel, animate)
}
override fun onTransitionEnd(transition: Transition) {
}
override fun onTransitionCancel(transition: Transition) {
super.onTransitionCancel(transition)
}
})
TransitionManager.go(Scene(cl_ob_loading), transition)
constraintSet.applyTo(cl_ob_loading)
}
}
val thirdIconAction = {
setupLoadingStart(
fl_progress_3,
uiModel.icons?.getOrNull(2),
tv_progress_3_1,
tv_progress_3_2,
animate,
lastAction
)
}
val iconsList = uiModel.icons?.getOrNull(0)
setupLoadingStart(fl_progress_1, iconsList, tv_progress_1_1, tv_progress_1_2, animate) {
setupLoadingStart(
fl_progress_2,
uiModel.icons?.getOrNull(1),
tv_progress_2_1,
tv_progress_2_2,
animate,
thirdIconAction
)
}
}
private val interpolator = AccelerateDecelerateInterpolator()
private val progressDrawable by lazy {
ContextCompat.getDrawable(this, R.drawable.bg_progress_indeterminate)
}
private val progressFinalDrawable by lazy {
ContextCompat.getDrawable(this, R.drawable.bg_progress_final)
}
private fun hideText(
textView: TextView,
animate: Boolean = true,
combine: (() -> Unit)? = null
) {
if (!animate) {
textView.animate().alpha(0f).setDuration(0).start()
textView.gone()
combine?.invoke()
return
}
textView.animate().alpha(0f).setDuration(500)
.setInterpolator(interpolator)
.setListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator?) {
super.onAnimationEnd(animation)
hideTextAnimationEnd()
}
override fun onAnimationCancel(animation: Animator?) {
super.onAnimationCancel(animation)
hideTextAnimationEnd()
}
private fun hideTextAnimationEnd() {
try {
textView.animate().setListener(null)
textView.gone()
combine?.invoke()
} catch (e: Exception) {
}
}
}).start()
}
fun View?.gone() {
if (this == null) return
visibility = View.GONE
}
private fun setupLoadingStart(
view: View,
icon: Icon?,
text1: TextView,
text2: TextView,
animate: Boolean = true,
combine: (() -> Unit)? = null
) {
try {
view.visibility = View.VISIBLE
view.tv_ob_loading.text = ""
view.iv_ob_loading.visibility = View.VISIBLE
view.iv_ob_loading.animate().alpha(1f).setDuration(if (animate) 1000 else 0)
.setInterpolator(interpolator).start()
val iconRes = icon?.iconRes ?: 0
if (iconRes != 0)
view.iv_ob_loading.setImageResource(iconRes)
else
BaseImageLoader.loadImage(this, icon?.icon, view.iv_ob_loading)
val pbObLoading = view.pb_ob_loading
val bounds = pbObLoading.indeterminateDrawable.copyBounds()
progressDrawable?.bounds = bounds
progressFinalDrawable?.bounds = bounds
pbObLoading.indeterminateDrawable = progressDrawable
text1.visibility = View.VISIBLE
text1.text = icon?.loadingText
text1.animate().alpha(1f).setDuration(if (animate) 1100 else 0)
.setInterpolator(interpolator).start()
text2.visibility = View.VISIBLE
text2.text = icon?.finalText
text2.animate().alpha(1f).setDuration(if (animate) 1100 else 0)
.setInterpolator(interpolator).start()
text1.post {
try {
val textAlpha = ObjectAnimator.ofFloat(text1, TextView.ALPHA, 1f, 0f)
textAlpha.duration = if (animate) 600 else 0
val textScale = ValueAnimator.ofFloat(1f, 0f)
val width = text1.width
var doOnce = true
textScale.addUpdateListener {
try {
val animatedFraction = it.animatedValue as Float
val layoutParams = text1.layoutParams
layoutParams.width = (animatedFraction * width).toInt()
text1.layoutParams = layoutParams
if (animatedFraction <= 0.03 && doOnce) {
val lp = text2.layoutParams as ConstraintLayout.LayoutParams
lp.startToEnd = view.id
text2.layoutParams = lp
doOnce = false
}
} catch (e: Exception) {
}
}
textScale.duration = if (animate) 600 else 0
textScale.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator?) {
super.onAnimationEnd(animation)
textScaleAnimationEnd()
}
override fun onAnimationCancel(animation: Animator?) {
super.onAnimationCancel(animation)
textScaleAnimationEnd()
}
private fun textScaleAnimationEnd() {
try {
text1.visibility = View.GONE
pbObLoading.indeterminateDrawable = progressFinalDrawable
view.postDelayed({
try {
combine?.invoke()
} catch (e: Exception) {
}
}, if (animate) 600 else 0)
} catch (e: Exception) {
}
}
})
val animator = AnimatorSet()
animator.startDelay = if (animate) 1500 else 0
animator.interpolator = interpolator
animator.playSequentially(textAlpha, textScale)
animator.start()
} catch (e: Exception) {
}
}
} catch (e: Exception) {
//handle exception
}
}
private fun showTextPostAnimation(uiModel: OnboardingUiDataModel, animate: Boolean) {
try {
tv_progress_1_2.text = uiModel.icons?.getOrNull(0)?.finalText
tv_progress_2_2.text = uiModel.icons?.getOrNull(1)?.finalText
tv_progress_3_2.text = uiModel.icons?.getOrNull(2)?.finalText
tv_progress_1_2.visible()
tv_progress_1_2.gravity = Gravity.CENTER
tv_progress_1_2.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12f)
tv_progress_2_2.visible()
tv_progress_2_2.gravity = Gravity.CENTER
tv_progress_2_2.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12f)
tv_progress_3_2.visible()
tv_progress_3_2.gravity = Gravity.CENTER
tv_progress_3_2.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12f)
if (!animate) {
tv_progress_1_2.alpha = 1f
tv_progress_2_2.alpha = 1f
tv_progress_3_2.alpha = 1f
return
}
val alpha = ValueAnimator.ofFloat(0f, 1f)
alpha.setDuration(300).interpolator = interpolator
alpha.addUpdateListener {
try {
val fraction = it.animatedFraction
tv_progress_1_2.alpha = fraction
tv_progress_2_2.alpha = fraction
tv_progress_3_2.alpha = fraction
} catch (e: Exception) {
}
}
alpha.start()
} catch (e: Exception) {
}
}
fun View?.visible() {
if (this == null) return
visibility = View.VISIBLE
}
fun getStatusBarHeight(context: Context): Int {
val resources = context.resources
var result = 0
val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")
if (resourceId > 0) {
result = resources.getDimensionPixelSize(resourceId)
}
return result
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment