reader/android: swipe left or right to turn pages
Change-Id: I037be10273f637a754c82bfcf3c6515034e19d13
diff --git a/android/app/src/main/java/io/v/android/apps/reader/PdfViewerActivity.java b/android/app/src/main/java/io/v/android/apps/reader/PdfViewerActivity.java
index b3e1c1a..2dfe9b7 100644
--- a/android/app/src/main/java/io/v/android/apps/reader/PdfViewerActivity.java
+++ b/android/app/src/main/java/io/v/android/apps/reader/PdfViewerActivity.java
@@ -10,13 +10,14 @@
import android.net.Uri;
import android.os.Bundle;
import android.provider.OpenableColumns;
+import android.support.v4.view.GestureDetectorCompat;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
+import android.view.MotionEvent;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;
-import android.widget.Button;
import android.widget.Toast;
import com.google.android.gms.analytics.HitBuilders;
@@ -47,8 +48,6 @@
private static final String EXTRA_DEVICE_SET_ID = "device_set_id";
private PdfViewWrapper mPdfView;
- private Button mButtonPrev;
- private Button mButtonNext;
private MenuItem mMenuItemLinkPage;
private DBList<DeviceSet> mDeviceSets;
@@ -78,20 +77,27 @@
mPdfView = (PdfViewWrapper) findViewById(R.id.pdfview);
mPdfView.init();
- mButtonPrev = (Button) findViewById(R.id.button_prev);
- mButtonNext = (Button) findViewById(R.id.button_next);
+ // Swipe gesture detection.
+ final GestureDetectorCompat swipeDetector = SwipeGestureDetector.create(
+ this,
+ new SwipeGestureDetector.SimpleOnSwipeListener() {
+ @Override
+ public boolean onSwipeLeft() {
+ nextPage();
+ return true;
+ }
- mButtonPrev.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- prevPage();
- }
- });
+ @Override
+ public boolean onSwipeRight() {
+ prevPage();
+ return true;
+ }
+ });
- mButtonNext.setOnClickListener(new View.OnClickListener() {
+ mPdfView.setOnTouchListener(new View.OnTouchListener() {
@Override
- public void onClick(View v) {
- nextPage();
+ public boolean onTouch(View v, MotionEvent event) {
+ return swipeDetector.onTouchEvent(event);
}
});
}
diff --git a/android/app/src/main/java/io/v/android/apps/reader/SwipeGestureDetector.java b/android/app/src/main/java/io/v/android/apps/reader/SwipeGestureDetector.java
new file mode 100644
index 0000000..3b73b4b
--- /dev/null
+++ b/android/app/src/main/java/io/v/android/apps/reader/SwipeGestureDetector.java
@@ -0,0 +1,90 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package io.v.android.apps.reader;
+
+import android.content.Context;
+import android.support.v4.view.GestureDetectorCompat;
+import android.view.GestureDetector;
+import android.view.MotionEvent;
+
+/**
+ * A swipe gesture detector which emits swipe events in left/right/up/down directions.
+ */
+public final class SwipeGestureDetector {
+
+ /**
+ * Use SwipeGestureDetector.create() instead.
+ */
+ private SwipeGestureDetector() {
+ }
+
+ /**
+ * The listener interface that is used to notify when swipe gestures occur.
+ * If you only want to listen for a subset, extend {@link SimpleOnSwipeListener} instead.
+ */
+ public interface OnSwipeListener {
+ boolean onSwipeLeft();
+ boolean onSwipeRight();
+ boolean onSwipeUp();
+ boolean onSwipeDown();
+ }
+
+ /**
+ * A convenient class to extend when you only want to listen to a subset of swipe gestures.
+ */
+ public static class SimpleOnSwipeListener implements OnSwipeListener {
+ @Override public boolean onSwipeLeft() { return false; }
+ @Override public boolean onSwipeRight() { return false; }
+ @Override public boolean onSwipeUp() { return false; }
+ @Override public boolean onSwipeDown() { return false; }
+ }
+
+ /**
+ * A gesture listener that listens to fling events and turns them into swipe events.
+ */
+ private static class FlingToSwipeListener extends GestureDetector.SimpleOnGestureListener {
+
+ private static final int DISTANCE_THRESHOLD = 100;
+ private static final int VELOCITY_THRESHOLD = 100;
+
+ private OnSwipeListener mSwipeListener;
+
+ public FlingToSwipeListener(OnSwipeListener swipeListener) {
+ mSwipeListener = swipeListener;
+ }
+
+ @Override
+ public boolean onFling(MotionEvent e1, MotionEvent e2, float vx, float vy) {
+ boolean result = false;
+ float dx = e2.getX() - e1.getX();
+ float dy = e2.getY() - e1.getY();
+ if (Math.abs(dx) > Math.abs(dy)) {
+ if (Math.abs(dx) > DISTANCE_THRESHOLD && Math.abs(vx) > VELOCITY_THRESHOLD) {
+ if (dx > 0) {
+ result = mSwipeListener.onSwipeRight();
+ } else {
+ result = mSwipeListener.onSwipeLeft();
+ }
+ }
+ } else {
+ if (Math.abs(dy) > DISTANCE_THRESHOLD && Math.abs(vy) > VELOCITY_THRESHOLD) {
+ if (dy > 0) {
+ result = mSwipeListener.onSwipeDown();
+ } else {
+ result = mSwipeListener.onSwipeUp();
+ }
+ }
+ }
+
+ return result;
+ }
+
+ }
+
+ public static GestureDetectorCompat create(Context context, OnSwipeListener listener) {
+ return new GestureDetectorCompat(context, new FlingToSwipeListener(listener));
+ }
+
+}
diff --git a/android/app/src/main/res/layout/activity_pdf_viewer.xml b/android/app/src/main/res/layout/activity_pdf_viewer.xml
index 9f57074..77bb12a 100644
--- a/android/app/src/main/res/layout/activity_pdf_viewer.xml
+++ b/android/app/src/main/res/layout/activity_pdf_viewer.xml
@@ -11,27 +11,10 @@
android:layout_marginTop="@dimen/activity_vertical_margin"
tools:context=".PdfViewerActivity">
- <Button
- android:id="@+id/button_prev"
- android:layout_width="48dp"
- android:layout_height="48dp"
- android:layout_alignParentBottom="true"
- android:layout_alignParentLeft="true"
- android:text="<" />
-
- <Button
- android:id="@+id/button_next"
- android:layout_width="48dp"
- android:layout_height="48dp"
- android:layout_alignParentBottom="true"
- android:layout_alignParentRight="true"
- android:text=">" />
-
<io.v.android.apps.reader.PdfViewWrapper
android:id="@+id/pdfview"
android:layout_width="match_parent"
android:layout_height="fill_parent"
- android:layout_above="@id/button_prev"
android:layout_alignParentTop="true" />
</RelativeLayout>