diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/AnimationManager.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/AnimationManager.java index e7e9439f..89e813af 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/AnimationManager.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/AnimationManager.java @@ -1,221 +1,221 @@ -/** - * Copyright 2016 Bartosz Schiller - *
- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.github.barteksc.pdfviewer; - -import android.animation.Animator; -import android.animation.Animator.AnimatorListener; -import android.animation.AnimatorListenerAdapter; -import android.animation.ValueAnimator; -import android.animation.ValueAnimator.AnimatorUpdateListener; -import android.graphics.PointF; -import android.view.animation.DecelerateInterpolator; -import android.widget.OverScroller; - - -/** - * This manager is used by the PDFView to launch animations. - * It uses the ValueAnimator appeared in API 11 to start - * an animation, and call moveTo() on the PDFView as a result - * of each animation update. - */ -class AnimationManager { - - private PDFView pdfView; - - private ValueAnimator animation; - - private OverScroller scroller; - - private boolean flinging = false; - - private boolean pageFlinging = false; - - public AnimationManager(PDFView pdfView) { - this.pdfView = pdfView; - scroller = new OverScroller(pdfView.getContext()); - } - - public void startXAnimation(float xFrom, float xTo) { - stopAll(); - animation = ValueAnimator.ofFloat(xFrom, xTo); - XAnimation xAnimation = new XAnimation(); - animation.setInterpolator(new DecelerateInterpolator()); - animation.addUpdateListener(xAnimation); - animation.addListener(xAnimation); - animation.setDuration(400); - animation.start(); - } - - public void startYAnimation(float yFrom, float yTo) { - stopAll(); - animation = ValueAnimator.ofFloat(yFrom, yTo); - YAnimation yAnimation = new YAnimation(); - animation.setInterpolator(new DecelerateInterpolator()); - animation.addUpdateListener(yAnimation); - animation.addListener(yAnimation); - animation.setDuration(400); - animation.start(); - } - - public void startZoomAnimation(float centerX, float centerY, float zoomFrom, float zoomTo) { - stopAll(); - animation = ValueAnimator.ofFloat(zoomFrom, zoomTo); - animation.setInterpolator(new DecelerateInterpolator()); - ZoomAnimation zoomAnim = new ZoomAnimation(centerX, centerY); - animation.addUpdateListener(zoomAnim); - animation.addListener(zoomAnim); - animation.setDuration(400); - animation.start(); - } - - public void startFlingAnimation(int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, int maxY) { - stopAll(); - flinging = true; - scroller.fling(startX, startY, velocityX, velocityY, minX, maxX, minY, maxY); - } - - public void startPageFlingAnimation(float targetOffset) { - if (pdfView.isSwipeVertical()) { - startYAnimation(pdfView.getCurrentYOffset(), targetOffset); - } else { - startXAnimation(pdfView.getCurrentXOffset(), targetOffset); - } - pageFlinging = true; - } - - void computeFling() { - if (scroller.computeScrollOffset()) { - pdfView.moveTo(scroller.getCurrX(), scroller.getCurrY()); - pdfView.loadPageByOffset(); - } else if (flinging) { // fling finished - flinging = false; - pdfView.loadPages(); - hideHandle(); - pdfView.performPageSnap(); - } - } - - public void stopAll() { - if (animation != null) { - animation.cancel(); - animation = null; - } - stopFling(); - } - - public void stopFling() { - flinging = false; - scroller.forceFinished(true); - } - - public boolean isFlinging() { - return flinging || pageFlinging; - } - - class XAnimation extends AnimatorListenerAdapter implements AnimatorUpdateListener { - - @Override - public void onAnimationUpdate(ValueAnimator animation) { - float offset = (Float) animation.getAnimatedValue(); - pdfView.moveTo(offset, pdfView.getCurrentYOffset()); - pdfView.loadPageByOffset(); - } - - @Override - public void onAnimationCancel(Animator animation) { - pdfView.loadPages(); - pageFlinging = false; - hideHandle(); - } - - @Override - public void onAnimationEnd(Animator animation) { - pdfView.loadPages(); - pageFlinging = false; - hideHandle(); - } - } - - class YAnimation extends AnimatorListenerAdapter implements AnimatorUpdateListener { - - @Override - public void onAnimationUpdate(ValueAnimator animation) { - float offset = (Float) animation.getAnimatedValue(); - pdfView.moveTo(pdfView.getCurrentXOffset(), offset); - pdfView.loadPageByOffset(); - } - - @Override - public void onAnimationCancel(Animator animation) { - pdfView.loadPages(); - pageFlinging = false; - hideHandle(); - } - - @Override - public void onAnimationEnd(Animator animation) { - pdfView.loadPages(); - pageFlinging = false; - hideHandle(); - } - } - - class ZoomAnimation implements AnimatorUpdateListener, AnimatorListener { - - private final float centerX; - private final float centerY; - - public ZoomAnimation(float centerX, float centerY) { - this.centerX = centerX; - this.centerY = centerY; - } - - @Override - public void onAnimationUpdate(ValueAnimator animation) { - float zoom = (Float) animation.getAnimatedValue(); - pdfView.zoomCenteredTo(zoom, new PointF(centerX, centerY)); - } - - @Override - public void onAnimationCancel(Animator animation) { - pdfView.loadPages(); - hideHandle(); - } - - @Override - public void onAnimationEnd(Animator animation) { - pdfView.loadPages(); - pdfView.performPageSnap(); - hideHandle(); - } - - @Override - public void onAnimationRepeat(Animator animation) { - } - - @Override - public void onAnimationStart(Animator animation) { - } - - } - - private void hideHandle() { - if (pdfView.getScrollHandle() != null) { - pdfView.getScrollHandle().hideDelayed(); - } - } - -} +/** + * Copyright 2016 Bartosz Schiller + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.github.barteksc.pdfviewer; + +import android.animation.Animator; +import android.animation.Animator.AnimatorListener; +import android.animation.AnimatorListenerAdapter; +import android.animation.ValueAnimator; +import android.animation.ValueAnimator.AnimatorUpdateListener; +import android.graphics.PointF; +import android.view.animation.DecelerateInterpolator; +import android.widget.OverScroller; + + +/** + * This manager is used by the PDFView to launch animations. + * It uses the ValueAnimator appeared in API 11 to start + * an animation, and call moveTo() on the PDFView as a result + * of each animation update. + */ +class AnimationManager { + + private PDFView pdfView; + + private ValueAnimator animation; + + private OverScroller scroller; + + private boolean flinging = false; + + private boolean pageFlinging = false; + + public AnimationManager(PDFView pdfView) { + this.pdfView = pdfView; + scroller = new OverScroller(pdfView.getContext()); + } + + public void startXAnimation(float xFrom, float xTo) { + stopAll(); + animation = ValueAnimator.ofFloat(xFrom, xTo); + XAnimation xAnimation = new XAnimation(); + animation.setInterpolator(new DecelerateInterpolator()); + animation.addUpdateListener(xAnimation); + animation.addListener(xAnimation); + animation.setDuration(400); + animation.start(); + } + + public void startYAnimation(float yFrom, float yTo) { + stopAll(); + animation = ValueAnimator.ofFloat(yFrom, yTo); + YAnimation yAnimation = new YAnimation(); + animation.setInterpolator(new DecelerateInterpolator()); + animation.addUpdateListener(yAnimation); + animation.addListener(yAnimation); + animation.setDuration(400); + animation.start(); + } + + public void startZoomAnimation(float centerX, float centerY, float zoomFrom, float zoomTo) { + stopAll(); + animation = ValueAnimator.ofFloat(zoomFrom, zoomTo); + animation.setInterpolator(new DecelerateInterpolator()); + ZoomAnimation zoomAnim = new ZoomAnimation(centerX, centerY); + animation.addUpdateListener(zoomAnim); + animation.addListener(zoomAnim); + animation.setDuration(400); + animation.start(); + } + + public void startFlingAnimation(int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, int maxY) { + stopAll(); + flinging = true; + scroller.fling(startX, startY, velocityX, velocityY, minX, maxX, minY, maxY); + } + + public void startPageFlingAnimation(float targetOffset) { + if (pdfView.isSwipeVertical()) { + startYAnimation(pdfView.getCurrentYOffset(), targetOffset); + } else { + startXAnimation(pdfView.getCurrentXOffset(), targetOffset); + } + pageFlinging = true; + } + + void computeFling() { + if (scroller.computeScrollOffset()) { + pdfView.moveTo(scroller.getCurrX(), scroller.getCurrY()); + pdfView.loadPageByOffset(); + } else if (flinging) { // fling finished + flinging = false; + pdfView.loadPages(); + hideHandle(); + pdfView.performPageSnap(); + } + } + + public void stopAll() { + if (animation != null) { + animation.cancel(); + animation = null; + } + stopFling(); + } + + public void stopFling() { + flinging = false; + scroller.forceFinished(true); + } + + public boolean isFlinging() { + return flinging || pageFlinging; + } + + class XAnimation extends AnimatorListenerAdapter implements AnimatorUpdateListener { + + @Override + public void onAnimationUpdate(ValueAnimator animation) { + float offset = (Float) animation.getAnimatedValue(); + pdfView.moveTo(offset, pdfView.getCurrentYOffset()); + pdfView.loadPageByOffset(); + } + + @Override + public void onAnimationCancel(Animator animation) { + pdfView.loadPages(); + pageFlinging = false; + hideHandle(); + } + + @Override + public void onAnimationEnd(Animator animation) { + pdfView.loadPages(); + pageFlinging = false; + hideHandle(); + } + } + + class YAnimation extends AnimatorListenerAdapter implements AnimatorUpdateListener { + + @Override + public void onAnimationUpdate(ValueAnimator animation) { + float offset = (Float) animation.getAnimatedValue(); + pdfView.moveTo(pdfView.getCurrentXOffset(), offset); + pdfView.loadPageByOffset(); + } + + @Override + public void onAnimationCancel(Animator animation) { + pdfView.loadPages(); + pageFlinging = false; + hideHandle(); + } + + @Override + public void onAnimationEnd(Animator animation) { + pdfView.loadPages(); + pageFlinging = false; + hideHandle(); + } + } + + class ZoomAnimation implements AnimatorUpdateListener, AnimatorListener { + + private final float centerX; + private final float centerY; + + public ZoomAnimation(float centerX, float centerY) { + this.centerX = centerX; + this.centerY = centerY; + } + + @Override + public void onAnimationUpdate(ValueAnimator animation) { + float zoom = (Float) animation.getAnimatedValue(); + pdfView.zoomCenteredTo(zoom, new PointF(centerX, centerY)); + } + + @Override + public void onAnimationCancel(Animator animation) { + pdfView.loadPages(); + hideHandle(); + } + + @Override + public void onAnimationEnd(Animator animation) { + pdfView.loadPages(); + pdfView.performPageSnap(); + hideHandle(); + } + + @Override + public void onAnimationRepeat(Animator animation) { + } + + @Override + public void onAnimationStart(Animator animation) { + } + + } + + private void hideHandle() { + if (pdfView.getScrollHandle() != null) { + pdfView.getScrollHandle().hideDelayed(); + } + } + +} diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/CacheManager.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/CacheManager.java index 082ca3bf..97e6914d 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/CacheManager.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/CacheManager.java @@ -1,192 +1,192 @@ -/** - * Copyright 2016 Bartosz Schiller - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.github.barteksc.pdfviewer; - -import android.graphics.RectF; -import android.support.annotation.Nullable; - -import com.github.barteksc.pdfviewer.model.PagePart; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Comparator; -import java.util.List; -import java.util.PriorityQueue; - -import static com.github.barteksc.pdfviewer.util.Constants.Cache.CACHE_SIZE; -import static com.github.barteksc.pdfviewer.util.Constants.Cache.THUMBNAILS_CACHE_SIZE; - -class CacheManager { - - private final PriorityQueue- * To fully understand this class you must know its principles : - * - The PDF document is seen as if we always want to draw all the pages. - * - The thing is that we only draw the visible parts. - * - All parts are the same size, this is because we can't interrupt a native page rendering, - * so we need these renderings to be as fast as possible, and be able to interrupt them - * as soon as we can. - * - The parts are loaded when the current offset or the current zoom level changes - *
- * Important :
- * - DocumentPage = A page of the PDF document.
- * - UserPage = A page as defined by the user.
- * By default, they're the same. But the user can change the pages order
- * using {@link #load(DocumentSource, String, int[])}. In this
- * particular case, a userPage of 5 can refer to a documentPage of 17.
- */
-public class PDFView extends RelativeLayout {
-
- private static final String TAG = PDFView.class.getSimpleName();
-
- public static final float DEFAULT_MAX_SCALE = 3.0f;
- public static final float DEFAULT_MID_SCALE = 1.75f;
- public static final float DEFAULT_MIN_SCALE = 1.0f;
-
- private float minZoom = DEFAULT_MIN_SCALE;
- private float midZoom = DEFAULT_MID_SCALE;
- private float maxZoom = DEFAULT_MAX_SCALE;
-
- /**
- * START - scrolling in first page direction
- * END - scrolling in last page direction
- * NONE - not scrolling
- */
- enum ScrollDir {
- NONE, START, END
- }
-
- private ScrollDir scrollDir = ScrollDir.NONE;
-
- /** Rendered parts go to the cache manager */
- CacheManager cacheManager;
-
- /** Animation manager manage all offset and zoom animation */
- private AnimationManager animationManager;
-
- /** Drag manager manage all touch events */
- private DragPinchManager dragPinchManager;
-
- PdfFile pdfFile;
-
- /** The index of the current sequence */
- private int currentPage;
-
- /**
- * If you picture all the pages side by side in their optimal width,
- * and taking into account the zoom level, the current offset is the
- * position of the left border of the screen in this big picture
- */
- private float currentXOffset = 0;
-
- /**
- * If you picture all the pages side by side in their optimal width,
- * and taking into account the zoom level, the current offset is the
- * position of the left border of the screen in this big picture
- */
- private float currentYOffset = 0;
-
- /** The zoom level, always >= 1 */
- private float zoom = 1f;
-
- /** True if the PDFView has been recycled */
- private boolean recycled = true;
-
- /** Current state of the view */
- private State state = State.DEFAULT;
-
- /** Async task used during the loading phase to decode a PDF document */
- private DecodingAsyncTask decodingAsyncTask;
-
- /** The thread {@link #renderingHandler} will run on */
- private HandlerThread renderingHandlerThread;
- /** Handler always waiting in the background and rendering tasks */
- RenderingHandler renderingHandler;
-
- private PagesLoader pagesLoader;
-
- Callbacks callbacks = new Callbacks();
-
- /** Paint object for drawing */
- private Paint paint;
-
- /** Paint object for drawing debug stuff */
- private Paint debugPaint;
-
- /** Policy for fitting pages to screen */
- private FitPolicy pageFitPolicy = FitPolicy.WIDTH;
-
- private boolean fitEachPage = false;
-
- private int defaultPage = 0;
-
- /** True if should scroll through pages vertically instead of horizontally */
- private boolean swipeVertical = true;
-
- private boolean enableSwipe = true;
-
- private boolean doubletapEnabled = true;
-
- private boolean nightMode = false;
-
- private boolean pageSnap = true;
-
- /** Pdfium core for loading and rendering PDFs */
- private PdfiumCore pdfiumCore;
-
- private ScrollHandle scrollHandle;
-
- private boolean isScrollHandleInit = false;
-
- ScrollHandle getScrollHandle() {
- return scrollHandle;
- }
-
- /**
- * True if bitmap should use ARGB_8888 format and take more memory
- * False if bitmap should be compressed by using RGB_565 format and take less memory
- */
- private boolean bestQuality = false;
-
- /**
- * True if annotations should be rendered
- * False otherwise
- */
- private boolean annotationRendering = false;
-
- /**
- * True if the view should render during scaling
+ * To fully understand this class you must know its principles :
+ * - The PDF document is seen as if we always want to draw all the pages.
+ * - The thing is that we only draw the visible parts.
+ * - All parts are the same size, this is because we can't interrupt a native page rendering,
+ * so we need these renderings to be as fast as possible, and be able to interrupt them
+ * as soon as we can.
+ * - The parts are loaded when the current offset or the current zoom level changes
+ *
+ * Important :
+ * - DocumentPage = A page of the PDF document.
+ * - UserPage = A page as defined by the user.
+ * By default, they're the same. But the user can change the pages order
+ * using {@link #load(DocumentSource, String, int[])}. In this
+ * particular case, a userPage of 5 can refer to a documentPage of 17.
+ */
+public class PDFView extends RelativeLayout {
+
+ private static final String TAG = PDFView.class.getSimpleName();
+
+ public static final float DEFAULT_MAX_SCALE = 3.0f;
+ public static final float DEFAULT_MID_SCALE = 1.75f;
+ public static final float DEFAULT_MIN_SCALE = 1.0f;
+
+ private float minZoom = DEFAULT_MIN_SCALE;
+ private float midZoom = DEFAULT_MID_SCALE;
+ private float maxZoom = DEFAULT_MAX_SCALE;
+
+ /**
+ * START - scrolling in first page direction
+ * END - scrolling in last page direction
+ * NONE - not scrolling
+ */
+ enum ScrollDir {
+ NONE, START, END
+ }
+
+ private ScrollDir scrollDir = ScrollDir.NONE;
+
+ /** Rendered parts go to the cache manager */
+ CacheManager cacheManager;
+
+ /** Animation manager manage all offset and zoom animation */
+ private AnimationManager animationManager;
+
+ /** Drag manager manage all touch events */
+ private DragPinchManager dragPinchManager;
+
+ PdfFile pdfFile;
+
+ /** The index of the current sequence */
+ private int currentPage;
+
+ /**
+ * If you picture all the pages side by side in their optimal width,
+ * and taking into account the zoom level, the current offset is the
+ * position of the left border of the screen in this big picture
+ */
+ private float currentXOffset = 0;
+
+ /**
+ * If you picture all the pages side by side in their optimal width,
+ * and taking into account the zoom level, the current offset is the
+ * position of the left border of the screen in this big picture
+ */
+ private float currentYOffset = 0;
+
+ /** The zoom level, always >= 1 */
+ private float zoom = 1f;
+
+ /** True if the PDFView has been recycled */
+ private boolean recycled = true;
+
+ /** Current state of the view */
+ private State state = State.DEFAULT;
+
+ /** Async task used during the loading phase to decode a PDF document */
+ private DecodingAsyncTask decodingAsyncTask;
+
+ /** The thread {@link #renderingHandler} will run on */
+ private HandlerThread renderingHandlerThread;
+ /** Handler always waiting in the background and rendering tasks */
+ RenderingHandler renderingHandler;
+
+ private PagesLoader pagesLoader;
+
+ Callbacks callbacks = new Callbacks();
+
+ /** Paint object for drawing */
+ private Paint paint;
+
+ /** Paint object for drawing debug stuff */
+ private Paint debugPaint;
+
+ /** Policy for fitting pages to screen */
+ private FitPolicy pageFitPolicy = FitPolicy.WIDTH;
+
+ private boolean fitEachPage = false;
+
+ private int defaultPage = 0;
+
+ private boolean dualPageMode = false;
+
+ private boolean isLandscapeOrientation = false;
+
+ /** True if should scroll through pages vertically instead of horizontally */
+ private boolean swipeVertical = true;
+
+ private boolean enableSwipe = true;
+
+ private boolean doubletapEnabled = true;
+
+ private boolean nightMode = false;
+
+ private boolean pageSnap = true;
+
+ /** Pdfium core for loading and rendering PDFs */
+ private PdfiumCore pdfiumCore;
+
+ private ScrollHandle scrollHandle;
+
+ private boolean isScrollHandleInit = false;
+
+ ScrollHandle getScrollHandle() {
+ return scrollHandle;
+ }
+
+ /**
+ * True if bitmap should use ARGB_8888 format and take more memory
+ * False if bitmap should be compressed by using RGB_565 format and take less memory
+ */
+ private boolean bestQuality = false;
+
+ /**
+ * True if annotations should be rendered
+ * False otherwise
+ */
+ private boolean annotationRendering = false;
+
+ /**
+ * True if the view should render during scaling
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.github.barteksc.pdfviewer.listener;
-
-import android.graphics.Canvas;
-
-/**
- * This interface allows an extern class to draw
- * something on the PDFView canvas, above all images.
- */
-public interface OnDrawListener {
-
- /**
- * This method is called when the PDFView is
- * drawing its view.
- *
- * The page is starting at (0,0)
- *
- * @param canvas The canvas on which to draw things.
- * @param pageWidth The width of the current page.
- * @param pageHeight The height of the current page.
- * @param displayedPage The current page index
- */
- void onLayerDrawn(Canvas canvas, float pageWidth, float pageHeight, int displayedPage);
-}
+/**
+ * Copyright 2016 Bartosz Schiller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.github.barteksc.pdfviewer.listener;
+
+import android.graphics.Canvas;
+
+/**
+ * This interface allows an extern class to draw
+ * something on the PDFView canvas, above all images.
+ */
+public interface OnDrawListener {
+
+ /**
+ * This method is called when the PDFView is
+ * drawing its view.
+ *
+ * The page is starting at (0,0)
+ *
+ * @param canvas The canvas on which to draw things.
+ * @param pageWidth The width of the current page.
+ * @param pageHeight The height of the current page.
+ * @param displayedPage The current page index
+ */
+ void onLayerDrawn(Canvas canvas, float pageWidth, float pageHeight, int displayedPage);
+}
diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnLoadCompleteListener.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnLoadCompleteListener.java
index c319fc58..a52cbc92 100644
--- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnLoadCompleteListener.java
+++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnLoadCompleteListener.java
@@ -1,29 +1,29 @@
-/**
- * Copyright 2016 Bartosz Schiller
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.github.barteksc.pdfviewer.listener;
-
-/**
- * Implement this interface to receive events from PDFView
- * when loading is complete.
- */
-public interface OnLoadCompleteListener {
-
- /**
- * Called when the PDF is loaded
- * @param nbPages the number of pages in this PDF file
- */
- void loadComplete(int nbPages);
-}
+/**
+ * Copyright 2016 Bartosz Schiller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.github.barteksc.pdfviewer.listener;
+
+/**
+ * Implement this interface to receive events from PDFView
+ * when loading is complete.
+ */
+public interface OnLoadCompleteListener {
+
+ /**
+ * Called when the PDF is loaded
+ * @param nbPages the number of pages in this PDF file
+ */
+ void loadComplete(int nbPages);
+}
diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnPageChangeListener.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnPageChangeListener.java
index dfb758a5..0945ca8e 100644
--- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnPageChangeListener.java
+++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/listener/OnPageChangeListener.java
@@ -1,32 +1,32 @@
-/**
- * Copyright 2016 Bartosz Schiller
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.github.barteksc.pdfviewer.listener;
-
-/**
- * Implements this interface to receive events from PDFView
- * when a page has changed through swipe
- */
-public interface OnPageChangeListener {
-
- /**
- * Called when the user use swipe to change page
- *
- * @param page the new page displayed, starting from 0
- * @param pageCount the total page count
- */
- void onPageChanged(int page, int pageCount);
-
-}
+/**
+ * Copyright 2016 Bartosz Schiller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.github.barteksc.pdfviewer.listener;
+
+/**
+ * Implements this interface to receive events from PDFView
+ * when a page has changed through swipe
+ */
+public interface OnPageChangeListener {
+
+ /**
+ * Called when the user use swipe to change page
+ *
+ * @param page the new page displayed, starting from 0
+ * @param pageCount the total page count
+ */
+ void onPageChanged(int page, int pageCount);
+
+}
diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/model/PagePart.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/model/PagePart.java
index 376d2ccd..19a2186f 100644
--- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/model/PagePart.java
+++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/model/PagePart.java
@@ -1,80 +1,80 @@
-/**
- * Copyright 2016 Bartosz Schiller
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.github.barteksc.pdfviewer.model;
-
-import android.graphics.Bitmap;
-import android.graphics.RectF;
-
-public class PagePart {
-
- private int page;
-
- private Bitmap renderedBitmap;
-
- private RectF pageRelativeBounds;
-
- private boolean thumbnail;
-
- private int cacheOrder;
-
- public PagePart(int page, Bitmap renderedBitmap, RectF pageRelativeBounds, boolean thumbnail, int cacheOrder) {
- super();
- this.page = page;
- this.renderedBitmap = renderedBitmap;
- this.pageRelativeBounds = pageRelativeBounds;
- this.thumbnail = thumbnail;
- this.cacheOrder = cacheOrder;
- }
-
- public int getCacheOrder() {
- return cacheOrder;
- }
-
- public int getPage() {
- return page;
- }
-
- public Bitmap getRenderedBitmap() {
- return renderedBitmap;
- }
-
- public RectF getPageRelativeBounds() {
- return pageRelativeBounds;
- }
-
- public boolean isThumbnail() {
- return thumbnail;
- }
-
- public void setCacheOrder(int cacheOrder) {
- this.cacheOrder = cacheOrder;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof PagePart)) {
- return false;
- }
-
- PagePart part = (PagePart) obj;
- return part.getPage() == page
- && part.getPageRelativeBounds().left == pageRelativeBounds.left
- && part.getPageRelativeBounds().right == pageRelativeBounds.right
- && part.getPageRelativeBounds().top == pageRelativeBounds.top
- && part.getPageRelativeBounds().bottom == pageRelativeBounds.bottom;
- }
-
-}
+/**
+ * Copyright 2016 Bartosz Schiller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.github.barteksc.pdfviewer.model;
+
+import android.graphics.Bitmap;
+import android.graphics.RectF;
+
+public class PagePart {
+
+ private int page;
+
+ private Bitmap renderedBitmap;
+
+ private RectF pageRelativeBounds;
+
+ private boolean thumbnail;
+
+ private int cacheOrder;
+
+ public PagePart(int page, Bitmap renderedBitmap, RectF pageRelativeBounds, boolean thumbnail, int cacheOrder) {
+ super();
+ this.page = page;
+ this.renderedBitmap = renderedBitmap;
+ this.pageRelativeBounds = pageRelativeBounds;
+ this.thumbnail = thumbnail;
+ this.cacheOrder = cacheOrder;
+ }
+
+ public int getCacheOrder() {
+ return cacheOrder;
+ }
+
+ public int getPage() {
+ return page;
+ }
+
+ public Bitmap getRenderedBitmap() {
+ return renderedBitmap;
+ }
+
+ public RectF getPageRelativeBounds() {
+ return pageRelativeBounds;
+ }
+
+ public boolean isThumbnail() {
+ return thumbnail;
+ }
+
+ public void setCacheOrder(int cacheOrder) {
+ this.cacheOrder = cacheOrder;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof PagePart)) {
+ return false;
+ }
+
+ PagePart part = (PagePart) obj;
+ return part.getPage() == page
+ && part.getPageRelativeBounds().left == pageRelativeBounds.left
+ && part.getPageRelativeBounds().right == pageRelativeBounds.right
+ && part.getPageRelativeBounds().top == pageRelativeBounds.top
+ && part.getPageRelativeBounds().bottom == pageRelativeBounds.bottom;
+ }
+
+}
diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/scroll/DefaultScrollHandle.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/scroll/DefaultScrollHandle.java
index 8195a540..42c1feab 100644
--- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/scroll/DefaultScrollHandle.java
+++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/scroll/DefaultScrollHandle.java
@@ -149,7 +149,11 @@ private void calculateMiddle() {
pos = getY();
viewSize = getHeight();
pdfViewSize = pdfView.getHeight();
- } else {
+ } else if (pdfView.isOnDualPageMode()){
+ pos = getX();
+ viewSize = getWidth() / 2;
+ pdfViewSize = pdfView.getWidth() / 2;
+ } else {
pos = getX();
viewSize = getWidth();
pdfViewSize = pdfView.getWidth();
diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/ArrayUtils.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/ArrayUtils.java
index 1ff38398..3fb887d6 100644
--- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/ArrayUtils.java
+++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/ArrayUtils.java
@@ -1,74 +1,74 @@
-/**
- * Copyright 2016 Bartosz Schiller
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.github.barteksc.pdfviewer.util;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class ArrayUtils {
-
- private ArrayUtils() {
- // Prevents instantiation
- }
-
- /** Transforms (0,1,2,2,3) to (0,1,2,3) */
- public static int[] deleteDuplicatedPages(int[] pages) {
- List
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.github.barteksc.pdfviewer.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ArrayUtils {
+
+ private ArrayUtils() {
+ // Prevents instantiation
+ }
+
+ /** Transforms (0,1,2,2,3) to (0,1,2,3) */
+ public static int[] deleteDuplicatedPages(int[] pages) {
+ List
- * Can not be forced on older API versions (< Build.VERSION_CODES.KITKAT) as the GestureDetector does
- * not detect scrolling while scaling.
- * False otherwise
- */
- private boolean renderDuringScale = false;
-
- /** Antialiasing and bitmap filtering */
- private boolean enableAntialiasing = true;
- private PaintFlagsDrawFilter antialiasFilter =
- new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
-
- /** Spacing between pages, in px */
- private int spacingPx = 0;
-
- /** Add dynamic spacing to fit each page separately on the screen. */
- private boolean autoSpacing = false;
-
- /** Fling a single page at a time */
- private boolean pageFling = true;
-
- /** Pages numbers used when calling onDrawAllListener */
- private List
+ * Can not be forced on older API versions (< Build.VERSION_CODES.KITKAT) as the GestureDetector does
+ * not detect scrolling while scaling.
+ * False otherwise
+ */
+ private boolean renderDuringScale = false;
+
+ /** Antialiasing and bitmap filtering */
+ private boolean enableAntialiasing = true;
+ private PaintFlagsDrawFilter antialiasFilter =
+ new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
+
+ /** Spacing between pages, in px */
+ private int spacingPx = 0;
+
+ /** Add dynamic spacing to fit each page separately on the screen. */
+ private boolean autoSpacing = false;
+
+ /** Fling a single page at a time */
+ private boolean pageFling = true;
+
+ /** Pages numbers used when calling onDrawAllListener */
+ private List