From 61d87976e8b29ed25061ae98743a6cf4f4274542 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Sat, 22 Jul 2017 16:08:08 -0700 Subject: Support sdk 19 where possible and add image picker (#10) * Fix plural * Switch to long * Test plural again * Comment * Major update to image picker and view utils * Make image activity full screen * Update min sdk and prefix * Lower sdk requirement and make string private * Bring kpref activity to sdk 19 --- .../ca/allanwang/kau/swipe/SwipeBackLayout.kt | 3 + .../ca/allanwang/kau/ui/SimpleRippleDrawable.kt | 3 + .../kotlin/ca/allanwang/kau/utils/ActivityUtils.kt | 4 + .../kotlin/ca/allanwang/kau/utils/AnimHolder.kt | 3 + .../kotlin/ca/allanwang/kau/utils/AnimUtils.kt | 74 +++++------- .../main/kotlin/ca/allanwang/kau/utils/Const.kt | 5 +- .../kotlin/ca/allanwang/kau/utils/ContextUtils.kt | 12 +- .../kotlin/ca/allanwang/kau/utils/IIconUtils.kt | 3 +- .../kotlin/ca/allanwang/kau/utils/PackageUtils.kt | 8 +- .../ca/allanwang/kau/utils/TransitionUtils.kt | 43 ++++++- .../kotlin/ca/allanwang/kau/utils/ViewUtils.kt | 124 ++++++++++++++++----- 11 files changed, 197 insertions(+), 85 deletions(-) (limited to 'core/src/main/kotlin/ca/allanwang') diff --git a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackLayout.kt b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackLayout.kt index 7f4399d..1474c1a 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackLayout.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackLayout.kt @@ -1,5 +1,6 @@ package ca.allanwang.kau.swipe +import android.annotation.SuppressLint import android.app.Activity import android.content.Context import android.graphics.Canvas @@ -37,6 +38,7 @@ class SwipeBackLayout @JvmOverloads constructor(context: Context, attrs: Attribu } var activity: Activity? = null + @SuppressLint("NewApi") set(value) { field = value if (value != null) { @@ -81,6 +83,7 @@ class SwipeBackLayout @JvmOverloads constructor(context: Context, attrs: Attribu val chromeFadeListener: SwipeListener by lazy { object : SwipeListener { + @SuppressLint("NewApi") override fun onScroll(percent: Float, px: Int, edgeFlag: Int) { if (!transitionSystemBars) return activity?.apply { diff --git a/core/src/main/kotlin/ca/allanwang/kau/ui/SimpleRippleDrawable.kt b/core/src/main/kotlin/ca/allanwang/kau/ui/SimpleRippleDrawable.kt index 30c8edd..b92b222 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/ui/SimpleRippleDrawable.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/ui/SimpleRippleDrawable.kt @@ -3,7 +3,9 @@ package ca.allanwang.kau.ui import android.content.res.ColorStateList import android.graphics.drawable.ColorDrawable import android.graphics.drawable.RippleDrawable +import android.os.Build import android.support.annotation.ColorInt +import android.support.annotation.RequiresApi import ca.allanwang.kau.utils.adjustAlpha /** @@ -11,6 +13,7 @@ import ca.allanwang.kau.utils.adjustAlpha * * Tries to mimic a standard ripple, given the foreground and background colors */ +@RequiresApi(Build.VERSION_CODES.LOLLIPOP) fun createSimpleRippleDrawable(@ColorInt foregroundColor: Int, @ColorInt backgroundColor: Int): RippleDrawable { val states = ColorStateList(arrayOf(intArrayOf()), intArrayOf(foregroundColor)) val content = ColorDrawable(backgroundColor) diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/ActivityUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/ActivityUtils.kt index cd6e089..54aeaff 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/utils/ActivityUtils.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/utils/ActivityUtils.kt @@ -39,13 +39,17 @@ fun Activity.finishSlideOut() { } inline var Activity.navigationBarColor: Int + @SuppressLint("NewApi") get() = if (buildIsLollipopAndUp) window.navigationBarColor else Color.BLACK + @SuppressLint("NewApi") set(value) { if (buildIsLollipopAndUp) window.navigationBarColor = value } inline var Activity.statusBarColor: Int + @SuppressLint("NewApi") get() = if (buildIsLollipopAndUp) window.statusBarColor else Color.BLACK + @SuppressLint("NewApi") set(value) { if (buildIsLollipopAndUp) window.statusBarColor = value } diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/AnimHolder.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/AnimHolder.kt index 3db8b9c..2767f04 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/utils/AnimHolder.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/utils/AnimHolder.kt @@ -1,5 +1,7 @@ package ca.allanwang.kau.utils +import android.os.Build +import android.support.annotation.RequiresApi import ca.allanwang.kau.kotlin.lazyInterpolator /** @@ -9,6 +11,7 @@ import ca.allanwang.kau.kotlin.lazyInterpolator */ object AnimHolder { + @RequiresApi(Build.VERSION_CODES.LOLLIPOP) val fastOutSlowInInterpolator = lazyInterpolator(android.R.interpolator.fast_out_linear_in) val decelerateInterpolator = lazyInterpolator(android.R.interpolator.decelerate_cubic) diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/AnimUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/AnimUtils.kt index bbde077..ed4b7bd 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/utils/AnimUtils.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/utils/AnimUtils.kt @@ -2,12 +2,12 @@ package ca.allanwang.kau.utils import android.animation.Animator import android.animation.AnimatorListenerAdapter +import android.annotation.SuppressLint import android.support.annotation.StringRes import android.view.View import android.view.ViewAnimationUtils import android.view.animation.Animation import android.view.animation.AnimationUtils -import android.view.animation.DecelerateInterpolator import android.widget.TextView /** @@ -15,33 +15,8 @@ import android.widget.TextView * * Animation extension functions for Views */ -@KauUtils fun View.rootCircularReveal(x: Int = 0, y: Int = 0, duration: Long = 500L, onStart: (() -> Unit)? = null, onFinish: (() -> Unit)? = null) { - this.addOnLayoutChangeListener(object : View.OnLayoutChangeListener { - override @KauUtils 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 @KauUtils fun onAnimationStart(animation: Animator?) { - visible() - onStart?.invoke() - } - - override @KauUtils fun onAnimationEnd(animation: Animator?) = onFinish?.invoke() ?: Unit - override @KauUtils fun onAnimationCancel(animation: Animator?) = onFinish?.invoke() ?: Unit - }) - reveal.start() - } - }) -} +@SuppressLint("NewApi") @KauUtils 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) { onStart?.invoke() @@ -49,10 +24,11 @@ import android.widget.TextView onFinish?.invoke() 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() - } + if (!buildIsLollipopAndUp) return fadeIn(offset, duration, onStart, onFinish) + + val r = if (radius >= 0) radius + else 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() { @@ -67,6 +43,7 @@ import android.widget.TextView anim.start() } +@SuppressLint("NewApi") @KauUtils fun View.circularHide(x: Int = 0, y: Int = 0, offset: Long = 0L, radius: Float = -1.0f, duration: Long = 500L, onStart: (() -> Unit)? = null, onFinish: (() -> Unit)? = null) { if (!isAttachedToWindow) { onStart?.invoke() @@ -74,10 +51,11 @@ import android.widget.TextView onFinish?.invoke() 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() - } + if (!buildIsLollipopAndUp) return fadeOut(offset, duration, onStart, onFinish) + + val r = if (radius >= 0) radius + else Math.max(Math.hypot(x.toDouble(), y.toDouble()), Math.hypot((width - x.toDouble()), (height - y.toDouble()))).toFloat() + val anim = ViewAnimationUtils.createCircularReveal(this, x, y, r, 0f).setDuration(duration) anim.startDelay = offset anim.addListener(object : AnimatorListenerAdapter() { @@ -100,20 +78,18 @@ import android.widget.TextView onFinish?.invoke() 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 @KauUtils fun onAnimationRepeat(animation: Animation?) {} - override @KauUtils fun onAnimationEnd(animation: Animation?) = onFinish?.invoke() ?: Unit - override @KauUtils fun onAnimationStart(animation: Animation?) { - visible() - onStart?.invoke() - } - }) - startAnimation(anim) - } + val anim = AnimationUtils.loadAnimation(context, android.R.anim.fade_in) + anim.startOffset = offset + anim.duration = duration + anim.setAnimationListener(object : Animation.AnimationListener { + override @KauUtils fun onAnimationRepeat(animation: Animation?) {} + override @KauUtils fun onAnimationEnd(animation: Animation?) = onFinish?.invoke() ?: Unit + override @KauUtils fun onAnimationStart(animation: Animation?) { + visible() + onStart?.invoke() + } + }) + startAnimation(anim) } @KauUtils fun View.fadeOut(offset: Long = 0L, duration: Long = 200L, onStart: (() -> Unit)? = null, onFinish: (() -> Unit)? = null) { diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/Const.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/Const.kt index 9fcc7e7..f267a60 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/utils/Const.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/utils/Const.kt @@ -8,4 +8,7 @@ const val ANDROID_NAMESPACE = "http://schemas.android.com/apk/res/android" const val KAU_LEFT = 1 const val KAU_TOP = 2 const val KAU_RIGHT = 4 -const val KAU_BOTTOM = 8 \ No newline at end of file +const val KAU_BOTTOM = 8 +const val KAU_HORIZONTAL = KAU_LEFT and KAU_RIGHT +const val KAU_VERTICAL = KAU_TOP and KAU_BOTTOM +const val KAU_ALL = KAU_HORIZONTAL and KAU_VERTICAL \ No newline at end of file diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt index a8e0715..bf30a91 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt @@ -1,5 +1,6 @@ package ca.allanwang.kau.utils +import android.annotation.SuppressLint import android.app.Activity import android.app.ActivityOptions import android.content.ClipData @@ -25,6 +26,7 @@ import com.afollestad.materialdialogs.MaterialDialog /** * Created by Allan Wang on 2017-06-03. */ +@SuppressLint("NewApi") fun Context.startActivity( clazz: Class, clearStack: Boolean = false, @@ -34,7 +36,9 @@ fun Context.startActivity( val intent = (Intent(this, clazz)) if (clearStack) intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) intent.intentBuilder() - val fullBundle = if (transition && this is Activity) ActivityOptions.makeSceneTransitionAnimation(this).toBundle() else Bundle() + val fullBundle = if (transition && this is Activity && buildIsLollipopAndUp) + ActivityOptions.makeSceneTransitionAnimation(this).toBundle() + else Bundle() if (transition && this !is Activity) KL.d("Cannot make scene transition when context is not an instance of an Activity") if (bundle != null) fullBundle.putAll(bundle) ContextCompat.startActivity(this, intent, if (fullBundle.isEmpty) null else fullBundle) @@ -97,7 +101,11 @@ inline fun Context.drawable(@DrawableRes id: Int): Drawable = ContextCompat.getD inline fun Context.drawable(@DrawableRes id: Int, fallback: Drawable?): Drawable? = if (id > 0) drawable(id) else fallback inline fun Context.interpolator(@InterpolatorRes id: Int) = AnimationUtils.loadInterpolator(this, id) inline fun Context.animation(@AnimRes id: Int) = AnimationUtils.loadAnimation(this, id) -inline fun Context.plural(@PluralsRes id: Int, quantity: Number) = resources.getQuantityString(id, quantity.toInt()) +/** + * Returns plural form of res. The quantity is also passed to the formatter as an int + */ +inline fun Context.plural(@PluralsRes id: Int, quantity: Number) + = resources.getQuantityString(id, quantity.toInt(), quantity.toInt()) //Attr retrievers fun Context.resolveColor(@AttrRes attr: Int, fallback: Int = 0): Int { diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/IIconUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/IIconUtils.kt index 03a1605..4c71945 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/utils/IIconUtils.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/utils/IIconUtils.kt @@ -13,8 +13,7 @@ import com.mikepenz.iconics.typeface.IIcon */ @KauUtils fun IIcon.toDrawable(c: Context, sizeDp: Int = 24, @ColorInt color: Int = Color.WHITE, builder: IconicsDrawable.() -> Unit = {}): Drawable { val state = ColorStateList.valueOf(color) - val icon = IconicsDrawable(c).icon(this).sizeDp(sizeDp) - icon.setTintList(state) + val icon = IconicsDrawable(c).icon(this).sizeDp(sizeDp).color(state) icon.builder() return icon } \ No newline at end of file diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/PackageUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/PackageUtils.kt index 89d64e5..36bcc93 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/utils/PackageUtils.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/utils/PackageUtils.kt @@ -30,12 +30,14 @@ import android.os.Build } } -inline val buildIsLollipopAndUp: Boolean - get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP - inline val buildIsMarshmallowAndUp: Boolean + get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M +inline val buildIsLollipopAndUp: Boolean + @SuppressWarnings("NewApi") + get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP + inline val buildIsNougatAndUp: Boolean get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/TransitionUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/TransitionUtils.kt index 9e668d0..fa062f7 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/utils/TransitionUtils.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/utils/TransitionUtils.kt @@ -1,11 +1,19 @@ package ca.allanwang.kau.utils -import android.support.transition.Transition -import android.support.transition.TransitionSet +import android.os.Build +import android.support.annotation.RequiresApi +import android.support.annotation.TransitionRes +import android.support.transition.AutoTransition +import android.support.transition.TransitionInflater +import android.support.transition.TransitionManager +import android.support.transition.Transition as SupportTransition +import android.transition.Transition +import android.view.ViewGroup /** * Created by Allan Wang on 2017-06-24. */ +@RequiresApi(Build.VERSION_CODES.LOLLIPOP) class TransitionEndListener(val onEnd: (transition: Transition) -> Unit) : Transition.TransitionListener { override fun onTransitionEnd(transition: Transition) = onEnd(transition) override fun onTransitionResume(transition: Transition) {} @@ -14,6 +22,35 @@ class TransitionEndListener(val onEnd: (transition: Transition) -> Unit) : Trans override fun onTransitionStart(transition: Transition) {} } -@KauUtils fun TransitionSet.addEndListener(onEnd: (transition: Transition) -> Unit) { +@RequiresApi(Build.VERSION_CODES.LOLLIPOP) +@KauUtils fun Transition.addEndListener(onEnd: (transition: Transition) -> Unit) { addListener(TransitionEndListener(onEnd)) +} + +@RequiresApi(Build.VERSION_CODES.LOLLIPOP) +class SupportTransitionEndListener(val onEnd: (transition: SupportTransition) -> Unit) : SupportTransition.TransitionListener { + override fun onTransitionEnd(transition: SupportTransition) = onEnd(transition) + override fun onTransitionResume(transition: SupportTransition) {} + override fun onTransitionPause(transition: SupportTransition) {} + override fun onTransitionCancel(transition: SupportTransition) {} + override fun onTransitionStart(transition: SupportTransition) {} +} + +@RequiresApi(Build.VERSION_CODES.LOLLIPOP) +@KauUtils fun SupportTransition.addEndListener(onEnd: (transition: SupportTransition) -> Unit) { + addListener(SupportTransitionEndListener(onEnd)) +} + +@KauUtils fun ViewGroup.transitionAuto(builder: AutoTransition.() -> Unit = {}) { + if (!buildIsLollipopAndUp) return + val transition = AutoTransition() + transition.builder() + TransitionManager.beginDelayedTransition(this, transition) +} + +@KauUtils fun ViewGroup.transitionDelayed(@TransitionRes id: Int, builder: android.support.transition.Transition.() -> Unit = {}) { + if (!buildIsLollipopAndUp) return + val transition = TransitionInflater.from(context).inflateTransition(id) + transition.builder() + TransitionManager.beginDelayedTransition(this, transition) } \ No newline at end of file diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/ViewUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/ViewUtils.kt index 59ae204..ead2cb7 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/utils/ViewUtils.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/utils/ViewUtils.kt @@ -5,10 +5,8 @@ package ca.allanwang.kau.utils import android.animation.ValueAnimator import android.content.Context import android.graphics.Color -import android.support.annotation.ColorInt -import android.support.annotation.ColorRes -import android.support.annotation.StringRes -import android.support.annotation.TransitionRes +import android.os.Build +import android.support.annotation.* import android.support.design.widget.FloatingActionButton import android.support.design.widget.Snackbar import android.support.design.widget.TextInputEditText @@ -93,30 +91,98 @@ fun FloatingActionButton.hideIf(hide: Boolean) = if (hide) hide() else show() /** * Set left margin to a value in px */ -@KauUtils fun View.updateLeftMargin(margin: Int) = updateMargins(margin, KAU_LEFT) +@KauUtils fun View.setMarginLeft(margin: Int) = setMargins(margin, KAU_LEFT) /** * Set top margin to a value in px */ -@KauUtils fun View.updateTopMargin(margin: Int) = updateMargins(margin, KAU_TOP) +@KauUtils fun View.setMarginTop(margin: Int) = setMargins(margin, KAU_TOP) /** * Set right margin to a value in px */ -@KauUtils fun View.updateRightMargin(margin: Int) = updateMargins(margin, KAU_RIGHT) +@KauUtils fun View.setMarginRight(margin: Int) = setMargins(margin, KAU_RIGHT) /** * Set bottom margin to a value in px */ -@KauUtils fun View.updateBottomMargin(margin: Int) = updateMargins(margin, KAU_BOTTOM) +@KauUtils fun View.setMarginBottom(margin: Int) = setMargins(margin, KAU_BOTTOM) -@KauUtils private fun View.updateMargins(margin: Int, flag: Int) { - val p = (layoutParams as? ViewGroup.MarginLayoutParams) ?: return +/** + * Set left and right margins to a value in px + */ +@KauUtils fun View.setMarginHorizontal(margin: Int) = setMargins(margin, KAU_HORIZONTAL) + +/** + * Set top and bottom margins to a value in px + */ +@KauUtils fun View.setMarginVertical(margin: Int) = setMargins(margin, KAU_VERTICAL) + +/** + * Set all margins to a value in px + */ +@KauUtils fun View.setMargin(margin: Int) = setMargins(margin, KAU_ALL) + +/** + * Base margin setter + * returns true if setting is successful, false otherwise + */ +@KauUtils private fun View.setMargins(margin: Int, flag: Int): Boolean { + val p = (layoutParams as? ViewGroup.MarginLayoutParams) ?: return false p.setMargins( - if (flag == KAU_LEFT) margin else p.leftMargin, - if (flag == KAU_TOP) margin else p.topMargin, - if (flag == KAU_RIGHT) margin else p.rightMargin, - if (flag == KAU_BOTTOM) margin else p.bottomMargin + if (flag and KAU_LEFT > 0) margin else p.leftMargin, + if (flag and KAU_TOP > 0) margin else p.topMargin, + if (flag and KAU_RIGHT > 0) margin else p.rightMargin, + if (flag and KAU_BOTTOM > 0) margin else p.bottomMargin + ) + requestLayout() + return true +} + +/** + * Set left padding to a value in px + */ +@KauUtils fun View.setPaddingLeft(padding: Int) = setPadding(padding, KAU_LEFT) + +/** + * Set top padding to a value in px + */ +@KauUtils fun View.setPaddingTop(padding: Int) = setPadding(padding, KAU_TOP) + +/** + * Set right padding to a value in px + */ +@KauUtils fun View.setPaddingRight(padding: Int) = setPadding(padding, KAU_RIGHT) + +/** + * Set bottom padding to a value in px + */ +@KauUtils fun View.setPaddingBottom(padding: Int) = setPadding(padding, KAU_BOTTOM) + +/** + * Set left and right padding to a value in px + */ +@KauUtils fun View.setPaddingHorizontal(padding: Int) = setPadding(padding, KAU_HORIZONTAL) + +/** + * Set top and bottom padding to a value in px + */ +@KauUtils fun View.setPaddingVertical(padding: Int) = setPadding(padding, KAU_VERTICAL) + +/** + * Set all padding to a value in px + */ +@KauUtils fun View.setPadding(padding: Int) = setPadding(padding, KAU_ALL) + +/** + * Base padding setter + */ +@KauUtils private fun View.setPadding(padding: Int, flag: Int) { + setPadding( + if (flag and KAU_LEFT > 0) padding else paddingLeft, + if (flag and KAU_TOP > 0) padding else paddingTop, + if (flag and KAU_RIGHT > 0) padding else paddingRight, + if (flag and KAU_BOTTOM > 0) padding else paddingBottom ) requestLayout() } @@ -131,18 +197,8 @@ fun FloatingActionButton.hideIf(hide: Boolean) = if (hide) hide() else show() (context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager).showSoftInput(this, InputMethodManager.SHOW_IMPLICIT) } -@KauUtils fun ViewGroup.transitionAuto(builder: AutoTransition.() -> Unit = {}) { - val transition = AutoTransition() - transition.builder() - TransitionManager.beginDelayedTransition(this, transition) -} - -@KauUtils fun ViewGroup.transitionDelayed(@TransitionRes id: Int, builder: Transition.() -> Unit = {}) { - val transition = TransitionInflater.from(context).inflateTransition(id) - transition.builder() - TransitionManager.beginDelayedTransition(this, transition) -} +@RequiresApi(Build.VERSION_CODES.LOLLIPOP) @KauUtils fun View.setRippleBackground(@ColorInt foregroundColor: Int, @ColorInt backgroundColor: Int) { background = createSimpleRippleDrawable(foregroundColor, backgroundColor) } @@ -192,4 +248,22 @@ inline fun FloatingActionButton.transition(crossinline action: FloatingActionBut start() } } +} + +/** + * Attaches a listener to the recyclerview to hide the fab when it is scrolling downwards + * The fab will reappear when scrolling has stopped or if the user scrolls up + */ +fun FloatingActionButton.hideOnDownwardsScroll(recycler: RecyclerView) { + recycler.addOnScrollListener(object : RecyclerView.OnScrollListener() { + + override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { + if (newState == android.support.v7.widget.RecyclerView.SCROLL_STATE_IDLE && !isShown) show(); + } + + override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { + if (dy > 0 && isShown) hide() + else if (dy < 0 && isHidden) show() + } + }) } \ No newline at end of file -- cgit v1.2.3