aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/dialogs/color/ColorPickerView.kt2
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/swipe/RelateSlider.java52
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/swipe/RelativeSlider.kt36
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackHelper.java68
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackHelper.kt45
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackLayout.java438
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackLayout.kt312
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackPage.java120
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackPage.kt66
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeListener.java10
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeListener.kt10
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/utils/ColorUtils.kt13
-rw-r--r--sample/src/main/AndroidManifest.xml2
-rw-r--r--sample/src/main/kotlin/ca/allanwang/kau/sample/AnimActivity.kt24
-rw-r--r--sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt2
15 files changed, 502 insertions, 698 deletions
diff --git a/core/src/main/kotlin/ca/allanwang/kau/dialogs/color/ColorPickerView.kt b/core/src/main/kotlin/ca/allanwang/kau/dialogs/color/ColorPickerView.kt
index da864c9..20e0259 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/dialogs/color/ColorPickerView.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/dialogs/color/ColorPickerView.kt
@@ -31,7 +31,7 @@ internal class ColorPickerView @JvmOverloads constructor(
var isInCustom: Boolean = false
var circleSize: Int = context.dimen(R.dimen.kau_color_circle_size).toInt()
val backgroundColor = context.resolveColor(R.attr.md_background_color,
- if (context.resolveColor(android.R.attr.textColorPrimary).isColorDark()) Color.WHITE else 0xff424242.toInt())
+ if (context.resolveColor(android.R.attr.textColorPrimary).isColorDark) Color.WHITE else 0xff424242.toInt())
val backgroundColorTint = backgroundColor.colorToForeground()
lateinit var dialog: MaterialDialog
lateinit var builder: ColorContract
diff --git a/core/src/main/kotlin/ca/allanwang/kau/swipe/RelateSlider.java b/core/src/main/kotlin/ca/allanwang/kau/swipe/RelateSlider.java
deleted file mode 100644
index d438d00..0000000
--- a/core/src/main/kotlin/ca/allanwang/kau/swipe/RelateSlider.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package ca.allanwang.kau.swipe;
-
-import android.os.Build;
-
-/**
- * Created by Mr.Jude on 2015/8/26.
- */
-public class RelateSlider implements SwipeListener {
- public SwipeBackPage curPage;
- private static final int DEFAULT_OFFSET = 40;
- private int offset = 500;
-
- public RelateSlider(SwipeBackPage curActivity) {
- this.curPage = curActivity;
- //curPage.addListener(this);
- }
-
- public void setOffset(int offset) {
- this.offset = offset;
- }
-
- public void setEnable(boolean enable){
- if (enable)curPage.addListener(this);
- else curPage.removeListener(this);
- }
-
- @Override
- public void onScroll(float percent, int px) {
- if (Build.VERSION.SDK_INT>11){
- SwipeBackPage page = SwipeBackHelper.getPrePage(curPage);
- if (page!=null){
- page.getSwipeBackLayout().setX(Math.min(-offset * Math.max(1 - percent,0)+DEFAULT_OFFSET,0));
- if (percent == 0){
- page.getSwipeBackLayout().setX(0);
- }
- }
- }
- }
-
- @Override
- public void onEdgeTouch() {
-
- }
-
- @Override
- public void onScrollToClose() {
- SwipeBackPage page = SwipeBackHelper.getPrePage(curPage);
- if (Build.VERSION.SDK_INT>11) {
- if (page != null) page.getSwipeBackLayout().setX(0);
- }
- }
-}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/swipe/RelativeSlider.kt b/core/src/main/kotlin/ca/allanwang/kau/swipe/RelativeSlider.kt
new file mode 100644
index 0000000..ee86ff2
--- /dev/null
+++ b/core/src/main/kotlin/ca/allanwang/kau/swipe/RelativeSlider.kt
@@ -0,0 +1,36 @@
+package ca.allanwang.kau.swipe
+
+import ca.allanwang.kau.kotlin.nonReadable
+
+/**
+ * Created by Mr.Jude on 2015/8/26.
+ */
+class RelativeSlider(var curPage: SwipeBackPage) : SwipeListener {
+
+ var offset = 0f
+
+ var enabled: Boolean
+ @Deprecated(level = DeprecationLevel.ERROR, message = "Cannot use enabled as getter")
+ get() = nonReadable()
+ set(value) {
+ if (value) curPage.addListener(this)
+ else curPage.removeListener(this)
+ }
+
+ override fun onScroll(percent: Float, px: Int) {
+ if (offset == 0f) return //relative slider is not enabled
+ val page = SwipeBackHelper.getPrePage(curPage) ?: return
+ page.swipeBackLayout.x = Math.min(-offset * Math.max(1 - percent, 0f) + DEFAULT_OFFSET, 0f)
+ if (percent == 0f) page.swipeBackLayout.x = 0f
+ }
+
+ override fun onEdgeTouch() {}
+
+ override fun onScrollToClose() {
+ SwipeBackHelper.getPrePage(curPage)?.swipeBackLayout?.x = 0f
+ }
+
+ companion object {
+ private const val DEFAULT_OFFSET = 40
+ }
+}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackHelper.java b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackHelper.java
deleted file mode 100644
index b72112e..0000000
--- a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackHelper.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package ca.allanwang.kau.swipe;
-
-import android.app.Activity;
-
-import java.util.Stack;
-
-/**
- * 滑动的全局管理类
- */
-public class SwipeBackHelper {
-
- private static final Stack<SwipeBackPage> mPageStack = new Stack<>();
-
- private static SwipeBackPage findHelperByActivity(Activity activity){
- for (SwipeBackPage swipeBackPage : mPageStack) {
- if (swipeBackPage.mActivity == activity) return swipeBackPage;
- }
- return null;
- }
-
- public static SwipeBackPage getCurrentPage(Activity activity){
- SwipeBackPage page;
- if ((page = findHelperByActivity(activity)) == null){
- throw new RuntimeException("You Should call SwipeBackHelper.onCreate(activity) first");
- }
- return page;
- }
-
- public static void onCreate(Activity activity) {
- SwipeBackPage page;
- if ((page = findHelperByActivity(activity)) == null){
- page = mPageStack.push(new SwipeBackPage(activity));
- }
- page.onCreate();
- }
-
- public static void onPostCreate(Activity activity){
- SwipeBackPage page;
- if ((page = findHelperByActivity(activity)) == null){
- throw new RuntimeException("You Should call SwipeBackHelper.onCreate(activity) first");
- }
- page.onPostCreate();
- }
-
- public static void onDestroy(Activity activity){
- SwipeBackPage page;
- if ((page = findHelperByActivity(activity)) == null){
- throw new RuntimeException("You Should call SwipeBackHelper.onCreate(activity) first");
- }
- mPageStack.remove(page);
- page.mActivity=null;
- }
-
- public static void finish(Activity activity){
- SwipeBackPage page;
- if ((page = findHelperByActivity(activity)) == null){
- throw new RuntimeException("You Should call SwipeBackHelper.onCreate(activity) first");
- }
- page.scrollToFinishActivity();
- }
-
- static SwipeBackPage getPrePage(SwipeBackPage activity){
- int index = mPageStack.indexOf(activity);
- if (index>0)return mPageStack.get(index-1);
- else return null;
- }
-
-}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackHelper.kt b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackHelper.kt
new file mode 100644
index 0000000..4a8b6dc
--- /dev/null
+++ b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackHelper.kt
@@ -0,0 +1,45 @@
+package ca.allanwang.kau.swipe
+
+import android.app.Activity
+import ca.allanwang.kau.logging.KL
+import java.util.*
+
+class SwipeBackException(message: String = "You Should call SwipeBackHelper.onCreate(activity) first") : RuntimeException(message)
+
+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]
+
+ fun onCreate(activity: Activity) {
+ pageStack.firstOrNull { it.activity === activity } ?: pageStack.push(SwipeBackPage(activity))
+// activity.window.exitTransition =
+ }
+
+ fun onPostCreate(activity: Activity) = this[activity].onPostCreate()
+
+ fun onDestroy(activity: Activity) {
+ KL.d("Swipe destroy")
+ val page: SwipeBackPage = this[activity]
+ pageStack.remove(page)
+ page.activity = null
+ }
+
+ 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
+ }
+
+}
+
+fun Activity.kauSwipeOnCreate() = SwipeBackHelper.onCreate(this)
+fun Activity.kauSwipeOnPostCreate() = SwipeBackHelper.onPostCreate(this)
+fun Activity.kauSwipeOnDestroy() = SwipeBackHelper.onDestroy(this)
+fun Activity.kauSwipeFinish() = SwipeBackHelper.finish(this)
+
diff --git a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackLayout.java b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackLayout.java
deleted file mode 100644
index 57195f2..0000000
--- a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackLayout.java
+++ /dev/null
@@ -1,438 +0,0 @@
-package ca.allanwang.kau.swipe;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.support.v4.view.ViewCompat;
-import android.support.v4.widget.ViewDragHelper;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class SwipeBackLayout extends FrameLayout {
- private static final String TAG = "ViewDragHelper";
-
- /**
- * Minimum velocity that will be detected as a fling
- */
- private static final int MIN_FLING_VELOCITY = 400; // dips per second
-
- private static final int DEFAULT_SCRIM_COLOR = 0x99000000;
-
- private static final int FULL_ALPHA = 255;
-
-
- /**
- * A view is currently being dragged. The position is currently changing as
- * a result of user input or simulated user input.
- */
- public static final int STATE_DRAGGING = ViewDragHelper.STATE_DRAGGING;
-
- /**
- * A view is currently settling into place as a result of a fling or
- * predefined non-interactive motion.
- */
- public static final int STATE_SETTLING = ViewDragHelper.STATE_SETTLING;
-
- /**
- * Default threshold of scroll
- */
- private static final float DEFAULT_SCROLL_THRESHOLD = 0.3f;
-
- private static final int OVERSCROLL_DISTANCE = 10;
-
- /**
- * Threshold of scroll, we will close the activity, when scrollPercent over
- * this value;
- */
- private float mScrollThreshold = DEFAULT_SCROLL_THRESHOLD;
-
- private Activity mActivity;
-
- private boolean mEnable = true;
-
- private boolean mDisallowIntercept = false;
-
- private View mContentView;
-
- private ViewDragHelper mDragHelper;
-
- private float mScrollPercent;
-
- private int mContentLeft;
-
- /**
- * The set of listeners to be sent events through.
- */
- private List<SwipeListener> mListeners;
-
- Drawable mShadowLeft;
-
- private float mScrimOpacity;
-
- private int mScrimColor = DEFAULT_SCRIM_COLOR;
-
- private boolean mInLayout;
-
- private Rect mTmpRect = new Rect();
-
- /**
- * Edge being dragged
- */
- private int mTrackingEdge;
-
- public SwipeBackLayout(Context context) {
- this(context, null);
- }
-
- public SwipeBackLayout(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public SwipeBackLayout(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs);
- mDragHelper = ViewDragHelper.create(this, new ViewDragCallback());
-
- setShadow(R.drawable.shadow_left);
-
- final float density = getResources().getDisplayMetrics().density;
- final float minVel = MIN_FLING_VELOCITY * density;
- setEdgeSize(getResources().getDisplayMetrics().widthPixels);
- mDragHelper.setMinVelocity(minVel);
- mDragHelper.setMaxVelocity(minVel * 2f);
- mDragHelper.setSensitivity(context, 0.3f);
- mDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
- }
-
- /**
- * Sets the sensitivity of the NavigationLayout.
- *
- * @param context The application context.
- * @param sensitivity value between 0 and 1, the final value for touchSlop =
- * ViewConfiguration.getScaledTouchSlop * (1 / s);
- */
- public void setSensitivity(Context context, float sensitivity) {
- mDragHelper.setSensitivity(context, sensitivity);
- }
-
- /**
- * Set up contentView which will be moved by user gesture
- *
- * @param view
- */
- private void setContentView(View view) {
- mContentView = view;
- }
-
- public void setEnableGesture(boolean enable) {
- mEnable = enable;
- }
-
- /**
- * Set a color to use for the scrim that obscures primary content while a
- * drawer is open.
- *
- * @param color Color to use in 0xAARRGGBB format.
- */
- public void setScrimColor(int color) {
- mScrimColor = color;
- invalidate();
- }
-
- /**
- * Set the size of an edge. This is the range in pixels along the edges of
- * this view that will actively detect edge touches or drags if edge
- * tracking is enabled.
- *
- * @param size The size of an edge in pixels
- */
- public void setEdgeSize(int size) {
- mTrackingEdge = size;
- mDragHelper.edsetEdgeSize(mTrackingEdge);
- }
-
-
- public void setEdgeSizePercent(float size) {
- mTrackingEdge = (int) (getResources().getDisplayMetrics().widthPixels * size);
- mDragHelper.setEdgeSize(mTrackingEdge);
- }
-
- /**
- * Register a callback to be invoked when a swipe event is sent to this
- * view.
- *
- * @param listener the swipe listener to attach to this view
- * @deprecated use {@link #addSwipeListener} instead
- */
- @Deprecated
- public void setSwipeListener(SwipeListener listener) {
- addSwipeListener(listener);
- }
-
- /**
- * Add a callback to be invoked when a swipe event is sent to this view.
- *
- * @param listener the swipe listener to attach to this view
- */
- public void addSwipeListener(SwipeListener listener) {
- if (mListeners == null) {
- mListeners = new ArrayList<SwipeListener>();
- }
- mListeners.add(listener);
- }
-
- /**
- * Removes a listener from the set of listeners
- *
- * @param listener
- */
- public void removeSwipeListener(SwipeListener listener) {
- if (mListeners == null) {
- return;
- }
- mListeners.remove(listener);
- }
-
-
-
- /**
- * Set scroll threshold, we will close the activity, when scrollPercent over
- * this value
- *
- * @param threshold
- */
- public void setScrollThreshold(float threshold) {
- if (threshold >= 1.0f || threshold <= 0) {
- throw new IllegalArgumentException("Threshold value should be between 0 and 1.0");
- }
- mScrollThreshold = threshold;
- }
-
-
- public void setShadow(Drawable shadow) {
- mShadowLeft = shadow;
- invalidate();
- }
-
-
- public void setShadow(int resId) {
- setShadow(getResources().getDrawable(resId));
- }
-
- /**
- * Scroll out contentView and finish the activity
- */
- public void scrollToFinishActivity() {
- final int childWidth = mContentView.getWidth();
- int left = 0, top = 0;
- left = childWidth + mShadowLeft.getIntrinsicWidth() + OVERSCROLL_DISTANCE;
- mDragHelper.smoothSlideViewTo(mContentView, left, top);
- invalidate();
- }
-
- @Override
- public boolean onInterceptTouchEvent(MotionEvent event) {
- if (!mEnable||mDisallowIntercept) {
- return false;
- }
- try {
- return mDragHelper.shouldInterceptTouchEvent(event);
- } catch (Exception e) {
-// e.printStackTrace();
- return false;
- }
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (!mEnable) {
- return false;
- }
- try {
- mDragHelper.processTouchEvent(event);
- } catch (Exception e) {
-// e.printStackTrace();
- return false;
- }
- return true;
- }
-
- public void setDisallowInterceptTouchEvent(boolean disallowIntercept) {
- mDisallowIntercept = disallowIntercept;
- }
-
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- mInLayout = true;
- if (mContentView != null)
- mContentView.layout(mContentLeft, 0,
- mContentLeft + mContentView.getMeasuredWidth(),
- mContentView.getMeasuredHeight());
- mInLayout = false;
- }
-
- @Override
- public void requestLayout() {
- if (!mInLayout) {
- super.requestLayout();
- }
- }
-
- @Override
- protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
- final boolean drawContent = child == mContentView;
-
- boolean ret = super.drawChild(canvas, child, drawingTime);
- if (mScrimOpacity > 0 && drawContent
- && mDragHelper.getViewDragState() != ViewDragHelper.STATE_IDLE) {
- drawShadow(canvas, child);
- drawScrim(canvas, child);
- }
- return ret;
- }
-
- private void drawScrim(Canvas canvas, View child) {
- final int baseAlpha = (mScrimColor & 0xff000000) >>> 24;
- final int alpha = (int) (baseAlpha * mScrimOpacity);
- final int color = alpha << 24 | (mScrimColor & 0xffffff);
- canvas.clipRect(0, 0, child.getLeft(), getHeight());
- canvas.drawColor(color);
- }
-
- private void drawShadow(Canvas canvas, View child) {
- final Rect childRect = mTmpRect;
- child.getHitRect(childRect);
-
- mShadowLeft.setBounds(childRect.left - mShadowLeft.getIntrinsicWidth(), childRect.top,
- childRect.left, childRect.bottom);
- mShadowLeft.setAlpha((int) (mScrimOpacity * FULL_ALPHA));
- mShadowLeft.draw(canvas);
- }
-
- public void attachToActivity(Activity activity) {
- if (getParent()!=null){
- return;
- }
- mActivity = activity;
- TypedArray a = activity.getTheme().obtainStyledAttributes(new int[]{
- android.R.attr.windowBackground
- });
- int background = a.getResourceId(0, 0);
- a.recycle();
-
- ViewGroup decor = (ViewGroup) activity.getWindow().getDecorView();
- View decorChild = decor.findViewById(android.R.id.content);
- while (decorChild.getParent() != decor){
- decorChild = (View) decorChild.getParent();
- }
- decorChild.setBackgroundResource(background);
- decor.removeView(decorChild);
- addView(decorChild);
- setContentView(decorChild);
- decor.addView(this);
- }
-
- public void removeFromActivity(Activity activity){
- if (getParent()==null)return;
- ViewGroup decorChild = (ViewGroup) getChildAt(0);
- ViewGroup decor = (ViewGroup) activity.getWindow().getDecorView();
- decor.removeView(this);
- removeView(decorChild);
- decor.addView(decorChild);
- }
-
- @Override
- public void computeScroll() {
- mScrimOpacity = 1 - mScrollPercent;
- if (mDragHelper.continueSettling(true)) {
- ViewCompat.postInvalidateOnAnimation(this);
- }
- }
-
- private class ViewDragCallback extends ViewDragHelper.Callback {
- private boolean mIsScrollOverValid;
-
- @Override
- public boolean tryCaptureView(View view, int i) {
- boolean ret = mDragHelper.isEdgeTouched(ViewDragHelper.EDGE_LEFT, i);
- if (ret) {
- if (mListeners != null && !mListeners.isEmpty()) {
- for (SwipeListener listener : mListeners) {
- listener.onEdgeTouch();
- }
- }
- mIsScrollOverValid = true;
- }
- return ret;
- }
-
- @Override
- public int getViewHorizontalDragRange(View child) {
- return mTrackingEdge;
- }
-
- @Override
- public int getViewVerticalDragRange(View child) {
- return 0;
- }
-
- @Override
- public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
- super.onViewPositionChanged(changedView, left, top, dx, dy);
- mScrollPercent = Math.abs((float) left / (mContentView.getWidth() /*+ mShadowLeft.getIntrinsicWidth()*/));
- mContentLeft = left;
- invalidate();
- if (mScrollPercent < mScrollThreshold && !mIsScrollOverValid) {
- mIsScrollOverValid = true;
- }
-
- if (mListeners != null && !mListeners.isEmpty()) {
- for (SwipeListener listener : mListeners) {
- listener.onScroll(mScrollPercent, mContentLeft);
- }
- }
- if (mScrollPercent >= 1) {
- if (!mActivity.isFinishing()){
- if (mListeners != null && !mListeners.isEmpty()
- && mScrollPercent >= mScrollThreshold && mIsScrollOverValid) {
- mIsScrollOverValid = false;
- for (SwipeListener listener : mListeners) {
- listener.onScrollToClose();
- }
- }
- mActivity.finish();
- }
- }
-
-
- }
-
- @Override
- public void onViewReleased(View releasedChild, float xvel, float yvel) {
- final int childWidth = releasedChild.getWidth();
-
- int left = 0, top = 0;
- //判断释放以后是应该滑到最右边(关闭),还是最左边(还原)
- left = xvel > 0 || xvel == 0 && mScrollPercent > mScrollThreshold ? childWidth
- + mShadowLeft.getIntrinsicWidth() + OVERSCROLL_DISTANCE : 0;
-
-
- mDragHelper.settleCapturedViewAt(left, top);
- invalidate();
- }
-
- @Override
- public int clampViewPositionHorizontal(View child, int left, int dx) {
- return Math.min(child.getWidth(), Math.max(left, 0));
- }
-
- }
-}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackLayout.kt b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackLayout.kt
new file mode 100644
index 0000000..37dde73
--- /dev/null
+++ b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackLayout.kt
@@ -0,0 +1,312 @@
+package ca.allanwang.kau.swipe
+
+import android.app.Activity
+import android.content.Context
+import android.graphics.Canvas
+import android.graphics.Color
+import android.support.v4.view.ViewCompat
+import android.support.v4.widget.ViewDragHelper
+import android.util.AttributeSet
+import android.view.MotionEvent
+import android.view.View
+import android.view.ViewGroup
+import android.widget.FrameLayout
+import ca.allanwang.kau.utils.navigationBarColor
+import ca.allanwang.kau.utils.statusBarColor
+import java.lang.ref.WeakReference
+
+class SwipeBackLayout @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0
+) : FrameLayout(context, attrs, defStyle), SwipeBackPageContract {
+
+ override val swipeBackLayout: SwipeBackLayout
+ get() = this
+ /**
+ * Threshold of scroll, we will close the activity, when scrollPercent over
+ * this value;
+ */
+ override var scrollThreshold = DEFAULT_SCROLL_THRESHOLD
+ set(value) {
+ if (value >= 1.0f || value <= 0) throw IllegalArgumentException("Threshold value should be between 0 and 1.0")
+ field = value
+ }
+
+ var activity: Activity? = null
+ set(value) {
+ field = value
+ if (value != null) {
+ statusBarAlpha = Color.alpha(value.statusBarColor)
+ navBarAlpha = Color.alpha(value.navigationBarColor)
+ }
+ }
+
+ override var swipeEnabled = true
+
+ override var disallowIntercept = false
+
+ private var contentView: View? = null
+
+ private val dragHelper: ViewDragHelper
+
+ private var scrollPercent: Float = 0.toFloat()
+
+ private var contentOffset: Int = 0
+
+ /**
+ * The set of listeners to be sent events through.
+ */
+ private var listeners: MutableList<WeakReference<SwipeListener>> = mutableListOf()
+
+ private var scrimOpacity: Float = 0f
+
+ override var scrimColor = DEFAULT_SCRIM_COLOR
+ /**
+ * Set a color to use for the scrim that obscures primary content while a
+ * drawer is open.
+
+ * @param color Color to use in 0xAARRGGBB format.
+ */
+ set(value) {
+ field = value
+ invalidate()
+ }
+
+ var statusBarAlpha: Int = 255
+ var navBarAlpha: Int = 255
+
+ val chromeFadeListener: SwipeListener by lazy {
+ object : SwipeListener {
+ override fun onScroll(percent: Float, px: Int) {
+ TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+ }
+
+ override fun onEdgeTouch() {
+ TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+ }
+
+ override fun onScrollToClose() {
+ TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+ }
+
+ }
+ }
+
+
+ private var inLayout: Boolean = false
+
+ /**
+ * Edge being dragged
+ */
+ private var trackingEdge: Int = 0
+
+ init {
+ dragHelper = ViewDragHelper.create(this, ViewDragCallback())
+ val density = resources.displayMetrics.density
+ val minVel = MIN_FLING_VELOCITY * density
+ setEdgeSize(resources.displayMetrics.widthPixels)
+ dragHelper.minVelocity = minVel
+ dragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT)
+ }
+
+
+ /**
+ * Set up contentView which will be moved by user gesture
+
+ * @param view
+ */
+ private fun setContentView(view: View) {
+ contentView = view
+ }
+
+ /**
+ * Set the size of an edge. This is the range in pixels along the edges of
+ * this view that will actively detect edge touches or drags if edge
+ * tracking is enabled.
+
+ * @param swipeEdge The size of an edge in pixels
+ */
+ override fun setEdgeSize(swipeEdge: Int) {
+ trackingEdge = swipeEdge
+ }
+
+
+ override fun setEdgeSizePercent(swipeEdgePercent: Float) {
+ trackingEdge = (resources.displayMetrics.widthPixels * swipeEdgePercent).toInt()
+ }
+
+ /**
+ * Add a callback to be invoked when a swipe event is sent to this view.
+
+ * @param listener the swipe listener to attach to this view
+ */
+ override fun addListener(listener: SwipeListener) {
+ listeners.add(WeakReference(listener))
+ }
+
+ /**
+ * Removes a listener from the set of listeners
+
+ * @param listener
+ */
+ override fun removeListener(listener: SwipeListener) {
+ val iter = listeners.iterator()
+ while (iter.hasNext()) {
+ val l = iter.next().get()
+ if (l == null || l == listener)
+ iter.remove()
+ }
+ }
+
+ /**
+ * Scroll out contentView and finish the activity
+ */
+ override fun scrollToFinishActivity() {
+ val childWidth = contentView!!.width
+ val top = 0
+ val left = childWidth + OVERSCROLL_DISTANCE
+ dragHelper.smoothSlideViewTo(contentView, left, top)
+ invalidate()
+ }
+
+ override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
+ if (!swipeEnabled || disallowIntercept) return false
+ val s = dragHelper.shouldInterceptTouchEvent(event)
+ return s
+ }
+
+ override fun onTouchEvent(event: MotionEvent): Boolean {
+ if (!swipeEnabled) return false
+ dragHelper.processTouchEvent(event)
+ return true
+ }
+
+ override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
+ inLayout = true
+ contentView?.layout(contentOffset, 0, contentOffset + contentView!!.measuredWidth, contentView!!.measuredHeight)
+ inLayout = false
+ }
+
+ override fun requestLayout() {
+ if (!inLayout) super.requestLayout()
+ }
+
+ override fun drawChild(canvas: Canvas, child: View, drawingTime: Long): Boolean {
+ val drawContent = child === contentView
+ val ret = super.drawChild(canvas, child, drawingTime)
+ if (scrimOpacity > 0 && drawContent && dragHelper.viewDragState != ViewDragHelper.STATE_IDLE)
+ drawScrim(canvas, child)
+ return ret
+ }
+
+ private fun drawScrim(canvas: Canvas, child: View) {
+ val baseAlpha = (scrimColor and 0xff000000.toInt()).ushr(24)
+ val alpha = (baseAlpha * scrimOpacity).toInt()
+ val color = alpha shl 24 or (scrimColor and 0xffffff)
+ canvas.clipRect(0, 0, child.left, height)
+ canvas.drawColor(color)
+ }
+
+ fun attachToActivity(activity: Activity) {
+ if (parent != null) return
+ this.activity = activity
+ val a = activity.theme.obtainStyledAttributes(intArrayOf(android.R.attr.windowBackground))
+ val background = a.getResourceId(0, 0)
+ a.recycle()
+
+ val decor = activity.window.decorView as ViewGroup
+ var decorChild = decor.findViewById<View>(android.R.id.content)
+ while (decorChild.parent !== decor) {
+ decorChild = decorChild.parent as View
+ }
+ decorChild.setBackgroundResource(background)
+ decor.removeView(decorChild)
+ addView(decorChild)
+ setContentView(decorChild)
+ decor.addView(this)
+ }
+
+ fun removeFromActivity(activity: Activity) {
+ if (parent == null) return
+ val decorChild = getChildAt(0) as ViewGroup
+ val decor = activity.window.decorView as ViewGroup
+ decor.removeView(this)
+ removeView(decorChild)
+ decor.addView(decorChild)
+ }
+
+ override fun computeScroll() {
+ scrimOpacity = 1 - scrollPercent
+ if (dragHelper.continueSettling(true)) ViewCompat.postInvalidateOnAnimation(this)
+ }
+
+ private inner class ViewDragCallback : ViewDragHelper.Callback() {
+ private var isScrollOverValid: Boolean = false
+
+ override fun tryCaptureView(view: View, i: Int): Boolean {
+ val ret = dragHelper.isEdgeTouched(ViewDragHelper.EDGE_LEFT, i)
+ if (ret) {
+ listeners.forEach { it.get()?.onEdgeTouch() }
+ isScrollOverValid = true
+ }
+ return ret
+ }
+
+ override fun getViewHorizontalDragRange(child: View): Int {
+ return trackingEdge
+ }
+
+ override fun getViewVerticalDragRange(child: View?): Int {
+ return 0
+ }
+
+ override fun onViewPositionChanged(changedView: View, left: Int, top: Int, dx: Int, dy: Int) {
+ super.onViewPositionChanged(changedView, left, top, dx, dy)
+ scrollPercent = Math.abs(left.toFloat() / contentView!!.width)
+ contentOffset = left
+ invalidate()
+ if (scrollPercent < scrollThreshold && !isScrollOverValid)
+ isScrollOverValid = true
+
+ listeners.forEach { it.get()?.onScroll(scrollPercent, contentOffset) }
+
+ if (scrollPercent >= 1) {
+ if (!(activity?.isFinishing ?: true)) {
+ if (scrollPercent >= scrollThreshold && isScrollOverValid) {
+ isScrollOverValid = false
+ listeners.forEach { it.get()?.onScrollToClose() }
+ }
+ activity?.finish()
+ }
+ }
+ }
+
+ override fun onViewReleased(releasedChild: View, xvel: Float, yvel: Float) {
+ val childWidth = releasedChild.width
+ val top = 0
+ val left = if (xvel > 0 || xvel == 0f && scrollPercent > scrollThreshold)
+ childWidth + OVERSCROLL_DISTANCE
+ else 0
+ dragHelper.settleCapturedViewAt(left, top)
+ invalidate()
+ }
+
+ override fun clampViewPositionHorizontal(child: View, left: Int, dx: Int): Int {
+ return Math.min(child.width, Math.max(left, 0))
+ }
+ }
+
+ companion object {
+ /**
+ * Minimum velocity that will be detected as a fling
+ */
+ private const val MIN_FLING_VELOCITY = 400 // dips per second
+
+ private const val DEFAULT_SCRIM_COLOR = 0x99000000.toInt()
+
+ /**
+ * Default threshold of scroll
+ */
+ private const val DEFAULT_SCROLL_THRESHOLD = 0.3f
+
+ private const val OVERSCROLL_DISTANCE = 10
+ }
+}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackPage.java b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackPage.java
deleted file mode 100644
index 8afb5db..0000000
--- a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackPage.java
+++ /dev/null
@@ -1,120 +0,0 @@
-package ca.allanwang.kau.swipe;
-
-import android.annotation.TargetApi;
-import android.app.Activity;
-import android.graphics.Color;
-import android.graphics.drawable.ColorDrawable;
-import android.view.ViewGroup;
-
-/**
- * Created by Mr.Jude on 2015/8/3.
- * 每个滑动页面的管理
- */
-public class SwipeBackPage {
- //仅为判断是否需要将mSwipeBackLayout注入进去
- private boolean mEnable = true;
- private boolean mRelativeEnable = false;
-
- Activity mActivity;
- SwipeBackLayout mSwipeBackLayout;
- RelateSlider slider;
- SwipeBackPage(Activity activity){
- this.mActivity = activity;
- }
-
- //页面的回调用于配置滑动效果
- void onCreate(){
- mActivity.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
- mActivity.getWindow().getDecorView().setBackgroundColor(Color.TRANSPARENT);
- mSwipeBackLayout = new SwipeBackLayout(mActivity);
- mSwipeBackLayout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
- slider = new RelateSlider(this);
- }
-
- void onPostCreate(){
- handleLayout();
- }
-
-
- @TargetApi(11)
- public SwipeBackPage setSwipeRelateEnable(boolean enable){
- mRelativeEnable = enable;
- slider.setEnable(enable);
- return this;
- }
-
- public SwipeBackPage setSwipeRelateOffset(int offset){
- slider.setOffset(offset);
- return this;
- }
-
- //是否可滑动关闭
- public SwipeBackPage setSwipeBackEnable(boolean enable) {
- mEnable = enable;
- mSwipeBackLayout.setEnableGesture(enable);
- handleLayout();
- return this;
- }
-
- private void handleLayout(){
- if (mEnable||mRelativeEnable){
- mSwipeBackLayout.attachToActivity(mActivity);
- }else {
- mSwipeBackLayout.removeFromActivity(mActivity);
- }
- }
-
- //可滑动的范围。百分比。200表示为左边200px的屏幕
- public SwipeBackPage setSwipeEdge(int swipeEdge){
- mSwipeBackLayout.setEdgeSize(swipeEdge);
- return this;
- }
-
- //可滑动的范围。百分比。0.2表示为左边20%的屏幕
- public SwipeBackPage setSwipeEdgePercent(float swipeEdgePercent){
- mSwipeBackLayout.setEdgeSizePercent(swipeEdgePercent);
- return this;
- }
-
- //对横向滑动手势的敏感程度。0为迟钝 1为敏感
- public SwipeBackPage setSwipeSensitivity(float sensitivity){
- mSwipeBackLayout.setSensitivity(mActivity, sensitivity);
- return this;
- }
-
- //底层阴影颜色
- public SwipeBackPage setScrimColor(int color){
- mSwipeBackLayout.setScrimColor(color);
- return this;
- }
-
- //触发关闭Activity百分比
- public SwipeBackPage setClosePercent(float percent){
- mSwipeBackLayout.setScrollThreshold(percent);
- return this;
- }
-
- public SwipeBackPage setDisallowInterceptTouchEvent(boolean disallowIntercept){
- mSwipeBackLayout.setDisallowInterceptTouchEvent(disallowIntercept);
- return this;
- }
-
- public SwipeBackPage addListener(SwipeListener listener){
- mSwipeBackLayout.addSwipeListener(listener);
- return this;
- }
-
- public SwipeBackPage removeListener(SwipeListener listener){
- mSwipeBackLayout.removeSwipeListener(listener);
- return this;
- }
-
- public SwipeBackLayout getSwipeBackLayout() {
- return mSwipeBackLayout;
- }
-
- public void scrollToFinishActivity() {
- mSwipeBackLayout.scrollToFinishActivity();
- }
-
-}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackPage.kt b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackPage.kt
new file mode 100644
index 0000000..e9a872b
--- /dev/null
+++ b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackPage.kt
@@ -0,0 +1,66 @@
+package ca.allanwang.kau.swipe
+
+import android.app.Activity
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.ViewGroup
+import ca.allanwang.kau.logging.KL
+
+/**
+ * Created by Mr.Jude on 2015/8/3.
+ * 每个滑动页面的管理
+ */
+class SwipeBackPage(activity: Activity) : SwipeBackPageContract by SwipeBackLayout(activity) {
+
+ var activity: Activity? = activity
+ var slider: RelativeSlider
+
+ /**
+ * initializing is the equivalent to onCreate
+ * since that is when the page is created
+ */
+ init {
+ activity.window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ activity.window.decorView.setBackgroundColor(Color.TRANSPARENT)
+ swipeBackLayout.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
+ slider = RelativeSlider(this)
+ }
+
+ fun onPostCreate() {
+ handleLayout()
+ }
+
+ override var swipeEnabled: Boolean
+ get() = swipeBackLayout.swipeEnabled
+ set(value) {
+ swipeBackLayout.swipeEnabled = value
+ handleLayout()
+ }
+
+ private fun handleLayout() {
+ KL.d("Handle layout")
+ if (swipeEnabled) swipeBackLayout.attachToActivity(activity!!)
+ else swipeBackLayout.removeFromActivity(activity!!)
+ }
+
+
+ //触发关闭Activity百分比
+ fun setClosePercent(percent: Float): SwipeBackPage {
+ swipeBackLayout.scrollThreshold=percent
+ return this
+ }
+
+}
+
+interface SwipeBackPageContract {
+ var swipeEnabled: Boolean
+ var scrimColor:Int
+ val swipeBackLayout: SwipeBackLayout
+ var scrollThreshold:Float
+ var disallowIntercept:Boolean
+ fun setEdgeSize(swipeEdge: Int)
+ fun setEdgeSizePercent(swipeEdgePercent: Float)
+ fun addListener(listener: SwipeListener)
+ fun removeListener(listener: SwipeListener)
+ fun scrollToFinishActivity()
+}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeListener.java b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeListener.java
deleted file mode 100644
index 6e67692..0000000
--- a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeListener.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package ca.allanwang.kau.swipe;
-
-public interface SwipeListener {
- void onScroll(float percent,int px);
- void onEdgeTouch();
- /**
- * Invoke when scroll percent over the threshold for the first time
- */
- void onScrollToClose();
- } \ No newline at end of file
diff --git a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeListener.kt b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeListener.kt
new file mode 100644
index 0000000..4fe9fa8
--- /dev/null
+++ b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeListener.kt
@@ -0,0 +1,10 @@
+package ca.allanwang.kau.swipe
+
+interface SwipeListener {
+ fun onScroll(percent: Float, px: Int)
+ fun onEdgeTouch()
+ /**
+ * Invoke when scroll percent over the threshold for the first time
+ */
+ fun onScrollToClose()
+} \ No newline at end of file
diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/ColorUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/ColorUtils.kt
index 8590d6f..84a7c06 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/utils/ColorUtils.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/utils/ColorUtils.kt
@@ -19,8 +19,8 @@ import com.afollestad.materialdialogs.R
/**
* Created by Allan Wang on 2017-06-08.
*/
-fun Int.isColorDark(): Boolean
- = (0.299 * Color.red(this) + 0.587 * Color.green(this) + 0.114 * Color.blue(this)) / 255.0 < 0.5
+val Int.isColorDark: Boolean
+ get() = (0.299 * Color.red(this) + 0.587 * Color.green(this) + 0.114 * Color.blue(this)) / 255.0 < 0.5
fun Int.toHexString(withAlpha: Boolean = false, withHexPrefix: Boolean = true): String {
val hex = if (withAlpha) String.format("#%08X", this)
@@ -36,6 +36,9 @@ fun Int.toHSV(): FloatArray {
return hsv
}
+inline val Int.isColorOpaque: Boolean
+ get() = Color.alpha(this) == 255
+
fun FloatArray.toColor(): Int = Color.HSVToColor(this)
fun Int.isColorVisibleOn(@ColorInt color: Int, @IntRange(from = 0L, to = 255L) delta: Int = 25,
@@ -49,7 +52,7 @@ fun Int.isColorVisibleOn(@ColorInt color: Int, @IntRange(from = 0L, to = 255L) d
@ColorInt
fun Context.getDisabledColor(): Int {
val primaryColor = resolveColor(android.R.attr.textColorPrimary)
- val disabledColor = if (primaryColor.isColorDark()) Color.BLACK else Color.WHITE
+ val disabledColor = if (primaryColor.isColorDark) Color.BLACK else Color.WHITE
return disabledColor.adjustAlpha(0.3f)
}
@@ -86,11 +89,11 @@ fun Int.darken(@FloatRange(from = 0.0, to = 1.0) factor: Float = 0.1f): Int {
@ColorInt
fun Int.colorToBackground(@FloatRange(from = 0.0, to = 1.0) factor: Float = 0.1f): Int
- = if (isColorDark()) darken(factor) else lighten(factor)
+ = if (isColorDark) darken(factor) else lighten(factor)
@ColorInt
fun Int.colorToForeground(@FloatRange(from = 0.0, to = 1.0) factor: Float = 0.1f): Int
- = if (isColorDark()) lighten(factor) else darken(factor)
+ = if (isColorDark) lighten(factor) else darken(factor)
@Throws(IllegalArgumentException::class)
fun String.toColor(): Int {
diff --git a/sample/src/main/AndroidManifest.xml b/sample/src/main/AndroidManifest.xml
index 0ab360e..66b73c3 100644
--- a/sample/src/main/AndroidManifest.xml
+++ b/sample/src/main/AndroidManifest.xml
@@ -24,7 +24,7 @@
</activity>
<activity
android:name=".AnimActivity"
- android:theme="@style/AppTheme.Slide" />
+ android:theme="@style/Kau.Translucent" />
<activity
android:name=".AboutActivity"
android:theme="@style/Kau.Translucent.About" />
diff --git a/sample/src/main/kotlin/ca/allanwang/kau/sample/AnimActivity.kt b/sample/src/main/kotlin/ca/allanwang/kau/sample/AnimActivity.kt
index fbcb88f..c2db025 100644
--- a/sample/src/main/kotlin/ca/allanwang/kau/sample/AnimActivity.kt
+++ b/sample/src/main/kotlin/ca/allanwang/kau/sample/AnimActivity.kt
@@ -1,10 +1,15 @@
package ca.allanwang.kau.sample
import android.os.Bundle
-import android.provider.MediaStore
import android.support.v7.app.AppCompatActivity
import ca.allanwang.kau.logging.KL
-import ca.allanwang.kau.permissions.*
+import ca.allanwang.kau.permissions.PERMISSION_ACCESS_COARSE_LOCATION
+import ca.allanwang.kau.permissions.PERMISSION_ACCESS_FINE_LOCATION
+import ca.allanwang.kau.permissions.kauOnRequestPermissionsResult
+import ca.allanwang.kau.permissions.kauRequestPermissions
+import ca.allanwang.kau.swipe.kauSwipeOnCreate
+import ca.allanwang.kau.swipe.kauSwipeOnDestroy
+import ca.allanwang.kau.swipe.kauSwipeOnPostCreate
import ca.allanwang.kau.utils.fullLinearRecycler
import ca.allanwang.kau.utils.startActivitySlideOut
import ca.allanwang.kau.utils.toast
@@ -35,6 +40,21 @@ class AnimActivity : AppCompatActivity() {
}
true
}
+ kauSwipeOnCreate()
+ }
+
+ override fun onPostCreate(savedInstanceState: Bundle?) {
+ super.onPostCreate(savedInstanceState)
+ kauSwipeOnPostCreate()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ kauSwipeOnDestroy()
+ }
+
+ override fun finish() {
+ super.finish()
}
override fun onBackPressed() {
diff --git a/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt b/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt
index d0a5ee1..1f2d757 100644
--- a/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt
+++ b/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt
@@ -210,7 +210,7 @@ class MainActivity : KPrefActivity() {
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
- R.id.action_settings -> startActivity(AnimActivity::class.java, clearStack = true)
+ R.id.action_settings -> startActivity(AnimActivity::class.java)
R.id.action_email -> sendEmail(R.string.your_email, R.string.your_subject)
R.id.test -> startActivity(ImageActivity::class.java, transition = true)
else -> return super.onOptionsItemSelected(item)