From 266569a14f3b1dea9002de58cef40b4149384ef6 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Thu, 1 Jun 2017 17:45:42 -0700 Subject: add progressbar and remove tab indicator --- .../com/pitchedapps/frost/views/AnimUtils.kt | 107 +++++++++++++++++++++ .../com/pitchedapps/frost/views/ViewUtils.kt | 18 +++- 2 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 app/src/main/kotlin/com/pitchedapps/frost/views/AnimUtils.kt (limited to 'app/src/main/kotlin/com/pitchedapps/frost/views') diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/AnimUtils.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/AnimUtils.kt new file mode 100644 index 00000000..a2a0dcff --- /dev/null +++ b/app/src/main/kotlin/com/pitchedapps/frost/views/AnimUtils.kt @@ -0,0 +1,107 @@ +package com.pitchedapps.frost.views + +import android.animation.Animator +import android.animation.AnimatorListenerAdapter +import android.view.View +import android.view.ViewAnimationUtils +import android.view.animation.Animation +import android.view.animation.AnimationUtils +import android.view.animation.DecelerateInterpolator + + +/** + * Created by Allan Wang on 2017-06-01. + */ + +fun View.rootCircularReveal(x: Int = 0, y: Int = 0, duration: Long = 500L, onStart: (() -> Unit)? = null, onFinish: (() -> Unit)? = null) { + this.addOnLayoutChangeListener(object : View.OnLayoutChangeListener { + override fun onLayoutChange(v: View, left: Int, top: Int, right: Int, bottom: Int, oldLeft: Int, oldTop: Int, + oldRight: Int, oldBottom: Int) { + v.removeOnLayoutChangeListener(this) + var x2 = x + var y2 = y + if (x2 > right) x2 = 0 + if (y2 > bottom) y2 = 0 + val radius = Math.hypot(Math.max(x2, right - x2).toDouble(), Math.max(y2, bottom - y2).toDouble()).toInt() + val reveal = ViewAnimationUtils.createCircularReveal(v, x2, y2, 0f, radius.toFloat()) + reveal.interpolator = DecelerateInterpolator(1f) + reveal.duration = duration + reveal.addListener(object : AnimatorListenerAdapter() { + override fun onAnimationStart(animation: Animator?) { + visibility = View.VISIBLE + onStart?.invoke() + } + + override fun onAnimationEnd(animation: Animator?) = onFinish?.invoke() ?: Unit + override fun onAnimationCancel(animation: Animator?) = onFinish?.invoke() ?: Unit + }) + reveal.start() + } + }) +} + +fun View.circularReveal(x: Int = 0, y: Int = 0, offset: Long = 0L, radius: Float = -1.0f, duration: Long = 500L, onStart: (() -> Unit)? = null, onFinish: (() -> Unit)? = null) { + if (!isAttachedToWindow) { + visibility = View.VISIBLE + return + } + var r = radius + if (r < 0.0f) { + r = Math.max(Math.hypot(x.toDouble(), y.toDouble()), Math.hypot((width - x.toDouble()), (height - y.toDouble()))).toFloat() + } + val anim = ViewAnimationUtils.createCircularReveal(this, x, y, 0f, r).setDuration(duration) + anim.startDelay = offset + anim.addListener(object : AnimatorListenerAdapter() { + override fun onAnimationStart(animation: Animator?) { + visibility = View.VISIBLE + onStart?.invoke() + } + + override fun onAnimationEnd(animation: Animator?) = onFinish?.invoke() ?: Unit + override fun onAnimationCancel(animation: Animator?) = onFinish?.invoke() ?: Unit + }) + anim.start() +} + +fun View.fadeIn(offset: Long = 0L, duration: Long = 200L, onStart: (() -> Unit)? = null, onFinish: (() -> Unit)? = null) { + if (!isAttachedToWindow) { + visibility = View.VISIBLE + return + } + if (isAttachedToWindow) { + val anim = AnimationUtils.loadAnimation(context, android.R.anim.fade_in) + anim.startOffset = offset + anim.duration = duration + anim.setAnimationListener(object : Animation.AnimationListener { + override fun onAnimationRepeat(animation: Animation?) {} + override fun onAnimationEnd(animation: Animation?) = onFinish?.invoke() ?: Unit + override fun onAnimationStart(animation: Animation?) { + visibility = View.VISIBLE + onStart?.invoke() + } + }) + startAnimation(anim) + } +} + +fun View.fadeOut(offset: Long = 0L, duration: Long = 200L, onStart: (() -> Unit)? = null, onFinish: (() -> Unit)? = null) { + if (!isAttachedToWindow) { + visibility = View.INVISIBLE + return + } + val anim = AnimationUtils.loadAnimation(context, android.R.anim.fade_out) + anim.startOffset = offset + anim.duration = duration + anim.setAnimationListener(object : Animation.AnimationListener { + override fun onAnimationRepeat(animation: Animation?) {} + override fun onAnimationEnd(animation: Animation?) { + visibility = View.INVISIBLE + onFinish?.invoke() + } + + override fun onAnimationStart(animation: Animation?) { + onStart?.invoke() + } + }) + startAnimation(anim) +} \ No newline at end of file diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/ViewUtils.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/ViewUtils.kt index 513287ef..01a49f7e 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/views/ViewUtils.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/views/ViewUtils.kt @@ -1,14 +1,30 @@ package com.pitchedapps.frost.views +import android.content.res.ColorStateList +import android.graphics.PorterDuff +import android.support.annotation.ColorInt +import android.support.annotation.ColorRes +import android.support.v4.content.ContextCompat import android.view.View import android.view.ViewGroup +import android.widget.ProgressBar + /** * Created by Allan Wang on 2017-05-31. */ fun View.matchParent() { - with (layoutParams) { + with(layoutParams) { height = ViewGroup.LayoutParams.MATCH_PARENT width = ViewGroup.LayoutParams.MATCH_PARENT } +} + +fun ProgressBar.tintRes(@ColorRes id: Int) = tint(ContextCompat.getColor(context, id)) + +fun ProgressBar.tint(@ColorInt color: Int) { + val sl = ColorStateList.valueOf(color) + progressTintList = sl + secondaryProgressTintList = sl + indeterminateTintList = sl } \ No newline at end of file -- cgit v1.2.3