aboutsummaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorSergei Kozelko <KozelkoS@yandex.ru>2022-10-22 06:37:31 +0000
committerGitHub <noreply@github.com>2022-10-22 06:37:31 +0000
commit5e3eaafe268fc64e8c7d92187e6c2447addc410d (patch)
tree5f2f1a6aa77d1811083f95e32893d6b27384630d /app
parentd11fb884c26c739e9e919ec98c1a0990f0953c93 (diff)
downloadinfinity-for-reddit-5e3eaafe268fc64e8c7d92187e6c2447addc410d.tar
infinity-for-reddit-5e3eaafe268fc64e8c7d92187e6c2447addc410d.tar.gz
infinity-for-reddit-5e3eaafe268fc64e8c7d92187e6c2447addc410d.tar.bz2
infinity-for-reddit-5e3eaafe268fc64e8c7d92187e6c2447addc410d.tar.lz
infinity-for-reddit-5e3eaafe268fc64e8c7d92187e6c2447addc410d.tar.xz
infinity-for-reddit-5e3eaafe268fc64e8c7d92187e6c2447addc410d.tar.zst
infinity-for-reddit-5e3eaafe268fc64e8c7d92187e6c2447addc410d.zip
Add view that can lock swipe-to-close gesture (#1140)
Slidr works by adding its own view in the hierarchy and listening to touch events in `onInterceptTouchEvent`. Once it detects movement in the correct direction, it returns `true` and handles all the events itself. Adding scrollable view detection to Slidr would solve the problem, but it is not possible and would probably have performance impact. Fortunately Slidr does not intercept the very first event, which is ACTION_DOWN, and it reaches scrollable view. So the scrollable view itself can decide if it should disallow the swipe. This also has a performance benefit over `OnScrollChangedListener` because the listener is triggered for every scroll of every view even if the child we are interested in did not scroll. On the other hand `on(Intercept)TouchEvent` is triggered only when the view is touched. There is a possibility that swipe won't be unlocked if view never receives ACTION_UP or ACTION_CANCEL. However the docs say nothing about the probability of this happening. Anyways, one possible solution is to post a runnable that will unlock swipe soon after locking.
Diffstat (limited to 'app')
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java7
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/activities/WikiActivity.java7
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java7
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsRecyclerViewAdapter.java7
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PostDetailRecyclerViewAdapter.java7
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/adapters/RulesRecyclerViewAdapter.java7
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/customviews/MarkwonLinearLayoutManager.java32
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/customviews/SwipeLockScrollView.java78
-rw-r--r--app/src/main/res/layout/adapter_table_block.xml5
9 files changed, 114 insertions, 43 deletions
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java
index 782441dc..2ded838c 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java
@@ -42,6 +42,7 @@ import ml.docilealligator.infinityforreddit.R;
import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper;
import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed;
import ml.docilealligator.infinityforreddit.customviews.MarkwonLinearLayoutManager;
+import ml.docilealligator.infinityforreddit.customviews.SwipeLockScrollView;
import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent;
import ml.docilealligator.infinityforreddit.markdown.MarkdownUtils;
import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils;
@@ -150,16 +151,16 @@ public class FullMarkdownActivity extends BaseActivity {
miscPlugin, markdownColor, spoilerBackgroundColor, null);
MarkwonAdapter markwonAdapter = MarkdownUtils.createTablesAdapter();
- LinearLayoutManagerBugFixed linearLayoutManager = new MarkwonLinearLayoutManager(this, new MarkwonLinearLayoutManager.HorizontalScrollViewScrolledListener() {
+ LinearLayoutManagerBugFixed linearLayoutManager = new MarkwonLinearLayoutManager(this, new SwipeLockScrollView.SwipeLockInterface() {
@Override
- public void onScrolledLeft() {
+ public void lockSwipe() {
if (mSlidrInterface != null) {
mSlidrInterface.lock();
}
}
@Override
- public void onScrolledRight() {
+ public void unlockSwipe() {
if (mSlidrInterface != null) {
mSlidrInterface.unlock();
}
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/WikiActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/WikiActivity.java
index 8f8e902b..6cb65b28 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/WikiActivity.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/WikiActivity.java
@@ -51,6 +51,7 @@ import ml.docilealligator.infinityforreddit.bottomsheetfragments.UrlMenuBottomSh
import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper;
import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed;
import ml.docilealligator.infinityforreddit.customviews.MarkwonLinearLayoutManager;
+import ml.docilealligator.infinityforreddit.customviews.SwipeLockScrollView;
import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent;
import ml.docilealligator.infinityforreddit.markdown.MarkdownUtils;
import ml.docilealligator.infinityforreddit.utils.JSONUtils;
@@ -183,16 +184,16 @@ public class WikiActivity extends BaseActivity {
miscPlugin, markdownColor, spoilerBackgroundColor, onLinkLongClickListener);
markwonAdapter = MarkdownUtils.createTablesAdapter();
- LinearLayoutManagerBugFixed linearLayoutManager = new MarkwonLinearLayoutManager(this, new MarkwonLinearLayoutManager.HorizontalScrollViewScrolledListener() {
+ LinearLayoutManagerBugFixed linearLayoutManager = new MarkwonLinearLayoutManager(this, new SwipeLockScrollView.SwipeLockInterface() {
@Override
- public void onScrolledLeft() {
+ public void lockSwipe() {
if (mSlidrInterface != null) {
mSlidrInterface.lock();
}
}
@Override
- public void onScrolledRight() {
+ public void unlockSwipe() {
if (mSlidrInterface != null) {
mSlidrInterface.unlock();
}
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java
index 1782a0a4..1503a469 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java
@@ -55,6 +55,7 @@ import ml.docilealligator.infinityforreddit.customviews.CustomMarkwonAdapter;
import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed;
import ml.docilealligator.infinityforreddit.customviews.MarkwonLinearLayoutManager;
import ml.docilealligator.infinityforreddit.customviews.SpoilerOnClickTextView;
+import ml.docilealligator.infinityforreddit.customviews.SwipeLockScrollView;
import ml.docilealligator.infinityforreddit.markdown.MarkdownUtils;
import ml.docilealligator.infinityforreddit.utils.APIUtils;
import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils;
@@ -507,9 +508,9 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment
});
commentMarkdownView.setRecycledViewPool(recycledViewPool);
- LinearLayoutManagerBugFixed linearLayoutManager = new MarkwonLinearLayoutManager(mActivity, new MarkwonLinearLayoutManager.HorizontalScrollViewScrolledListener() {
+ LinearLayoutManagerBugFixed linearLayoutManager = new MarkwonLinearLayoutManager(mActivity, new SwipeLockScrollView.SwipeLockInterface() {
@Override
- public void onScrolledLeft() {
+ public void lockSwipe() {
if (mActivity instanceof AccountSavedThingActivity) {
((AccountSavedThingActivity) mActivity).lockSwipeRightToGoBack();
} else {
@@ -518,7 +519,7 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment
}
@Override
- public void onScrolledRight() {
+ public void unlockSwipe() {
if (mActivity instanceof AccountSavedThingActivity) {
((AccountSavedThingActivity) mActivity).unlockSwipeRightToGoBack();
} else {
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsRecyclerViewAdapter.java
index feaedc98..df2718cf 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsRecyclerViewAdapter.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsRecyclerViewAdapter.java
@@ -64,6 +64,7 @@ import ml.docilealligator.infinityforreddit.customviews.CustomMarkwonAdapter;
import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed;
import ml.docilealligator.infinityforreddit.customviews.MarkwonLinearLayoutManager;
import ml.docilealligator.infinityforreddit.customviews.SpoilerOnClickTextView;
+import ml.docilealligator.infinityforreddit.customviews.SwipeLockScrollView;
import ml.docilealligator.infinityforreddit.fragments.ViewPostDetailFragment;
import ml.docilealligator.infinityforreddit.markdown.MarkdownUtils;
import ml.docilealligator.infinityforreddit.post.Post;
@@ -1240,14 +1241,14 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVi
}
commentMarkdownView.setRecycledViewPool(recycledViewPool);
- LinearLayoutManagerBugFixed linearLayoutManager = new MarkwonLinearLayoutManager(mActivity, new MarkwonLinearLayoutManager.HorizontalScrollViewScrolledListener() {
+ LinearLayoutManagerBugFixed linearLayoutManager = new MarkwonLinearLayoutManager(mActivity, new SwipeLockScrollView.SwipeLockInterface() {
@Override
- public void onScrolledLeft() {
+ public void lockSwipe() {
((ViewPostDetailActivity) mActivity).lockSwipeRightToGoBack();
}
@Override
- public void onScrolledRight() {
+ public void unlockSwipe() {
((ViewPostDetailActivity) mActivity).unlockSwipeRightToGoBack();
}
});
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PostDetailRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PostDetailRecyclerViewAdapter.java
index 05deb6fb..9c9e4411 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PostDetailRecyclerViewAdapter.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PostDetailRecyclerViewAdapter.java
@@ -89,6 +89,7 @@ import ml.docilealligator.infinityforreddit.bottomsheetfragments.UrlMenuBottomSh
import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper;
import ml.docilealligator.infinityforreddit.customviews.AspectRatioGifImageView;
import ml.docilealligator.infinityforreddit.customviews.MarkwonLinearLayoutManager;
+import ml.docilealligator.infinityforreddit.customviews.SwipeLockScrollView;
import ml.docilealligator.infinityforreddit.fragments.ViewPostDetailFragment;
import ml.docilealligator.infinityforreddit.markdown.MarkdownUtils;
import ml.docilealligator.infinityforreddit.post.Post;
@@ -1194,14 +1195,14 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler
mActivity.startActivity(intent);
});
- mContentMarkdownView.setLayoutManager(new MarkwonLinearLayoutManager(mActivity, new MarkwonLinearLayoutManager.HorizontalScrollViewScrolledListener() {
+ mContentMarkdownView.setLayoutManager(new MarkwonLinearLayoutManager(mActivity, new SwipeLockScrollView.SwipeLockInterface() {
@Override
- public void onScrolledLeft() {
+ public void lockSwipe() {
((ViewPostDetailActivity) mActivity).lockSwipeRightToGoBack();
}
@Override
- public void onScrolledRight() {
+ public void unlockSwipe() {
((ViewPostDetailActivity) mActivity).unlockSwipeRightToGoBack();
}
}));
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/RulesRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/RulesRecyclerViewAdapter.java
index ad173262..c7d32b93 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/RulesRecyclerViewAdapter.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/RulesRecyclerViewAdapter.java
@@ -33,6 +33,7 @@ import ml.docilealligator.infinityforreddit.bottomsheetfragments.UrlMenuBottomSh
import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper;
import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed;
import ml.docilealligator.infinityforreddit.customviews.MarkwonLinearLayoutManager;
+import ml.docilealligator.infinityforreddit.customviews.SwipeLockScrollView;
import ml.docilealligator.infinityforreddit.markdown.MarkdownUtils;
import ml.docilealligator.infinityforreddit.utils.Utils;
@@ -146,16 +147,16 @@ public class RulesRecyclerViewAdapter extends RecyclerView.Adapter<RulesRecycler
}
markwonAdapter = MarkdownUtils.createTablesAdapter();
LinearLayoutManagerBugFixed linearLayoutManager = new MarkwonLinearLayoutManager(activity,
- new MarkwonLinearLayoutManager.HorizontalScrollViewScrolledListener() {
+ new SwipeLockScrollView.SwipeLockInterface() {
@Override
- public void onScrolledLeft() {
+ public void lockSwipe() {
if (slidrInterface != null) {
slidrInterface.lock();
}
}
@Override
- public void onScrolledRight() {
+ public void unlockSwipe() {
if (slidrInterface != null) {
slidrInterface.unlock();
}
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/MarkwonLinearLayoutManager.java b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/MarkwonLinearLayoutManager.java
index 35923fa6..73f904c5 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/MarkwonLinearLayoutManager.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/MarkwonLinearLayoutManager.java
@@ -2,39 +2,25 @@ package ml.docilealligator.infinityforreddit.customviews;
import android.content.Context;
import android.view.View;
-import android.view.ViewTreeObserver;
-import android.widget.HorizontalScrollView;
+
+import androidx.annotation.Nullable;
public class MarkwonLinearLayoutManager extends LinearLayoutManagerBugFixed {
- public interface HorizontalScrollViewScrolledListener {
- void onScrolledLeft();
- void onScrolledRight();
- }
- private HorizontalScrollViewScrolledListener horizontalScrollViewScrolledListener;
+ @Nullable
+ private final SwipeLockScrollView.SwipeLockInterface swipeLockInterface;
- public MarkwonLinearLayoutManager(Context context, HorizontalScrollViewScrolledListener horizontalScrollViewScrolledListener) {
+ public MarkwonLinearLayoutManager(Context context,
+ @Nullable SwipeLockScrollView.SwipeLockInterface swipeLockInterface) {
super(context);
- this.horizontalScrollViewScrolledListener = horizontalScrollViewScrolledListener;
+ this.swipeLockInterface = swipeLockInterface;
}
@Override
public void addView(View child) {
super.addView(child);
- if (child instanceof HorizontalScrollView) {
- child.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
- private int x = 0;
- @Override
- public void onScrollChanged() {
- if (child.getScrollX() < x) {
- horizontalScrollViewScrolledListener.onScrolledLeft();
- } else {
- horizontalScrollViewScrolledListener.onScrolledRight();
- }
-
- x = child.getScrollX();
- }
- });
+ if (child instanceof SwipeLockScrollView) {
+ ((SwipeLockScrollView) child).setSwipeLockInterface(swipeLockInterface);
}
}
}
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/SwipeLockScrollView.java b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/SwipeLockScrollView.java
new file mode 100644
index 00000000..4b5fc677
--- /dev/null
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/SwipeLockScrollView.java
@@ -0,0 +1,78 @@
+package ml.docilealligator.infinityforreddit.customviews;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.widget.HorizontalScrollView;
+
+import androidx.annotation.Nullable;
+
+/** {@link HorizontalScrollView} that listens for touch events and locks swipes
+ * if it can be scrolled to the right. {@link SwipeLockInterface} must be set for
+ * locking to work.
+ */
+public class SwipeLockScrollView extends HorizontalScrollView {
+ @Nullable
+ private SwipeLockInterface swipeLockInterface = null;
+ private boolean locked = false;
+
+ public SwipeLockScrollView(Context context) {
+ super(context);
+ }
+
+ public SwipeLockScrollView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public SwipeLockScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ public void setSwipeLockInterface(@Nullable SwipeLockInterface swipeLockInterface) {
+ this.swipeLockInterface = swipeLockInterface;
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ updateSwipeLock(ev);
+ return super.onInterceptTouchEvent(ev);
+ }
+
+ @SuppressLint("ClickableViewAccessibility") // we are just listening to touch events
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ updateSwipeLock(ev);
+ return super.onTouchEvent(ev);
+ }
+
+ /**
+ * Unlocks swipe if the view cannot be scrolled right anymore or if {@code ev} is
+ * {@link MotionEvent#ACTION_UP} or {@link MotionEvent#ACTION_CANCEL}
+ */
+ private void updateSwipeLock(MotionEvent ev) {
+ if (swipeLockInterface != null) {
+ int action = ev.getAction();
+ if (action == MotionEvent.ACTION_UP ||
+ action == MotionEvent.ACTION_CANCEL ||
+ getScrollX() == 0) {
+ // calling SlidrInterface#unlock aborts the swipe
+ // so don't call unlock if it is already unlocked
+ if (locked) {
+ swipeLockInterface.unlockSwipe();
+ locked = false;
+ }
+ } else {
+ if (!locked) {
+ swipeLockInterface.lockSwipe();
+ locked = true;
+ }
+ }
+ }
+ }
+
+ public interface SwipeLockInterface {
+ void lockSwipe();
+ void unlockSwipe();
+ }
+}
diff --git a/app/src/main/res/layout/adapter_table_block.xml b/app/src/main/res/layout/adapter_table_block.xml
index ab8ddfb1..a4adce5f 100644
--- a/app/src/main/res/layout/adapter_table_block.xml
+++ b/app/src/main/res/layout/adapter_table_block.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+<ml.docilealligator.infinityforreddit.customviews.SwipeLockScrollView
+ xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
@@ -12,4 +13,4 @@
android:layout_height="wrap_content"
android:stretchColumns="*" />
-</HorizontalScrollView> \ No newline at end of file
+</ml.docilealligator.infinityforreddit.customviews.SwipeLockScrollView>