diff --git a/app/build.gradle b/app/build.gradle
index 5aa2ec4..e37c77a 100755
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,13 +1,12 @@
apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
android {
- compileSdkVersion 25
- buildToolsVersion "25.0.2"
-
+ compileSdkVersion 28
defaultConfig {
applicationId "me.yokeyword.swipebackfragment.sample"
- minSdkVersion 14
- targetSdkVersion 23
+ minSdkVersion 16
+ targetSdkVersion 28
versionCode 1
versionName "1.0"
}
@@ -20,8 +19,12 @@ android {
}
dependencies {
- compile fileTree(include: ['*.jar'], dir: 'libs')
- compile 'com.android.support:appcompat-v7:25.2.0'
- compile 'com.android.support:recyclerview-v7:25.2.0'
- compile project(':swipeback')
+ implementation fileTree(include: ['*.jar'], dir: 'libs')
+ implementation 'androidx.appcompat:appcompat:1.0.2'
+ implementation 'androidx.recyclerview:recyclerview:1.0.0'
+ implementation project(':swipeback')
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+}
+repositories {
+ mavenCentral()
}
diff --git a/app/src/main/java/me/yokeyword/swipebackfragment/sample/BaseSwipeBackFragment.java b/app/src/main/java/me/yokeyword/swipebackfragment/sample/BaseSwipeBackFragment.java
index 6080683..510b16c 100644
--- a/app/src/main/java/me/yokeyword/swipebackfragment/sample/BaseSwipeBackFragment.java
+++ b/app/src/main/java/me/yokeyword/swipebackfragment/sample/BaseSwipeBackFragment.java
@@ -1,10 +1,10 @@
package me.yokeyword.swipebackfragment.sample;
import android.content.Context;
-import android.support.v4.app.Fragment;
-import android.support.v7.widget.Toolbar;
+import androidx.appcompat.widget.Toolbar;
import android.view.View;
+import androidx.fragment.app.Fragment;
import me.yokeyword.swipebackfragment.SwipeBackFragment;
diff --git a/app/src/main/java/me/yokeyword/swipebackfragment/sample/MainActivity.java b/app/src/main/java/me/yokeyword/swipebackfragment/sample/MainActivity.java
index 4c70cde..caf28f6 100644
--- a/app/src/main/java/me/yokeyword/swipebackfragment/sample/MainActivity.java
+++ b/app/src/main/java/me/yokeyword/swipebackfragment/sample/MainActivity.java
@@ -1,9 +1,9 @@
package me.yokeyword.swipebackfragment.sample;
import android.os.Bundle;
-import android.support.v4.app.Fragment;
import android.widget.Toast;
+import androidx.fragment.app.Fragment;
import me.yokeyword.swipebackfragment.SwipeBackActivity;
import me.yokeyword.swipebackfragment.sample.fragment.FirstSwipeBackFragment;
diff --git a/app/src/main/java/me/yokeyword/swipebackfragment/sample/PagerAdapter.java b/app/src/main/java/me/yokeyword/swipebackfragment/sample/PagerAdapter.java
index 577b798..7461671 100644
--- a/app/src/main/java/me/yokeyword/swipebackfragment/sample/PagerAdapter.java
+++ b/app/src/main/java/me/yokeyword/swipebackfragment/sample/PagerAdapter.java
@@ -1,7 +1,6 @@
package me.yokeyword.swipebackfragment.sample;
import android.content.Context;
-import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -10,6 +9,8 @@
import java.util.ArrayList;
import java.util.List;
+import androidx.recyclerview.widget.RecyclerView;
+
/**
* Created by YoKeyword on 16/4/21.
diff --git a/app/src/main/java/me/yokeyword/swipebackfragment/sample/fragment/FirstSwipeBackFragment.java b/app/src/main/java/me/yokeyword/swipebackfragment/sample/fragment/FirstSwipeBackFragment.java
index bfa0d7f..41487cb 100644
--- a/app/src/main/java/me/yokeyword/swipebackfragment/sample/fragment/FirstSwipeBackFragment.java
+++ b/app/src/main/java/me/yokeyword/swipebackfragment/sample/fragment/FirstSwipeBackFragment.java
@@ -1,8 +1,8 @@
package me.yokeyword.swipebackfragment.sample.fragment;
import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v7.widget.Toolbar;
+import androidx.annotation.Nullable;
+import androidx.appcompat.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
diff --git a/app/src/main/java/me/yokeyword/swipebackfragment/sample/fragment/RecyclerSwipeBackFragment.java b/app/src/main/java/me/yokeyword/swipebackfragment/sample/fragment/RecyclerSwipeBackFragment.java
index 6882a8a..723e77b 100644
--- a/app/src/main/java/me/yokeyword/swipebackfragment/sample/fragment/RecyclerSwipeBackFragment.java
+++ b/app/src/main/java/me/yokeyword/swipebackfragment/sample/fragment/RecyclerSwipeBackFragment.java
@@ -1,9 +1,8 @@
package me.yokeyword.swipebackfragment.sample.fragment;
+import androidx.appcompat.widget.Toolbar;
+
import android.os.Bundle;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -11,6 +10,8 @@
import java.util.ArrayList;
import java.util.List;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
import me.yokeyword.swipebackfragment.sample.BaseSwipeBackFragment;
import me.yokeyword.swipebackfragment.sample.PagerAdapter;
import me.yokeyword.swipebackfragment.sample.R;
diff --git a/app/src/main/java/me/yokeyword/swipebackfragment/sample/fragment/SecondSwipeBackFragment.java b/app/src/main/java/me/yokeyword/swipebackfragment/sample/fragment/SecondSwipeBackFragment.java
index 577bbac..53d4213 100644
--- a/app/src/main/java/me/yokeyword/swipebackfragment/sample/fragment/SecondSwipeBackFragment.java
+++ b/app/src/main/java/me/yokeyword/swipebackfragment/sample/fragment/SecondSwipeBackFragment.java
@@ -1,10 +1,10 @@
package me.yokeyword.swipebackfragment.sample.fragment;
import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v4.view.GravityCompat;
-import android.support.v7.widget.PopupMenu;
-import android.support.v7.widget.Toolbar;
+import androidx.annotation.Nullable;
+import androidx.core.view.GravityCompat;
+import androidx.appcompat.widget.PopupMenu;
+import androidx.appcompat.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
diff --git a/app/src/main/java/me/yokeyword/swipebackfragment/sample/fragment/ThirdSwipeBackFragment.java b/app/src/main/java/me/yokeyword/swipebackfragment/sample/fragment/ThirdSwipeBackFragment.java
index 1403880..d502409 100644
--- a/app/src/main/java/me/yokeyword/swipebackfragment/sample/fragment/ThirdSwipeBackFragment.java
+++ b/app/src/main/java/me/yokeyword/swipebackfragment/sample/fragment/ThirdSwipeBackFragment.java
@@ -1,10 +1,10 @@
package me.yokeyword.swipebackfragment.sample.fragment;
import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v4.view.GravityCompat;
-import android.support.v7.widget.PopupMenu;
-import android.support.v7.widget.Toolbar;
+import androidx.annotation.Nullable;
+import androidx.core.view.GravityCompat;
+import androidx.appcompat.widget.PopupMenu;
+import androidx.appcompat.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
diff --git a/app/src/main/res/layout/fragment_swipe_back_recy.xml b/app/src/main/res/layout/fragment_swipe_back_recy.xml
index e04ac46..614689a 100644
--- a/app/src/main/res/layout/fragment_swipe_back_recy.xml
+++ b/app/src/main/res/layout/fragment_swipe_back_recy.xml
@@ -7,7 +7,7 @@
-
diff --git a/app/src/main/res/layout/toolbar.xml b/app/src/main/res/layout/toolbar.xml
index ada3ca3..5c5e295 100644
--- a/app/src/main/res/layout/toolbar.xml
+++ b/app/src/main/res/layout/toolbar.xml
@@ -1,5 +1,5 @@
- {
+ val background = windowBackground
+ view.setBackgroundResource(background)
+ }
+ else -> view.setBackgroundResource(defaultBg)
+ }
+ }
+ }
+
+ override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? = if (mLocking) {
+ mNoAnim
+ } else super.onCreateAnimation(transit, enter, nextAnim)
+
+ fun setSwipeBackEnable(enable: Boolean) {
+ swipeBackLayout!!.setEnableGesture(enable)
+ }
+
+ companion object {
+ private const val SWIPEBACKFRAGMENT_STATE_SAVE_IS_HIDDEN = "SWIPEBACKFRAGMENT_STATE_SAVE_IS_HIDDEN"
+ }
+}
diff --git a/swipeback/src/main/java/me/yokeyword/swipebackfragment/SwipeBackLayout.java b/swipeback/src/main/java/me/yokeyword/swipebackfragment/SwipeBackLayout.java
deleted file mode 100644
index a0dd626..0000000
--- a/swipeback/src/main/java/me/yokeyword/swipebackfragment/SwipeBackLayout.java
+++ /dev/null
@@ -1,510 +0,0 @@
-package me.yokeyword.swipebackfragment;
-
-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.annotation.IntDef;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentActivity;
-import android.support.v4.view.ViewCompat;
-import android.support.v4.widget.ViewDragHelper;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.widget.FrameLayout;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.List;
-
-
-/**
- * Thx https://github.com/ikew0ng/SwipeBackLayout
- * SwipeBackLayout
- * Created by YoKeyword on 16/4/19.
- */
-public class SwipeBackLayout extends FrameLayout {
- /**
- * Edge flag indicating that the left edge should be affected.
- */
- public static final int EDGE_LEFT = ViewDragHelper.EDGE_LEFT;
-
- /**
- * Edge flag indicating that the right edge should be affected.
- */
- public static final int EDGE_RIGHT = ViewDragHelper.EDGE_RIGHT;
-
- public static final int EDGE_ALL = EDGE_LEFT | EDGE_RIGHT;
-
-
- /**
- * A view is not currently being dragged or animating as a result of a
- * fling/snap.
- */
- public static final int STATE_IDLE = ViewDragHelper.STATE_IDLE;
-
- /**
- * 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;
-
- private static final int DEFAULT_SCRIM_COLOR = 0x99000000;
- private static final int FULL_ALPHA = 255;
- private static final float DEFAULT_SCROLL_THRESHOLD = 0.4f;
- private static final int OVERSCROLL_DISTANCE = 10;
-
- private float mScrollFinishThreshold = DEFAULT_SCROLL_THRESHOLD;
-
- private ViewDragHelper mHelper;
-
- private float mScrollPercent;
- private float mScrimOpacity;
-
- private FragmentActivity mActivity;
- private View mContentView;
- private SwipeBackFragment mFragment;
- private Fragment mPreFragment;
-
- private Drawable mShadowLeft;
- private Drawable mShadowRight;
- private Rect mTmpRect = new Rect();
-
- private int mEdgeFlag;
- private boolean mEnable = true;
- private int mCurrentSwipeOrientation;
-
- private Context context;
- private EdgeLevel edgeLevel;
-
- public enum EdgeLevel {
- MAX, MIN, MED
- }
-
- /**
- * The set of listeners to be sent events through.
- */
- private List mListeners;
-
- public SwipeBackLayout(Context context) {
- this(context, null);
- }
-
- public SwipeBackLayout(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public SwipeBackLayout(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- this.context = context;
- init();
- }
-
- private void init() {
- mHelper = ViewDragHelper.create(this, new ViewDragCallback());
- setShadow(R.drawable.shadow_left, EDGE_LEFT);
- setEdgeOrientation(EDGE_LEFT);
- }
-
- /**
- * 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");
- }
- mScrollFinishThreshold = threshold;
- }
-
- /**
- * Enable edge tracking for the selected edges of the parent view.
- * The callback's {@link ViewDragHelper.Callback#onEdgeTouched(int, int)} and
- * {@link ViewDragHelper.Callback#onEdgeDragStarted(int, int)} methods will only be invoked
- * for edges for which edge tracking has been enabled.
- *
- * @param orientation Combination of edge flags describing the edges to watch
- * @see #EDGE_LEFT
- * @see #EDGE_RIGHT
- */
- public void setEdgeOrientation(int orientation) {
- mEdgeFlag = orientation;
- mHelper.setEdgeTrackingEnabled(orientation);
-
- if (orientation == EDGE_RIGHT || orientation == EDGE_ALL) {
- setShadow(R.drawable.shadow_right, EDGE_RIGHT);
- }
- }
-
- public void setEdgeLevel(EdgeLevel edgeLevel) {
- this.edgeLevel = edgeLevel;
- validateEdgeLevel(0, edgeLevel);
- }
-
- public void setEdgeLevel(int widthPixel) {
- validateEdgeLevel(widthPixel, null);
- }
-
- public EdgeLevel getEdgeLevel() {
- return edgeLevel;
- }
-
- private void validateEdgeLevel(int widthPixel, EdgeLevel edgeLevel) {
- try {
- DisplayMetrics metrics = new DisplayMetrics();
- WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
- windowManager.getDefaultDisplay().getMetrics(metrics);
- Field mEdgeSize = mHelper.getClass().getDeclaredField("mEdgeSize");
- mEdgeSize.setAccessible(true);
- if (widthPixel != 0) {
- mEdgeSize.setInt(mHelper, widthPixel);
- } else {
- if (edgeLevel == EdgeLevel.MAX) {
- mEdgeSize.setInt(mHelper, metrics.widthPixels);
- } else if (edgeLevel == EdgeLevel.MED) {
- mEdgeSize.setInt(mHelper, metrics.widthPixels / 2);
- } else if (edgeLevel == EdgeLevel.MIN) {
- mEdgeSize.setInt(mHelper, ((int) (20 * metrics.density + 0.5f)));
- }
- }
- } catch (NoSuchFieldException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- }
- }
-
- @IntDef({EDGE_LEFT, EDGE_RIGHT, EDGE_ALL})
- @Retention(RetentionPolicy.SOURCE)
- public @interface EdgeOrientation {
- }
-
- /**
- * Set a drawable used for edge shadow.
- */
- public void setShadow(Drawable shadow, int edgeFlag) {
- if ((edgeFlag & EDGE_LEFT) != 0) {
- mShadowLeft = shadow;
- } else if ((edgeFlag & EDGE_RIGHT) != 0) {
- mShadowRight = shadow;
- }
- invalidate();
- }
-
- /**
- * Set a drawable used for edge shadow.
- */
- public void setShadow(int resId, int edgeFlag) {
- setShadow(getResources().getDrawable(resId), edgeFlag);
- }
-
- /**
- * 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(OnSwipeListener listener) {
- if (mListeners == null) {
- mListeners = new ArrayList<>();
- }
- mListeners.add(listener);
- }
-
- /**
- * Removes a listener from the set of listeners
- *
- * @param listener
- */
- public void removeSwipeListener(OnSwipeListener listener) {
- if (mListeners == null) {
- return;
- }
- mListeners.remove(listener);
- }
-
- public interface OnSwipeListener {
- /**
- * Invoke when state change
- *
- * @param state flag to describe scroll state
- * @see #STATE_IDLE
- * @see #STATE_DRAGGING
- * @see #STATE_SETTLING
- */
- void onDragStateChange(int state);
-
- /**
- * Invoke when edge touched
- *
- * @param oritentationEdgeFlag edge flag describing the edge being touched
- * @see #EDGE_LEFT
- * @see #EDGE_RIGHT
- */
- void onEdgeTouch(int oritentationEdgeFlag);
-
- /**
- * Invoke when scroll percent over the threshold for the first time
- *
- * @param scrollPercent scroll percent of this view
- */
- void onDragScrolled(float scrollPercent);
- }
-
- @Override
- protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
- boolean isDrawView = child == mContentView;
- boolean drawChild = super.drawChild(canvas, child, drawingTime);
- if (isDrawView && mScrimOpacity > 0 && mHelper.getViewDragState() != ViewDragHelper.STATE_IDLE) {
- drawShadow(canvas, child);
- drawScrim(canvas, child);
- }
- return drawChild;
- }
-
- private void drawShadow(Canvas canvas, View child) {
- final Rect childRect = mTmpRect;
- child.getHitRect(childRect);
-
- if ((mCurrentSwipeOrientation & EDGE_LEFT) != 0) {
- mShadowLeft.setBounds(childRect.left - mShadowLeft.getIntrinsicWidth(), childRect.top, childRect.left, childRect.bottom);
- mShadowLeft.setAlpha((int) (mScrimOpacity * FULL_ALPHA));
- mShadowLeft.draw(canvas);
- } else if ((mCurrentSwipeOrientation & EDGE_RIGHT) != 0) {
- mShadowRight.setBounds(childRect.right, childRect.top, childRect.right + mShadowRight.getIntrinsicWidth(), childRect.bottom);
- mShadowRight.setAlpha((int) (mScrimOpacity * FULL_ALPHA));
- mShadowRight.draw(canvas);
- }
- }
-
- private void drawScrim(Canvas canvas, View child) {
- final int baseAlpha = (DEFAULT_SCRIM_COLOR & 0xff000000) >>> 24;
- final int alpha = (int) (baseAlpha * mScrimOpacity);
- final int color = alpha << 24;
-
- if ((mCurrentSwipeOrientation & EDGE_LEFT) != 0) {
- canvas.clipRect(0, 0, child.getLeft(), getHeight());
- } else if ((mCurrentSwipeOrientation & EDGE_RIGHT) != 0) {
- canvas.clipRect(child.getRight(), 0, getRight(), getHeight());
- }
- canvas.drawColor(color);
- }
-
- @Override
- public void computeScroll() {
- mScrimOpacity = 1 - mScrollPercent;
- if (mScrimOpacity >= 0) {
- if (mHelper.continueSettling(true)) {
- ViewCompat.postInvalidateOnAnimation(this);
- }
- }
- }
-
- public void setFragment(SwipeBackFragment fragment, View view) {
- this.mFragment = fragment;
- mContentView = view;
- }
-
- public void hiddenFragment() {
- if (mPreFragment != null && mPreFragment.getView() != null) {
- mPreFragment.getView().setVisibility(GONE);
- }
- }
-
- public void attachToActivity(FragmentActivity activity) {
- 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();
- ViewGroup decorChild = (ViewGroup) decor.getChildAt(0);
- decorChild.setBackgroundResource(background);
- decor.removeView(decorChild);
- addView(decorChild);
- setContentView(decorChild);
- decor.addView(this);
- }
-
- public void attachToFragment(SwipeBackFragment swipeBackFragment, View view) {
- addView(view);
- setFragment(swipeBackFragment, view);
- }
-
- private void setContentView(View view) {
- mContentView = view;
- }
-
- public void setEnableGesture(boolean enable) {
- mEnable = enable;
- }
-
- class ViewDragCallback extends ViewDragHelper.Callback {
-
- @Override
- public boolean tryCaptureView(View child, int pointerId) {
- boolean dragEnable = mHelper.isEdgeTouched(mEdgeFlag, pointerId);
- if (dragEnable) {
- if (mHelper.isEdgeTouched(EDGE_LEFT, pointerId)) {
- mCurrentSwipeOrientation = EDGE_LEFT;
- } else if (mHelper.isEdgeTouched(EDGE_RIGHT, pointerId)) {
- mCurrentSwipeOrientation = EDGE_RIGHT;
- }
-
- if (mListeners != null && !mListeners.isEmpty()) {
- for (OnSwipeListener listener : mListeners) {
- listener.onEdgeTouch(mCurrentSwipeOrientation);
- }
- }
-
- if (mPreFragment == null) {
- if (mFragment != null) {
- List fragmentList = mFragment.getFragmentManager().getFragments();
- if (fragmentList != null && fragmentList.size() > 1) {
- int index = fragmentList.indexOf(mFragment);
- for (int i = index - 1; i >= 0; i--) {
- Fragment fragment = fragmentList.get(i);
- if (fragment != null && fragment.getView() != null) {
- fragment.getView().setVisibility(VISIBLE);
- mPreFragment = fragment;
- break;
- }
- }
- }
- }
- } else {
- View preView = mPreFragment.getView();
- if (preView != null && preView.getVisibility() != VISIBLE) {
- preView.setVisibility(VISIBLE);
- }
- }
- }
- return dragEnable;
- }
-
- @Override
- public int clampViewPositionHorizontal(View child, int left, int dx) {
- int ret = 0;
- if ((mCurrentSwipeOrientation & EDGE_LEFT) != 0) {
- ret = Math.min(child.getWidth(), Math.max(left, 0));
- } else if ((mCurrentSwipeOrientation & EDGE_RIGHT) != 0) {
- ret = Math.min(0, Math.max(left, -child.getWidth()));
- }
- return ret;
- }
-
- @Override
- public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
- super.onViewPositionChanged(changedView, left, top, dx, dy);
- if ((mCurrentSwipeOrientation & EDGE_LEFT) != 0) {
- mScrollPercent = Math.abs((float) left / (getWidth() + mShadowLeft.getIntrinsicWidth()));
- } else if ((mCurrentSwipeOrientation & EDGE_RIGHT) != 0) {
- mScrollPercent = Math.abs((float) left / (mContentView.getWidth() + mShadowRight.getIntrinsicWidth()));
- }
- invalidate();
-
- if (mListeners != null && !mListeners.isEmpty()
- && mHelper.getViewDragState() == STATE_DRAGGING && mScrollPercent <= 1 && mScrollPercent > 0) {
- for (OnSwipeListener listener : mListeners) {
- listener.onDragScrolled(mScrollPercent);
- }
- }
-
- if (mScrollPercent > 1) {
- if (mFragment != null) {
- if (mPreFragment instanceof SwipeBackFragment) {
- ((SwipeBackFragment) mPreFragment).mLocking = true;
- }
- if (!mFragment.isDetached()) {
- mFragment.mLocking = true;
- mFragment.getFragmentManager().popBackStackImmediate();
- mFragment.mLocking = false;
- }
- if (mPreFragment instanceof SwipeBackFragment) {
- ((SwipeBackFragment) mPreFragment).mLocking = false;
- }
- } else {
- if (!mActivity.isFinishing()) {
- mActivity.finish();
- mActivity.overridePendingTransition(0, 0);
- }
- }
- }
- }
-
- @Override
- public int getViewHorizontalDragRange(View child) {
- if (mFragment != null) {
- return 1;
- } else if (mActivity != null && ((SwipeBackActivity) mActivity).swipeBackPriority()) {
- return 1;
- }
-
- return 0;
- }
-
- @Override
- public void onViewReleased(View releasedChild, float xvel, float yvel) {
- final int childWidth = releasedChild.getWidth();
-
- int left = 0, top = 0;
- if ((mCurrentSwipeOrientation & EDGE_LEFT) != 0) {
- left = xvel > 0 || xvel == 0 && mScrollPercent > mScrollFinishThreshold ? (childWidth
- + mShadowLeft.getIntrinsicWidth() + OVERSCROLL_DISTANCE) : 0;
- } else if ((mCurrentSwipeOrientation & EDGE_RIGHT) != 0) {
- left = xvel < 0 || xvel == 0 && mScrollPercent > mScrollFinishThreshold ? -(childWidth
- + mShadowRight.getIntrinsicWidth() + OVERSCROLL_DISTANCE) : 0;
- }
-
- mHelper.settleCapturedViewAt(left, top);
- invalidate();
- }
-
- @Override
- public void onViewDragStateChanged(int state) {
- super.onViewDragStateChanged(state);
- if (mListeners != null && !mListeners.isEmpty()) {
- for (OnSwipeListener listener : mListeners) {
- listener.onDragStateChange(state);
- }
- }
- }
-
- @Override
- public void onEdgeTouched(int edgeFlags, int pointerId) {
- super.onEdgeTouched(edgeFlags, pointerId);
- if ((mEdgeFlag & edgeFlags) != 0) {
- mCurrentSwipeOrientation = edgeFlags;
- }
- }
-
- }
-
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- if (!mEnable) return super.onInterceptTouchEvent(ev);
- return mHelper.shouldInterceptTouchEvent(ev);
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (!mEnable) return super.onTouchEvent(event);
- mHelper.processTouchEvent(event);
- return true;
- }
-}
\ No newline at end of file
diff --git a/swipeback/src/main/java/me/yokeyword/swipebackfragment/SwipeBackLayout.kt b/swipeback/src/main/java/me/yokeyword/swipebackfragment/SwipeBackLayout.kt
new file mode 100644
index 0000000..221f92a
--- /dev/null
+++ b/swipeback/src/main/java/me/yokeyword/swipebackfragment/SwipeBackLayout.kt
@@ -0,0 +1,450 @@
+package me.yokeyword.swipebackfragment
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.graphics.Canvas
+import android.graphics.Rect
+import android.graphics.drawable.Drawable
+import androidx.annotation.IntDef
+import androidx.core.view.ViewCompat
+import androidx.customview.widget.ViewDragHelper
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.FragmentActivity
+
+import android.util.AttributeSet
+import android.util.DisplayMetrics
+import android.view.MotionEvent
+import android.view.View
+import android.view.ViewGroup
+import android.view.WindowManager
+import android.widget.FrameLayout
+import kotlin.annotation.Retention
+import java.lang.annotation.RetentionPolicy
+import java.util.ArrayList
+
+
+/**
+ * Thx https://github.com/ikew0ng/SwipeBackLayout
+ * SwipeBackLayout
+ * Created by YoKeyword on 16/4/19.
+ */
+open class SwipeBackLayout : FrameLayout {
+
+ constructor(appContext: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0):super(appContext, attrs, defStyleAttr)
+ constructor(appContext: Context):super(appContext)
+
+ private var mScrollFinishThreshold = DEFAULT_SCROLL_THRESHOLD
+
+ private var mHelper: ViewDragHelper? = null
+
+ private var mScrollPercent: Float = 0.toFloat()
+ private var mScrimOpacity: Float = 0.toFloat()
+
+ private var mActivity: FragmentActivity? = null
+ private var mContentView: View? = null
+ private var mFragment: SwipeBackFragment? = null
+ private var mPreFragment: Fragment? = null
+
+ private var mShadowLeft: Drawable? = null
+ private var mShadowRight: Drawable? = null
+ private val mTmpRect = Rect()
+
+ private var mEdgeFlag: Int = 0
+ private var mEnable = true
+ private var mCurrentSwipeOrientation: Int = 0
+ var edgeLevel: EdgeLevel? = null
+ set(edgeLevel) {
+ field = edgeLevel
+ validateEdgeLevel(0, edgeLevel)
+ }
+
+ /**
+ * The set of listeners to be sent events through.
+ */
+ private var mListeners: MutableList? = null
+
+ enum class EdgeLevel {
+ MAX, MIN, MED
+ }
+
+ init {
+ mHelper = ViewDragHelper.create(this, ViewDragCallback())
+ setShadow(R.drawable.shadow_left, EDGE_LEFT)
+ setEdgeOrientation(EDGE_LEFT)
+ }
+
+ /**
+ * Set scroll threshold, we will close the activity, when scrollPercent over
+ * this value
+ *
+ * @param threshold
+ */
+ fun setScrollThresHold(threshold: Float) {
+ if (threshold >= 1.0f || threshold <= 0)
+ throw IllegalArgumentException("Threshold value should be between 0 and 1.0")
+ mScrollFinishThreshold = threshold
+ }
+
+ /**
+ * Enable edge tracking for the selected edges of the parent view.
+ * The callback's [ViewDragHelper.Callback.onEdgeTouched] and
+ * [ViewDragHelper.Callback.onEdgeDragStarted] methods will only be invoked
+ * for edges for which edge tracking has been enabled.
+ *
+ * @param orientation Combination of edge flags describing the edges to watch
+ * @see .EDGE_LEFT
+ *
+ * @see .EDGE_RIGHT
+ */
+ fun setEdgeOrientation(orientation: Int) {
+ mEdgeFlag = orientation
+ mHelper!!.setEdgeTrackingEnabled(orientation)
+ if (orientation == EDGE_RIGHT || orientation == EDGE_ALL)
+ setShadow(R.drawable.shadow_right, EDGE_RIGHT)
+ }
+
+ fun setEdgeLevel(widthPixel: Int) {
+ validateEdgeLevel(widthPixel, null)
+ }
+
+ private fun validateEdgeLevel(widthPixel: Int, edgeLevel: EdgeLevel?) {
+ try {
+ val metrics = DisplayMetrics()
+ val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
+ windowManager.defaultDisplay.getMetrics(metrics)
+ val mEdgeSize = mHelper!!.javaClass.getDeclaredField("mEdgeSize")
+ mEdgeSize.isAccessible = true
+ if (widthPixel != 0) {
+ mEdgeSize.setInt(mHelper, widthPixel)
+ } else when (edgeLevel) {
+ EdgeLevel.MAX -> mEdgeSize.setInt(mHelper, metrics.widthPixels)
+ EdgeLevel.MED -> mEdgeSize.setInt(mHelper, metrics.widthPixels / 2)
+ EdgeLevel.MIN -> mEdgeSize.setInt(mHelper, (20 * metrics.density + 0.5f).toInt())
+ }
+ } catch (e: NoSuchFieldException) {
+ e.printStackTrace()
+ } catch (e: IllegalAccessException) {
+ e.printStackTrace()
+ }
+
+ }
+
+ @IntDef(EDGE_LEFT, EDGE_RIGHT, EDGE_ALL)
+ @Retention(AnnotationRetention.SOURCE)
+ annotation class EdgeOrientation
+
+ /**
+ * Set a drawable used for edge shadow.
+ */
+ fun setShadow(shadow: Drawable, edgeFlag: Int) {
+ when {
+ edgeFlag and EDGE_LEFT != 0 -> mShadowLeft = shadow
+ edgeFlag and EDGE_RIGHT != 0 -> mShadowRight = shadow
+ }
+ invalidate()
+ }
+
+ /**
+ * Set a drawable used for edge shadow.
+ */
+ fun setShadow(resId: Int, edgeFlag: Int) {
+ setShadow(resources.getDrawable(resId), edgeFlag)
+ }
+
+ /**
+ * 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
+ */
+ open fun addSwipeListener(listener: OnSwipeListener) {
+ if (mListeners == null) mListeners = ArrayList()
+ mListeners!!.add(listener)
+ }
+
+ /**
+ * Removes a listener from the set of listeners
+ *
+ * @param listener
+ */
+ open fun removeSwipeListener(listener: OnSwipeListener) {
+ if (mListeners == null) return
+ mListeners!!.remove(listener)
+ }
+
+ interface OnSwipeListener {
+ /**
+ * Invoke when state change
+ *
+ * @param state flag to describe scroll state
+ * @see .STATE_IDLE
+ *
+ * @see .STATE_DRAGGING
+ *
+ * @see .STATE_SETTLING
+ */
+ fun onDragStateChange(state: Int)
+
+ /**
+ * Invoke when edge touched
+ *
+ * @param oritentationEdgeFlag edge flag describing the edge being touched
+ * @see .EDGE_LEFT
+ *
+ * @see .EDGE_RIGHT
+ */
+ fun onEdgeTouch(oritentationEdgeFlag: Int)
+
+ /**
+ * Invoke when scroll percent over the threshold for the first time
+ *
+ * @param scrollPercent scroll percent of this view
+ */
+ fun onDragScrolled(scrollPercent: Float)
+ }
+
+ override fun drawChild(canvas: Canvas, child: View, drawingTime: Long): Boolean {
+ val isDrawView = child === mContentView
+ val drawChild = super.drawChild(canvas, child, drawingTime)
+ if (isDrawView && mScrimOpacity > 0 && mHelper!!.viewDragState != ViewDragHelper.STATE_IDLE) {
+ drawShadow(canvas, child)
+ drawScrim(canvas, child)
+ }
+ return drawChild
+ }
+
+ private fun drawShadow(canvas: Canvas, child: View) {
+ val childRect = mTmpRect
+ child.getHitRect(childRect)
+ when {
+ mCurrentSwipeOrientation and EDGE_LEFT != 0 -> {
+ mShadowLeft!!.setBounds(childRect.left - mShadowLeft!!.intrinsicWidth, childRect.top, childRect.left, childRect.bottom)
+ mShadowLeft!!.alpha = (mScrimOpacity * FULL_ALPHA).toInt()
+ mShadowLeft!!.draw(canvas)
+ }
+ mCurrentSwipeOrientation and EDGE_RIGHT != 0 -> {
+ mShadowRight!!.setBounds(childRect.right, childRect.top, childRect.right + mShadowRight!!.intrinsicWidth, childRect.bottom)
+ mShadowRight!!.alpha = (mScrimOpacity * FULL_ALPHA).toInt()
+ mShadowRight!!.draw(canvas)
+ }
+ }
+ }
+
+ private fun drawScrim(canvas: Canvas, child: View) {
+ val baseAlpha = (DEFAULT_SCRIM_COLOR and -0x1000000).ushr(24)
+ val alpha = (baseAlpha * mScrimOpacity).toInt()
+ val color = alpha shl 24
+ when {
+ mCurrentSwipeOrientation and EDGE_LEFT != 0 -> canvas.clipRect(0, 0, child.left, height)
+ mCurrentSwipeOrientation and EDGE_RIGHT != 0 -> canvas.clipRect(child.right, 0, right, height)
+ }
+ canvas.drawColor(color)
+ }
+
+ override fun computeScroll() {
+ mScrimOpacity = 1 - mScrollPercent
+ if (mScrimOpacity >= 0 && mHelper!!.continueSettling(true)) {
+ ViewCompat.postInvalidateOnAnimation(this)
+ }
+ }
+
+ open fun setFragment(fragment: SwipeBackFragment, view: View) {
+ this.mFragment = fragment
+ mContentView = view
+ }
+
+ open fun hiddenFragment() {
+ when {
+ mPreFragment != null && mPreFragment!!.view != null -> mPreFragment!!.view!!.visibility = View.GONE
+ }
+ }
+
+ fun attachToActivity(activity: FragmentActivity) {
+ mActivity = 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
+ val decorChild = decor.getChildAt(0) as ViewGroup
+ decorChild.setBackgroundResource(background)
+ decor.removeView(decorChild)
+ addView(decorChild)
+ setContentView(decorChild)
+ decor.addView(this)
+ }
+
+ fun attachToFragment(swipeBackFragment: SwipeBackFragment, view: View) {
+ addView(view)
+ setFragment(swipeBackFragment, view)
+ }
+
+ private fun setContentView(view: View) {
+ mContentView = view
+ }
+
+ fun setEnableGesture(enable: Boolean) {
+ mEnable = enable
+ }
+
+ internal inner class ViewDragCallback : ViewDragHelper.Callback() {
+
+ override fun tryCaptureView(child: View, pointerId: Int): Boolean {
+ val dragEnable = mHelper!!.isEdgeTouched(mEdgeFlag, pointerId)
+ if (dragEnable) {
+ when {
+ mHelper!!.isEdgeTouched(EDGE_LEFT, pointerId) -> mCurrentSwipeOrientation = EDGE_LEFT
+ mHelper!!.isEdgeTouched(EDGE_RIGHT, pointerId) -> mCurrentSwipeOrientation = EDGE_RIGHT
+ }
+
+ if (mListeners != null && !mListeners!!.isEmpty()) for (listener in mListeners!!)
+ listener.onEdgeTouch(mCurrentSwipeOrientation)
+
+ if (mPreFragment == null) when {
+ mFragment != null -> {
+ val fragmentList = mFragment!!.fragmentManager!!.fragments
+ if (fragmentList.size > 1) {
+ val index = fragmentList.indexOf(mFragment)
+ for (i in index - 1 downTo 0) {
+ val fragment = fragmentList[i]
+ if (fragment != null && fragment.view != null) {
+ fragment.view!!.visibility = View.VISIBLE
+ mPreFragment = fragment
+ break
+ }
+ }
+ }
+ }
+ }
+ else {
+ val preView = mPreFragment!!.view
+ if (preView != null && preView.visibility != View.VISIBLE)
+ preView.visibility = View.VISIBLE
+ }
+ }
+ return dragEnable
+ }
+
+ override fun clampViewPositionHorizontal(child: View, left: Int, dx: Int): Int {
+ var ret = 0
+ when {
+ mCurrentSwipeOrientation and EDGE_LEFT != 0 -> ret = Math.min(child.width, Math.max(left, 0))
+ mCurrentSwipeOrientation and EDGE_RIGHT != 0 -> ret = Math.min(0, Math.max(left, -child.width))
+ }
+ return ret
+ }
+
+ override fun onViewPositionChanged(changedView: View, left: Int, top: Int, dx: Int, dy: Int) {
+ super.onViewPositionChanged(changedView, left, top, dx, dy)
+ when {
+ mCurrentSwipeOrientation and EDGE_LEFT != 0 -> mScrollPercent = Math.abs(left.toFloat() / (width + mShadowLeft!!.intrinsicWidth))
+ mCurrentSwipeOrientation and EDGE_RIGHT != 0 -> mScrollPercent = Math.abs(left.toFloat() / (mContentView!!.width + mShadowRight!!.intrinsicWidth))
+ }
+ invalidate()
+
+ if (mListeners != null && !mListeners!!.isEmpty() && mHelper!!.viewDragState == STATE_DRAGGING && mScrollPercent <= 1 && mScrollPercent > 0) for (listener in mListeners!!)
+ listener.onDragScrolled(mScrollPercent)
+
+ if (mScrollPercent > 1) when {
+ mFragment != null -> {
+ if (mPreFragment is SwipeBackFragment)
+ (mPreFragment as SwipeBackFragment).mLocking = true
+ if (!mFragment!!.isDetached) {
+ mFragment!!.mLocking = true
+ mFragment!!.fragmentManager!!.popBackStackImmediate()
+ mFragment!!.mLocking = false
+ }
+ if (mPreFragment is SwipeBackFragment)
+ (mPreFragment as SwipeBackFragment).mLocking = false
+ }
+ else -> if (!mActivity!!.isFinishing) {
+ mActivity!!.finish()
+ mActivity!!.overridePendingTransition(0, 0)
+ }
+ }
+ }
+
+ override fun getViewHorizontalDragRange(child: View): Int = when {
+ mFragment != null -> 1
+ mActivity != null && (mActivity as SwipeBackActivity).swipeBackPriority() -> 1
+ else -> 0
+ }
+
+ override fun onViewReleased(releasedChild: View, xvel: Float, yvel: Float) {
+ val childWidth = releasedChild.width
+ var left = 0
+ val top = 0
+ when {
+ mCurrentSwipeOrientation and EDGE_LEFT != 0 -> left = if (xvel > 0 || xvel == 0f && mScrollPercent > mScrollFinishThreshold)
+ childWidth + mShadowLeft!!.intrinsicWidth + OVERSCROLL_DISTANCE
+ else 0
+ mCurrentSwipeOrientation and EDGE_RIGHT != 0 -> left = if (xvel < 0 || xvel == 0f && mScrollPercent > mScrollFinishThreshold)
+ -(childWidth + mShadowRight!!.intrinsicWidth + OVERSCROLL_DISTANCE)
+ else 0
+ }
+
+ mHelper!!.settleCapturedViewAt(left, top)
+ invalidate()
+ }
+
+ override fun onViewDragStateChanged(state: Int) {
+ super.onViewDragStateChanged(state)
+ if (mListeners != null && !mListeners!!.isEmpty()) for (listener in mListeners!!)
+ listener.onDragStateChange(state)
+ }
+
+ override fun onEdgeTouched(edgeFlags: Int, pointerId: Int) {
+ super.onEdgeTouched(edgeFlags, pointerId)
+ if (mEdgeFlag and edgeFlags != 0)
+ mCurrentSwipeOrientation = edgeFlags
+ }
+
+ }
+
+ override fun onInterceptTouchEvent(ev: MotionEvent): Boolean =
+ if (!mEnable) super.onInterceptTouchEvent(ev) else mHelper!!.shouldInterceptTouchEvent(ev)
+
+ @SuppressLint("ClickableViewAccessibility")
+ override fun onTouchEvent(event: MotionEvent): Boolean {
+ if (!mEnable) return super.onTouchEvent(event)
+ mHelper!!.processTouchEvent(event)
+ return true
+ }
+
+ companion object {
+ /**
+ * Edge flag indicating that the left edge should be affected.
+ */
+ const val EDGE_LEFT = ViewDragHelper.EDGE_LEFT
+
+ /**
+ * Edge flag indicating that the right edge should be affected.
+ */
+ const val EDGE_RIGHT = ViewDragHelper.EDGE_RIGHT
+
+ const val EDGE_ALL = EDGE_LEFT or EDGE_RIGHT
+
+
+ /**
+ * A view is not currently being dragged or animating as a result of a
+ * fling/snap.
+ */
+ val STATE_IDLE = ViewDragHelper.STATE_IDLE
+
+ /**
+ * A view is currently being dragged. The position is currently changing as
+ * a result of user input or simulated user input.
+ */
+ val STATE_DRAGGING = ViewDragHelper.STATE_DRAGGING
+
+ /**
+ * A view is currently settling into place as a result of a fling or
+ * predefined non-interactive motion.
+ */
+ val STATE_SETTLING = ViewDragHelper.STATE_SETTLING
+
+ private val DEFAULT_SCRIM_COLOR = -0x67000000
+ private val FULL_ALPHA = 255
+ private val DEFAULT_SCROLL_THRESHOLD = 0.4f
+ private val OVERSCROLL_DISTANCE = 10
+ }
+}
\ No newline at end of file