diff options
Diffstat (limited to 'core-ui/src/main/kotlin/ca/allanwang/kau/ui/widgets/ElasticDragDismissFrameLayout.kt')
-rw-r--r-- | core-ui/src/main/kotlin/ca/allanwang/kau/ui/widgets/ElasticDragDismissFrameLayout.kt | 115 |
1 files changed, 74 insertions, 41 deletions
diff --git a/core-ui/src/main/kotlin/ca/allanwang/kau/ui/widgets/ElasticDragDismissFrameLayout.kt b/core-ui/src/main/kotlin/ca/allanwang/kau/ui/widgets/ElasticDragDismissFrameLayout.kt index b89373e..f4578f2 100644 --- a/core-ui/src/main/kotlin/ca/allanwang/kau/ui/widgets/ElasticDragDismissFrameLayout.kt +++ b/core-ui/src/main/kotlin/ca/allanwang/kau/ui/widgets/ElasticDragDismissFrameLayout.kt @@ -1,11 +1,11 @@ /* - * Copyright 2015 Google Inc. + * Copyright 2018 Allan Wang * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -13,22 +13,28 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package ca.allanwang.kau.ui.widgets import android.app.Activity import android.content.Context import android.graphics.Color import android.os.Build -import androidx.annotation.RequiresApi import android.transition.TransitionInflater import android.util.AttributeSet import android.view.MotionEvent import android.view.View import android.widget.FrameLayout +import androidx.annotation.RequiresApi import ca.allanwang.kau.logging.KL import ca.allanwang.kau.ui.R -import ca.allanwang.kau.utils.* +import ca.allanwang.kau.utils.AnimHolder +import ca.allanwang.kau.utils.dimen +import ca.allanwang.kau.utils.dpToPx +import ca.allanwang.kau.utils.isNavBarOnBottom +import ca.allanwang.kau.utils.navigationBarColor +import ca.allanwang.kau.utils.scaleXY +import ca.allanwang.kau.utils.statusBarColor +import ca.allanwang.kau.utils.withAlpha /** * A [FrameLayout] which responds to nested scrolls to create drag-dismissable layouts. @@ -37,7 +43,10 @@ import ca.allanwang.kau.utils.* */ @RequiresApi(Build.VERSION_CODES.LOLLIPOP) class ElasticDragDismissFrameLayout @JvmOverloads constructor( - context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0, defStyleRes: Int = 0 + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0, + defStyleRes: Int = 0 ) : FrameLayout(context, attrs, defStyleAttr, defStyleRes) { // configurable attribs @@ -62,8 +71,11 @@ class ElasticDragDismissFrameLayout @JvmOverloads constructor( init { if (attrs != null) { val a = getContext().obtainStyledAttributes(attrs, R.styleable.ElasticDragDismissFrameLayout, 0, 0) - dragDismissDistance = a.getDimensionPixelSize(R.styleable.ElasticDragDismissFrameLayout_dragDismissDistance, Int.MAX_VALUE).toFloat() - dragDismissFraction = a.getFloat(R.styleable.ElasticDragDismissFrameLayout_dragDismissFraction, dragDismissFraction) + dragDismissDistance = + a.getDimensionPixelSize(R.styleable.ElasticDragDismissFrameLayout_dragDismissDistance, Int.MAX_VALUE) + .toFloat() + dragDismissFraction = + a.getFloat(R.styleable.ElasticDragDismissFrameLayout_dragDismissFraction, dragDismissFraction) dragDismissScale = a.getFloat(R.styleable.ElasticDragDismissFrameLayout_dragDismissScale, dragDismissScale) dragElacticity = a.getFloat(R.styleable.ElasticDragDismissFrameLayout_dragElasticity, dragElacticity) a.recycle() @@ -74,27 +86,27 @@ class ElasticDragDismissFrameLayout @JvmOverloads constructor( /** * Called for each drag event. - - * @param elasticOffset Indicating the drag offset with elasticity applied i.e. may - * * exceed 1. - * * + * @param elasticOffset Indicating the drag offset with elasticity applied i.e. may exceed 1. + * * @param elasticOffsetPixels The elastically scaled drag distance in pixels. - * * - * @param rawOffset Value from [0, 1] indicating the raw drag offset i.e. - * * without elasticity applied. A value of 1 indicates that the - * * dismiss distance has been reached. - * * - * @param rawOffsetPixels The raw distance the user has dragged + * + * @param rawOffset Value from [0, 1] indicating the raw drag offset i.e. without elasticity applied. + * A value of 1 indicates that the dismiss distance has been reached. + * + * @param rawOffsetPixels The raw distance the user has dragged */ - internal open fun onDrag(elasticOffset: Float, elasticOffsetPixels: Float, - rawOffset: Float, rawOffsetPixels: Float) { + internal open fun onDrag( + elasticOffset: Float, + elasticOffsetPixels: Float, + rawOffset: Float, + rawOffsetPixels: Float + ) { } /** * Called when dragging is released and has exceeded the threshold dismiss distance. */ internal open fun onDragDismissed() {} - } override fun onInterceptTouchEvent(ev: MotionEvent): Boolean { @@ -114,8 +126,13 @@ class ElasticDragDismissFrameLayout @JvmOverloads constructor( } } - override fun onNestedScroll(target: View, dxConsumed: Int, dyConsumed: Int, - dxUnconsumed: Int, dyUnconsumed: Int) { + override fun onNestedScroll( + target: View, + dxConsumed: Int, + dyConsumed: Int, + dxUnconsumed: Int, + dyUnconsumed: Int + ) { dragScale(dyUnconsumed) } @@ -129,12 +146,12 @@ class ElasticDragDismissFrameLayout @JvmOverloads constructor( scaleXY = 1f } else { animate() - .translationY(0f) - .scaleXY(1f) - .setDuration(200L) - .setInterpolator(AnimHolder.fastOutSlowInInterpolator(context)) - .setListener(null) - .start() + .translationY(0f) + .scaleXY(1f) + .setDuration(200L) + .setInterpolator(AnimHolder.fastOutSlowInInterpolator(context)) + .setListener(null) + .start() } totalDrag = 0f @@ -201,15 +218,23 @@ class ElasticDragDismissFrameLayout @JvmOverloads constructor( translationY = 0f scaleXY = 1f } - dispatchDragCallback(dragFraction, dragTo, - Math.min(1f, Math.abs(totalDrag) / dragDismissDistance), totalDrag) + dispatchDragCallback( + dragFraction, dragTo, + Math.min(1f, Math.abs(totalDrag) / dragDismissDistance), totalDrag + ) } - private fun dispatchDragCallback(elasticOffset: Float, elasticOffsetPixels: Float, - rawOffset: Float, rawOffsetPixels: Float) { + private fun dispatchDragCallback( + elasticOffset: Float, + elasticOffsetPixels: Float, + rawOffset: Float, + rawOffsetPixels: Float + ) { callbacks.forEach { - it.onDrag(elasticOffset, elasticOffsetPixels, - rawOffset, rawOffsetPixels) + it.onDrag( + elasticOffset, elasticOffsetPixels, + rawOffset, rawOffsetPixels + ) } } @@ -227,8 +252,12 @@ class ElasticDragDismissFrameLayout @JvmOverloads constructor( private val navBarAlpha: Int = Color.alpha(activity.navigationBarColor) private val fadeNavBar: Boolean = activity.isNavBarOnBottom - public override fun onDrag(elasticOffset: Float, elasticOffsetPixels: Float, - rawOffset: Float, rawOffsetPixels: Float) { + public override fun onDrag( + elasticOffset: Float, + elasticOffsetPixels: Float, + rawOffset: Float, + rawOffsetPixels: Float + ) { if (elasticOffsetPixels > 0) { // dragging downward, fade the status bar in proportion activity.statusBarColor = activity.statusBarColor.withAlpha(((1f - rawOffset) * statusBarAlpha).toInt()) @@ -238,7 +267,8 @@ class ElasticDragDismissFrameLayout @JvmOverloads constructor( activity.navigationBarColor = activity.navigationBarColor.withAlpha(navBarAlpha) } else if (fadeNavBar) { // dragging upward, fade the navigation bar in proportion - activity.navigationBarColor = activity.navigationBarColor.withAlpha(((1f - rawOffset) * navBarAlpha).toInt()) + activity.navigationBarColor = + activity.navigationBarColor.withAlpha(((1f - rawOffset) * navBarAlpha).toInt()) } } @@ -247,15 +277,18 @@ class ElasticDragDismissFrameLayout @JvmOverloads constructor( } } - fun addExitListener(activity: Activity, transitionBottom: Int = R.transition.kau_exit_slide_bottom, transitionTop: Int = R.transition.kau_exit_slide_top) { + fun addExitListener( + activity: Activity, + transitionBottom: Int = R.transition.kau_exit_slide_bottom, + transitionTop: Int = R.transition.kau_exit_slide_top + ) { addListener(object : ElasticDragDismissFrameLayout.SystemChromeFader(activity) { override fun onDragDismissed() { KL.v { "New transition" } activity.window.returnTransition = TransitionInflater.from(activity) - .inflateTransition(if (translationY > 0) transitionBottom else transitionTop) + .inflateTransition(if (translationY > 0) transitionBottom else transitionTop) activity.finishAfterTransition() } }) } - } |