diff options
author | Allan Wang <me@allanwang.ca> | 2017-08-05 14:49:47 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-05 14:49:47 -0700 |
commit | c707d42b311f96cbabc1971f98598c8b8922ba16 (patch) | |
tree | 3c592c2a8bdd2fb759e3632adf038b5d7cecfabb /core/src/main/kotlin/ca/allanwang/kau/swipe | |
parent | bafc1996d803862d30a2c7d0c402d30c79c4f647 (diff) | |
download | kau-c707d42b311f96cbabc1971f98598c8b8922ba16.tar.gz kau-c707d42b311f96cbabc1971f98598c8b8922ba16.tar.bz2 kau-c707d42b311f96cbabc1971f98598c8b8922ba16.zip |
Swipe (#24)
* Test emulator
* Update readme
* Update fastadapter and about listing
* Make faq parser asynchronous
* Modularize about panels
* Add basis for faq
* Test and finalize the faq panel
* Update readme
* Update changelog
* Remove emulator for now
* Update sample
* Change back to manual versioning to avoid suggestion errors
* Add awesome-kt banner
* Fix faq background color
* Fix merge conflicts 2
* Add waffle badge
* Update readme
* Fix lint
* Create FileUtils and NotificationUtils
* Remove frost hardcode
* Fix simple date
* Update swipe to use weak references
* Initializing test dependencies
* Update to gradle 4.1
* Fix lint warnings
* Drop back down and fix errors
* Finalize swipe with example
* Finalize weak reference and ordering
* Update test code
* Make loggers inline
Diffstat (limited to 'core/src/main/kotlin/ca/allanwang/kau/swipe')
5 files changed, 68 insertions, 46 deletions
diff --git a/core/src/main/kotlin/ca/allanwang/kau/swipe/RelativeSlider.kt b/core/src/main/kotlin/ca/allanwang/kau/swipe/RelativeSlider.kt index 2ffb2ef..f14f5cf 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/swipe/RelativeSlider.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/swipe/RelativeSlider.kt @@ -1,7 +1,5 @@ package ca.allanwang.kau.swipe -import ca.allanwang.kau.kotlin.nonReadable - /** * Created by Mr.Jude on 2015/8/26. * @@ -9,13 +7,12 @@ import ca.allanwang.kau.kotlin.nonReadable * * Helper class to give the previous activity an offset as the main page is pulled */ -class RelativeSlider(var curPage: SwipeBackPage) : SwipeListener { +internal class RelativeSlider(var curPage: SwipeBackPage) : SwipeListener { var offset = 0f var enabled: Boolean - @Deprecated(level = DeprecationLevel.ERROR, message = "Cannot use enabled as getter") - get() = nonReadable() + get() = curPage.hasListener(this) set(value) { if (value) curPage.addListener(this) else curPage.removeListener(this) diff --git a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackHelper.kt b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackHelper.kt index 503f1fc..0859ac5 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackHelper.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackHelper.kt @@ -2,27 +2,27 @@ package ca.allanwang.kau.swipe import android.app.Activity import ca.allanwang.kau.R +import ca.allanwang.kau.kotlin.kauRemoveIf +import ca.allanwang.kau.logging.KL import ca.allanwang.kau.swipe.SwipeBackHelper.onDestroy import java.util.* -class SwipeBackException(message: String = "You Should call kauSwipeOnCreate() first") : RuntimeException(message) +internal class SwipeBackException(message: String = "You Should call kauSwipeOnCreate() first") : RuntimeException(message) /** * Singleton to hold our swipe stack * All activity pages held with strong references, so it is crucial to call * [onDestroy] whenever an activity should be disposed */ -object SwipeBackHelper { +internal object SwipeBackHelper { private val pageStack = Stack<SwipeBackPage>() - private operator fun get(activity: Activity): SwipeBackPage - = pageStack.firstOrNull { it.activity === activity } ?: throw SwipeBackException() - - fun getCurrentPage(activity: Activity): SwipeBackPage = this[activity] + private operator fun get(activity: Activity): SwipeBackPage? + = pageStack.firstOrNull { it.activityRef.get() === activity } fun onCreate(activity: Activity, builder: SwipeBackContract.() -> Unit = {}) { - val page = pageStack.firstOrNull { it.activity === activity } ?: pageStack.push(SwipeBackPage(activity).apply { builder() }) + val page = this[activity] ?: pageStack.push(SwipeBackPage(activity).apply { builder() }) val startAnimation: Int = when (page.edgeFlag) { SWIPE_EDGE_LEFT -> R.anim.kau_slide_in_right SWIPE_EDGE_RIGHT -> R.anim.kau_slide_in_left @@ -30,23 +30,28 @@ object SwipeBackHelper { else -> R.anim.kau_slide_in_top } activity.overridePendingTransition(startAnimation, 0) + KL.v("KauSwipe onCreate ${activity.localClassName}") } - fun onPostCreate(activity: Activity) = this[activity].onPostCreate() + fun onPostCreate(activity: Activity) { + this[activity]?.onPostCreate() ?: throw SwipeBackException() + KL.v("KauSwipe onPostCreate ${activity.localClassName}") + } fun onDestroy(activity: Activity) { - val page: SwipeBackPage = this[activity] - pageStack.remove(page) - page.activity = null + val page: SwipeBackPage? = this[activity] + pageStack.kauRemoveIf { it.activityRef.get() == null || it === page } + page?.activityRef?.clear() + KL.v("KauSwipe onDestroy ${activity.localClassName}") } - fun finish(activity: Activity) = this[activity].scrollToFinishActivity() + fun finish(activity: Activity) = this[activity]?.scrollToFinishActivity() - internal fun getPrePage(activity: SwipeBackPage): SwipeBackPage? { - val index = pageStack.indexOf(activity) - return if (index > 0) pageStack[index - 1] else null + internal fun getPrePage(page: SwipeBackPage): SwipeBackPage? { + //clean invalid pages + pageStack.kauRemoveIf { it.activityRef.get() == null } + return pageStack.getOrNull(pageStack.indexOf(page) - 1) } - } /** 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 1474c1a..51cd17f 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackLayout.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackLayout.kt @@ -10,6 +10,7 @@ import android.view.MotionEvent import android.view.View import android.view.ViewGroup import android.widget.FrameLayout +import ca.allanwang.kau.logging.KL import ca.allanwang.kau.utils.adjustAlpha import ca.allanwang.kau.utils.navigationBarColor import ca.allanwang.kau.utils.statusBarColor @@ -22,8 +23,8 @@ import java.lang.ref.WeakReference * If an edge detection occurs, this layout consumes all the touch events * Use the [swipeEnabled] toggle if you need the scroll events on the same axis */ -class SwipeBackLayout @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0 -) : FrameLayout(context, attrs, defStyle), SwipeBackContract { +internal class SwipeBackLayout @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0 +) : FrameLayout(context, attrs, defStyle), SwipeBackContract, SwipeBackContractInternal { override val swipeBackLayout: SwipeBackLayout get() = this @@ -51,7 +52,7 @@ class SwipeBackLayout @JvmOverloads constructor(context: Context, attrs: Attribu override var disallowIntercept = false - private var contentView: View? = null + private lateinit var contentViewRef: WeakReference<View> private val dragHelper: ViewDragHelper @@ -156,16 +157,6 @@ class SwipeBackLayout @JvmOverloads constructor(context: Context, attrs: Attribu addListener(chromeFadeListener) } - - /** - * Set up contentView which will be moved by user gesture - - * @param view - */ - private fun setContentView(view: View) { - contentView = view - } - override fun setEdgeSizePercent(swipeEdgePercent: Float) { edgeSize = ((if (horizontal) resources.displayMetrics.widthPixels else resources.displayMetrics.heightPixels) * swipeEdgePercent).toInt() } @@ -181,6 +172,7 @@ class SwipeBackLayout @JvmOverloads constructor(context: Context, attrs: Attribu /** * Removes a listener from the set of listeners + * and scans our list for invalid ones * @param listener */ @@ -194,10 +186,27 @@ class SwipeBackLayout @JvmOverloads constructor(context: Context, attrs: Attribu } /** + * Checks if a listener exists in our list, + * and remove invalid ones at the same time + */ + override fun hasListener(listener: SwipeListener): Boolean { + val iter = listeners.iterator() + while (iter.hasNext()) { + val l = iter.next().get() + if (l == null) + iter.remove() + else if (l == listener) + return true + } + return false + } + + /** * Scroll out contentView and finish the activity */ override fun scrollToFinishActivity() { - val childWidth = contentView!!.width + val contentView = contentViewRef.get() ?: return KL.e("KauSwipe cannot scroll to finish as contentView is null. Is onPostCreate called?") + val childWidth = contentView.width val top = 0 val left = childWidth + OVERSCROLL_DISTANCE dragHelper.smoothSlideViewTo(contentView, left, top) @@ -224,6 +233,7 @@ class SwipeBackLayout @JvmOverloads constructor(context: Context, attrs: Attribu } override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) { + val contentView = contentViewRef.get() ?: return KL.e("KauSwipe cannot change layout as contentView is null. Is onPostCreate called?") inLayout = true val xOffset: Int val yOffset: Int @@ -234,7 +244,7 @@ class SwipeBackLayout @JvmOverloads constructor(context: Context, attrs: Attribu xOffset = 0 yOffset = contentOffset } - contentView?.layout(xOffset, yOffset, xOffset + contentView!!.measuredWidth, yOffset + contentView!!.measuredHeight) + contentView.layout(xOffset, yOffset, xOffset + contentView.measuredWidth, yOffset + contentView.measuredHeight) inLayout = false } @@ -243,7 +253,7 @@ class SwipeBackLayout @JvmOverloads constructor(context: Context, attrs: Attribu } override fun drawChild(canvas: Canvas, child: View, drawingTime: Long): Boolean { - val drawContent = child === contentView + val drawContent = child === contentViewRef.get() val ret = super.drawChild(canvas, child, drawingTime) if (scrimOpacity > 0 && drawContent && dragHelper.viewDragState != ViewDragHelper.STATE_IDLE) drawScrim(canvas, child) @@ -272,7 +282,7 @@ class SwipeBackLayout @JvmOverloads constructor(context: Context, attrs: Attribu val contentChild = content.getChildAt(0) content.removeView(contentChild) addView(contentChild) - setContentView(contentChild) + contentViewRef = WeakReference(contentChild) content.addView(this) } @@ -286,6 +296,7 @@ class SwipeBackLayout @JvmOverloads constructor(context: Context, attrs: Attribu content.removeView(this) removeView(contentChild) content.addView(contentChild) + contentViewRef.clear() } override fun computeScroll() { @@ -324,10 +335,11 @@ class SwipeBackLayout @JvmOverloads constructor(context: Context, attrs: Attribu override fun onViewPositionChanged(changedView: View, left: Int, top: Int, dx: Int, dy: Int) { super.onViewPositionChanged(changedView, left, top, dx, dy) + val contentView = contentViewRef.get() ?: return KL.e("KauSwipe cannot change view position as contentView is null; is onPostCreate called?") //make sure that we are using the proper axis scrollPercent = Math.abs( - if (horizontal) left.toFloat() / contentView!!.width - else (top.toFloat() / contentView!!.height)) + if (horizontal) left.toFloat() / contentView.width + else (top.toFloat() / contentView.height)) contentOffset = if (horizontal) left else top invalidate() if (scrollPercent < scrollThreshold && !isScrollOverValid) diff --git a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackPage.kt b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackPage.kt index 81ddb62..3132f8c 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackPage.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackPage.kt @@ -4,15 +4,17 @@ import android.app.Activity import android.graphics.Color import android.graphics.drawable.ColorDrawable import android.view.ViewGroup +import ca.allanwang.kau.logging.KL +import java.lang.ref.WeakReference /** * Created by Mr.Jude on 2015/8/3. * * Updated by Allan Wang on 2017/07/05 */ -class SwipeBackPage(activity: Activity) : SwipeBackContract by SwipeBackLayout(activity) { +internal class SwipeBackPage(activity: Activity) : SwipeBackContractInternal by SwipeBackLayout(activity) { - var activity: Activity? = activity + var activityRef = WeakReference(activity) var slider: RelativeSlider /** @@ -38,8 +40,9 @@ class SwipeBackPage(activity: Activity) : SwipeBackContract by SwipeBackLayout(a } private fun handleLayout() { - if (swipeEnabled) swipeBackLayout.attachToActivity(activity!!) - else swipeBackLayout.removeFromActivity(activity!!) + val activity = activityRef.get() ?: return KL.v("KauSwipe activity ref gone during handleLayout") + if (swipeEnabled) swipeBackLayout.attachToActivity(activity) + else swipeBackLayout.removeFromActivity(activity) } fun setClosePercent(percent: Float): SwipeBackPage { @@ -49,6 +52,10 @@ class SwipeBackPage(activity: Activity) : SwipeBackContract by SwipeBackLayout(a } +internal interface SwipeBackContractInternal : SwipeBackContract { + val swipeBackLayout: SwipeBackLayout +} + interface SwipeBackContract { /** * Toggle main touch intercept @@ -59,7 +66,6 @@ interface SwipeBackContract { * This dynamically fades as the page gets closer to exiting */ var scrimColor: Int - val swipeBackLayout: SwipeBackLayout var edgeSize: Int /** * Set the flag for which edge the page is scrolling from @@ -92,7 +98,9 @@ interface SwipeBackContract { * Sets edge size based on screen size */ fun setEdgeSizePercent(swipeEdgePercent: Float) + fun addListener(listener: SwipeListener) fun removeListener(listener: SwipeListener) + fun hasListener(listener: SwipeListener): Boolean fun scrollToFinishActivity() }
\ No newline at end of file diff --git a/core/src/main/kotlin/ca/allanwang/kau/swipe/ViewDragHelper.java b/core/src/main/kotlin/ca/allanwang/kau/swipe/ViewDragHelper.java index 3368e10..566e9e5 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/swipe/ViewDragHelper.java +++ b/core/src/main/kotlin/ca/allanwang/kau/swipe/ViewDragHelper.java @@ -28,7 +28,7 @@ import static ca.allanwang.kau.swipe.SwipeBackHelperKt.SWIPE_EDGE_TOP; * This is an extension of {@link android.support.v4.widget.ViewDragHelper} * Along with additional methods defined in {@link ViewDragHelperExtras} */ -public class ViewDragHelper implements ViewDragHelperExtras { +class ViewDragHelper implements ViewDragHelperExtras { private static final String TAG = "ViewDragHelper"; /** |