diff --git a/README.md b/README.md index 72fe8678..4417e325 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,25 @@ -# Looking for new maintainer! +# WARNING! +This fork was made in order to migrate the library to AndroidX. Add-ons and updates probably will not appear. +[![Release](https://jitpack.io/v/TalbotGooday/AndroidPdfViewer.svg)](https://jitpack.io/#TalbotGooday/AndroidPdfViewer) +Add to _build.gradle_: +```groovy +allprojects { + repositories { + ... + maven { url 'https://jitpack.io' } + } +} +``` +Add the dependency +```groovy +implementation 'com.github.TalbotGooday:AndroidPdfViewer:Tag' +``` + +--- +### Original description # Android PdfViewer __AndroidPdfViewer 1.x is available on [AndroidPdfViewerV1](https://github.com/barteksc/AndroidPdfViewerV1) diff --git a/android-pdf-viewer/bintray.gradle b/android-pdf-viewer/bintray.gradle deleted file mode 100644 index 9a01f197..00000000 --- a/android-pdf-viewer/bintray.gradle +++ /dev/null @@ -1,89 +0,0 @@ -apply plugin: 'com.github.dcendents.android-maven' -apply plugin: 'com.jfrog.bintray' - -group = publishedGroupId -version = libraryVersion - -install { - repositories.mavenInstaller { - pom.project { - packaging 'aar' - groupId publishedGroupId - artifactId artifact - - name libraryName - description libraryDescription - url siteUrl - - licenses { - license { - name licenseName - url licenseUrl - } - } - developers { - developer { - id developerId - name developerName - email developerEmail - } - } - scm { - connection gitUrl - developerConnection gitUrl - url siteUrl - } - } - } -} - -task sourcesJar(type: Jar) { - classifier = 'sources' - from android.sourceSets.main.java.srcDirs -} - -task javadoc(type: Javadoc) { - source = android.sourceSets.main.java.srcDirs - classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) -} - -afterEvaluate { - javadoc.classpath += files(android.libraryVariants.collect { variant -> - variant.javaCompileProvider.get().classpath.files - }) -} - -task javadocJar(type: Jar, dependsOn: javadoc) { - classifier = 'javadoc' - from javadoc.destinationDir -} - -artifacts { - archives javadocJar - archives sourcesJar -} - -Properties properties = new Properties() -properties.load(project.rootProject.file('local.properties').newDataInputStream()) - -bintray { - user = properties.getProperty("bintray.user") - key = properties.getProperty("bintray.apikey") - - configurations = ['archives'] - pkg { - repo = bintrayRepo - name = bintrayName - desc = libraryDescription - websiteUrl = siteUrl - vcsUrl = gitUrl - licenses = allLicenses - dryRun = false - publish = true - override = false - publicDownloadNumbers = true - version { - desc = libraryDescription - } - } -} \ No newline at end of file diff --git a/android-pdf-viewer/build.gradle b/android-pdf-viewer/build.gradle index 32d03665..e7d55e9f 100644 --- a/android-pdf-viewer/build.gradle +++ b/android-pdf-viewer/build.gradle @@ -1,44 +1,17 @@ apply plugin: 'com.android.library' -ext { - bintrayRepo = 'maven' - bintrayName = 'android-pdf-viewer' - - publishedGroupId = 'com.github.barteksc' - libraryName = 'AndroidPdfViewer' - artifact = 'android-pdf-viewer' - - libraryDescription = 'Android view for displaying PDFs rendered with PdfiumAndroid' - - siteUrl = 'https://github.com/barteksc/AndroidPdfViewer' - gitUrl = 'https://github.com/barteksc/AndroidPdfViewer.git' - - libraryVersion = '3.2.0-beta.1' - - developerId = 'barteksc' - developerName = 'Bartosz Schiller' - developerEmail = 'barteksch@boo.pl' - - licenseName = 'The Apache Software License, Version 2.0' - licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt' - allLicenses = ["Apache-2.0"] -} - android { - compileSdkVersion 28 + compileSdkVersion 29 defaultConfig { - minSdkVersion 14 - targetSdkVersion 28 + minSdkVersion 16 + targetSdkVersion 29 versionCode 1 versionName "3.2.0-beta.1" } - } dependencies { - implementation 'com.android.support:support-compat:28.0.0' - api 'com.github.barteksc:pdfium-android:1.9.0' -} - -apply from: 'bintray.gradle' \ No newline at end of file + implementation 'androidx.core:core:1.3.1' + api 'com.github.TalbotGooday:PdfiumAndroid:1.0.1' +} \ No newline at end of file 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..c2667344 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 passiveCache; - - private final PriorityQueue activeCache; - - private final List thumbnails; - - private final Object passiveActiveLock = new Object(); - - private final PagePartComparator orderComparator = new PagePartComparator(); - - public CacheManager() { - activeCache = new PriorityQueue<>(CACHE_SIZE, orderComparator); - passiveCache = new PriorityQueue<>(CACHE_SIZE, orderComparator); - thumbnails = new ArrayList<>(); - } - - public void cachePart(PagePart part) { - synchronized (passiveActiveLock) { - // If cache too big, remove and recycle - makeAFreeSpace(); - - // Then add part - activeCache.offer(part); - } - } - - public void makeANewSet() { - synchronized (passiveActiveLock) { - passiveCache.addAll(activeCache); - activeCache.clear(); - } - } - - private void makeAFreeSpace() { - synchronized (passiveActiveLock) { - while ((activeCache.size() + passiveCache.size()) >= CACHE_SIZE && - !passiveCache.isEmpty()) { - PagePart part = passiveCache.poll(); - part.getRenderedBitmap().recycle(); - } - - while ((activeCache.size() + passiveCache.size()) >= CACHE_SIZE && - !activeCache.isEmpty()) { - activeCache.poll().getRenderedBitmap().recycle(); - } - } - } - - public void cacheThumbnail(PagePart part) { - synchronized (thumbnails) { - // If cache too big, remove and recycle - while (thumbnails.size() >= THUMBNAILS_CACHE_SIZE) { - thumbnails.remove(0).getRenderedBitmap().recycle(); - } - - // Then add thumbnail - addWithoutDuplicates(thumbnails, part); - } - - } - - public boolean upPartIfContained(int page, RectF pageRelativeBounds, int toOrder) { - PagePart fakePart = new PagePart(page, null, pageRelativeBounds, false, 0); - - PagePart found; - synchronized (passiveActiveLock) { - if ((found = find(passiveCache, fakePart)) != null) { - passiveCache.remove(found); - found.setCacheOrder(toOrder); - activeCache.offer(found); - return true; - } - - return find(activeCache, fakePart) != null; - } - } - - /** - * Return true if already contains the described PagePart - */ - public boolean containsThumbnail(int page, RectF pageRelativeBounds) { - PagePart fakePart = new PagePart(page, null, pageRelativeBounds, true, 0); - synchronized (thumbnails) { - for (PagePart part : thumbnails) { - if (part.equals(fakePart)) { - return true; - } - } - return false; - } - } - - /** - * Add part if it doesn't exist, recycle bitmap otherwise - */ - private void addWithoutDuplicates(Collection collection, PagePart newPart) { - for (PagePart part : collection) { - if (part.equals(newPart)) { - newPart.getRenderedBitmap().recycle(); - return; - } - } - collection.add(newPart); - } - - @Nullable - private static PagePart find(PriorityQueue vector, PagePart fakePart) { - for (PagePart part : vector) { - if (part.equals(fakePart)) { - return part; - } - } - return null; - } - - public List getPageParts() { - synchronized (passiveActiveLock) { - List parts = new ArrayList<>(passiveCache); - parts.addAll(activeCache); - return parts; - } - } - - public List getThumbnails() { - synchronized (thumbnails) { - return thumbnails; - } - } - - public void recycle() { - synchronized (passiveActiveLock) { - for (PagePart part : passiveCache) { - part.getRenderedBitmap().recycle(); - } - passiveCache.clear(); - for (PagePart part : activeCache) { - part.getRenderedBitmap().recycle(); - } - activeCache.clear(); - } - synchronized (thumbnails) { - for (PagePart part : thumbnails) { - part.getRenderedBitmap().recycle(); - } - thumbnails.clear(); - } - } - - class PagePartComparator implements Comparator { - @Override - public int compare(PagePart part1, PagePart part2) { - if (part1.getCacheOrder() == part2.getCacheOrder()) { - return 0; - } - return part1.getCacheOrder() > part2.getCacheOrder() ? 1 : -1; - } - } - -} +/** + * 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 androidx.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 passiveCache; + + private final PriorityQueue activeCache; + + private final List thumbnails; + + private final Object passiveActiveLock = new Object(); + + private final PagePartComparator orderComparator = new PagePartComparator(); + + public CacheManager() { + activeCache = new PriorityQueue<>(CACHE_SIZE, orderComparator); + passiveCache = new PriorityQueue<>(CACHE_SIZE, orderComparator); + thumbnails = new ArrayList<>(); + } + + public void cachePart(PagePart part) { + synchronized (passiveActiveLock) { + // If cache too big, remove and recycle + makeAFreeSpace(); + + // Then add part + activeCache.offer(part); + } + } + + public void makeANewSet() { + synchronized (passiveActiveLock) { + passiveCache.addAll(activeCache); + activeCache.clear(); + } + } + + private void makeAFreeSpace() { + synchronized (passiveActiveLock) { + while ((activeCache.size() + passiveCache.size()) >= CACHE_SIZE && + !passiveCache.isEmpty()) { + PagePart part = passiveCache.poll(); + part.getRenderedBitmap().recycle(); + } + + while ((activeCache.size() + passiveCache.size()) >= CACHE_SIZE && + !activeCache.isEmpty()) { + activeCache.poll().getRenderedBitmap().recycle(); + } + } + } + + public void cacheThumbnail(PagePart part) { + synchronized (thumbnails) { + // If cache too big, remove and recycle + while (thumbnails.size() >= THUMBNAILS_CACHE_SIZE) { + thumbnails.remove(0).getRenderedBitmap().recycle(); + } + + // Then add thumbnail + addWithoutDuplicates(thumbnails, part); + } + + } + + public boolean upPartIfContained(int page, RectF pageRelativeBounds, int toOrder) { + PagePart fakePart = new PagePart(page, null, pageRelativeBounds, false, 0); + + PagePart found; + synchronized (passiveActiveLock) { + if ((found = find(passiveCache, fakePart)) != null) { + passiveCache.remove(found); + found.setCacheOrder(toOrder); + activeCache.offer(found); + return true; + } + + return find(activeCache, fakePart) != null; + } + } + + /** + * Return true if already contains the described PagePart + */ + public boolean containsThumbnail(int page, RectF pageRelativeBounds) { + PagePart fakePart = new PagePart(page, null, pageRelativeBounds, true, 0); + synchronized (thumbnails) { + for (PagePart part : thumbnails) { + if (part.equals(fakePart)) { + return true; + } + } + return false; + } + } + + /** + * Add part if it doesn't exist, recycle bitmap otherwise + */ + private void addWithoutDuplicates(Collection collection, PagePart newPart) { + for (PagePart part : collection) { + if (part.equals(newPart)) { + newPart.getRenderedBitmap().recycle(); + return; + } + } + collection.add(newPart); + } + + @Nullable + private static PagePart find(PriorityQueue vector, PagePart fakePart) { + for (PagePart part : vector) { + if (part.equals(fakePart)) { + return part; + } + } + return null; + } + + public List getPageParts() { + synchronized (passiveActiveLock) { + List parts = new ArrayList<>(passiveCache); + parts.addAll(activeCache); + return parts; + } + } + + public List getThumbnails() { + synchronized (thumbnails) { + return thumbnails; + } + } + + public void recycle() { + synchronized (passiveActiveLock) { + for (PagePart part : passiveCache) { + part.getRenderedBitmap().recycle(); + } + passiveCache.clear(); + for (PagePart part : activeCache) { + part.getRenderedBitmap().recycle(); + } + activeCache.clear(); + } + synchronized (thumbnails) { + for (PagePart part : thumbnails) { + part.getRenderedBitmap().recycle(); + } + thumbnails.clear(); + } + } + + class PagePartComparator implements Comparator { + @Override + public int compare(PagePart part1, PagePart part2) { + if (part1.getCacheOrder() == part2.getCacheOrder()) { + return 0; + } + return part1.getCacheOrder() > part2.getCacheOrder() ? 1 : -1; + } + } + +} diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/DecodingAsyncTask.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/DecodingAsyncTask.java index 24292ac9..911cebf7 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/DecodingAsyncTask.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/DecodingAsyncTask.java @@ -51,9 +51,19 @@ protected Throwable doInBackground(Void... params) { PDFView pdfView = pdfViewReference.get(); if (pdfView != null) { PdfDocument pdfDocument = docSource.createDocument(pdfView.getContext(), pdfiumCore, password); - pdfFile = new PdfFile(pdfiumCore, pdfDocument, pdfView.getPageFitPolicy(), getViewSize(pdfView), - userPages, pdfView.isSwipeVertical(), pdfView.getSpacingPx(), pdfView.isAutoSpacingEnabled(), - pdfView.isFitEachPage()); + pdfFile = new PdfFile( + pdfiumCore, + pdfDocument, + pdfView.getPageFitPolicy(), + getViewSize(pdfView), + userPages, + pdfView.isOnDualPageMode(), + pdfView.isSwipeVertical(), + pdfView.getSpacingPx(), + pdfView.isAutoSpacingEnabled(), + pdfView.isFitEachPage(), + pdfView.isOnLandscapeOrientation() + ); return null; } else { return new NullPointerException("pdfView == null"); diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PDFView.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PDFView.java index b8374721..2c080dda 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PDFView.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PDFView.java @@ -114,18 +114,26 @@ enum ScrollDir { private ScrollDir scrollDir = ScrollDir.NONE; - /** Rendered parts go to the cache manager */ + /** + * Rendered parts go to the cache manager + */ CacheManager cacheManager; - /** Animation manager manage all offset and zoom animation */ + /** + * Animation manager manage all offset and zoom animation + */ private AnimationManager animationManager; - /** Drag manager manage all touch events */ + /** + * Drag manager manage all touch events + */ private DragPinchManager dragPinchManager; PdfFile pdfFile; - /** The index of the current sequence */ + /** + * The index of the current sequence + */ private int currentPage; /** @@ -142,41 +150,65 @@ enum ScrollDir { */ private float currentYOffset = 0; - /** The zoom level, always >= 1 */ + /** + * The zoom level, always >= 1 + */ private float zoom = 1f; - /** True if the PDFView has been recycled */ + /** + * True if the PDFView has been recycled + */ private boolean recycled = true; - /** Current state of the view */ + /** + * Current state of the view + */ private State state = State.DEFAULT; - /** Async task used during the loading phase to decode a PDF document */ + /** + * Async task used during the loading phase to decode a PDF document + */ private DecodingAsyncTask decodingAsyncTask; - /** The thread {@link #renderingHandler} will run on */ + /** + * The thread {@link #renderingHandler} will run on + */ private HandlerThread renderingHandlerThread; - /** Handler always waiting in the background and rendering tasks */ + /** + * Handler always waiting in the background and rendering tasks + */ RenderingHandler renderingHandler; private PagesLoader pagesLoader; Callbacks callbacks = new Callbacks(); - /** Paint object for drawing */ + /** + * Paint object for drawing + */ private Paint paint; - /** Paint object for drawing debug stuff */ + /** + * Paint object for drawing debug stuff + */ private Paint debugPaint; - /** Policy for fitting pages to screen */ + /** + * 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 dualPageMode = false; + + private boolean isLandscapeOrientation = false; + + /** + * True if should scroll through pages vertically instead of horizontally + */ private boolean swipeVertical = true; private boolean enableSwipe = true; @@ -187,7 +219,9 @@ enum ScrollDir { private boolean pageSnap = true; - /** Pdfium core for loading and rendering PDFs */ + /** + * Pdfium core for loading and rendering PDFs + */ private PdfiumCore pdfiumCore; private ScrollHandle scrollHandle; @@ -218,30 +252,46 @@ ScrollHandle getScrollHandle() { */ private boolean renderDuringScale = false; - /** Antialiasing and bitmap filtering */ + /** + * 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 */ + /** + * Spacing between pages, in px + */ private int spacingPx = 0; - /** Add dynamic spacing to fit each page separately on the screen. */ + /** + * Add dynamic spacing to fit each page separately on the screen. + */ private boolean autoSpacing = false; - /** Fling a single page at a time */ + /** + * Fling a single page at a time + */ private boolean pageFling = true; - /** Pages numbers used when calling onDrawAllListener */ + /** + * Pages numbers used when calling onDrawAllListener + */ private List onDrawPagesNums = new ArrayList<>(10); - /** Holds info whether view has been added to layout and has width and height */ + /** + * Holds info whether view has been added to layout and has width and height + */ private boolean hasSize = false; - /** Holds last used Configurator that should be loaded when view has size */ + /** + * Holds last used Configurator that should be loaded when view has size + */ private Configurator waitingDocumentConfigurator; - /** Construct the initial view */ + /** + * Construct the initial view + */ public PDFView(Context context, AttributeSet set) { super(context, set); @@ -452,7 +502,9 @@ public boolean isRecycled() { return recycled; } - /** Handle fling animation */ + /** + * Handle fling animation + */ @Override public void computeScroll() { super.computeScroll(); @@ -493,10 +545,10 @@ protected void onSizeChanged(int w, int h, int oldw, int oldh) { float relativeCenterPointInStripXOffset; float relativeCenterPointInStripYOffset; - if (swipeVertical){ + if (swipeVertical) { relativeCenterPointInStripXOffset = centerPointInStripXOffset / pdfFile.getMaxPageWidth(); relativeCenterPointInStripYOffset = centerPointInStripYOffset / pdfFile.getDocLen(zoom); - }else { + } else { relativeCenterPointInStripXOffset = centerPointInStripXOffset / pdfFile.getDocLen(zoom); relativeCenterPointInStripYOffset = centerPointInStripYOffset / pdfFile.getMaxPageHeight(); } @@ -506,12 +558,12 @@ protected void onSizeChanged(int w, int h, int oldw, int oldh) { if (swipeVertical) { currentXOffset = -relativeCenterPointInStripXOffset * pdfFile.getMaxPageWidth() + w * 0.5f; - currentYOffset = -relativeCenterPointInStripYOffset * pdfFile.getDocLen(zoom) + h * 0.5f ; - }else { + currentYOffset = -relativeCenterPointInStripYOffset * pdfFile.getDocLen(zoom) + h * 0.5f; + } else { currentXOffset = -relativeCenterPointInStripXOffset * pdfFile.getDocLen(zoom) + w * 0.5f; currentYOffset = -relativeCenterPointInStripYOffset * pdfFile.getMaxPageHeight() + h * 0.5f; } - moveTo(currentXOffset,currentYOffset); + moveTo(currentXOffset, currentYOffset); loadPageByOffset(); } @@ -667,7 +719,9 @@ private void drawWithListener(Canvas canvas, int page, OnDrawListener listener) } } - /** Draw a given PagePart on the canvas */ + /** + * Draw a given PagePart on the canvas + */ private void drawPart(Canvas canvas, PagePart part) { // Can seem strange, but avoid lot of calls RectF pageRelativeBounds = part.getPageRelativeBounds(); @@ -747,15 +801,22 @@ public void loadPages() { redraw(); } - /** Called when the PDF is loaded */ + /** + * Called when the PDF is loaded + */ void loadComplete(PdfFile pdfFile) { state = State.LOADED; this.pdfFile = pdfFile; + if (renderingHandlerThread == null) { + renderingHandlerThread = new HandlerThread("PDF renderer"); + } + if (!renderingHandlerThread.isAlive()) { renderingHandlerThread.start(); } + renderingHandler = new RenderingHandler(renderingHandlerThread.getLooper(), this); renderingHandler.start(); @@ -924,10 +985,14 @@ void loadPageByOffset() { } } + public void performPageSnap() { + performPageSnap(true); + } + /** * Animate to the nearest snapping position for the current SnapPolicy */ - public void performPageSnap() { + public void performPageSnap(boolean withAnimation) { if (!pageSnap || pdfFile == null || pdfFile.getPagesCount() == 0) { return; } @@ -939,9 +1004,17 @@ public void performPageSnap() { float offset = snapOffsetForPage(centerPage, edge); if (swipeVertical) { - animationManager.startYAnimation(currentYOffset, -offset); + if (withAnimation) { + animationManager.startYAnimation(currentYOffset, -offset); + } else { + moveTo(currentXOffset, -offset); + } } else { - animationManager.startXAnimation(currentXOffset, -offset); + if (withAnimation) { + animationManager.startXAnimation(currentXOffset, -offset); + } else { + moveTo(-offset, currentYOffset); + } } } @@ -1179,6 +1252,22 @@ public boolean isBestQuality() { return bestQuality; } + public boolean isOnDualPageMode() { + return dualPageMode; + } + + public boolean isOnLandscapeOrientation() { + return isLandscapeOrientation; + } + + public void setLandscapeOrientation(boolean landscapeOrientation) { + this.isLandscapeOrientation = landscapeOrientation; + } + + public void setDualPageMode(boolean dualPageMode) { + this.dualPageMode = dualPageMode; + } + public boolean isSwipeVertical() { return swipeVertical; } @@ -1263,7 +1352,9 @@ public boolean doRenderDuringScale() { return renderDuringScale; } - /** Returns null if document is not loaded */ + /** + * Returns null if document is not loaded + */ public PdfDocument.Meta getDocumentMeta() { if (pdfFile == null) { return null; @@ -1271,7 +1362,9 @@ public PdfDocument.Meta getDocumentMeta() { return pdfFile.getMetaData(); } - /** Will be empty until document is loaded */ + /** + * Will be empty until document is loaded + */ public List getTableOfContents() { if (pdfFile == null) { return Collections.emptyList(); @@ -1279,7 +1372,9 @@ public List getTableOfContents() { return pdfFile.getBookmarks(); } - /** Will be empty until document is loaded */ + /** + * Will be empty until document is loaded + */ public List getLinks(int page) { if (pdfFile == null) { return Collections.emptyList(); @@ -1287,32 +1382,44 @@ public List getLinks(int page) { return pdfFile.getPageLinks(page); } - /** Use an asset file as the pdf source */ + /** + * Use an asset file as the pdf source + */ public Configurator fromAsset(String assetName) { return new Configurator(new AssetSource(assetName)); } - /** Use a file as the pdf source */ + /** + * Use a file as the pdf source + */ public Configurator fromFile(File file) { return new Configurator(new FileSource(file)); } - /** Use URI as the pdf source, for use with content providers */ + /** + * Use URI as the pdf source, for use with content providers + */ public Configurator fromUri(Uri uri) { return new Configurator(new UriSource(uri)); } - /** Use bytearray as the pdf source, documents is not saved */ + /** + * Use bytearray as the pdf source, documents is not saved + */ public Configurator fromBytes(byte[] bytes) { return new Configurator(new ByteArraySource(bytes)); } - /** Use stream as the pdf source. Stream will be written to bytearray, because native code does not support Java Streams */ + /** + * Use stream as the pdf source. Stream will be written to bytearray, because native code does not support Java Streams + */ public Configurator fromStream(InputStream stream) { return new Configurator(new InputStreamSource(stream)); } - /** Use custom source as pdf source */ + /** + * Use custom source as pdf source + */ public Configurator fromSource(DocumentSource docSource) { return new Configurator(docSource); } @@ -1353,6 +1460,10 @@ public class Configurator { private int defaultPage = 0; + private boolean landscapeOrientation = false; + + private boolean dualPageMode = false; + private boolean swipeHorizontal = false; private boolean annotationRendering = false; @@ -1461,6 +1572,16 @@ public Configurator defaultPage(int defaultPage) { return this; } + public Configurator landscapeOrientation(boolean landscapeOrientation) { + this.landscapeOrientation = landscapeOrientation; + return this; + } + + public Configurator dualPageMode(boolean dualPageMode) { + this.dualPageMode = dualPageMode; + return this; + } + public Configurator swipeHorizontal(boolean swipeHorizontal) { this.swipeHorizontal = swipeHorizontal; return this; @@ -1542,6 +1663,8 @@ public void load() { PDFView.this.setNightMode(nightMode); PDFView.this.enableDoubletap(enableDoubletap); PDFView.this.setDefaultPage(defaultPage); + PDFView.this.setLandscapeOrientation(landscapeOrientation); + PDFView.this.setDualPageMode(dualPageMode); PDFView.this.setSwipeVertical(!swipeHorizontal); PDFView.this.enableAnnotationRendering(annotationRendering); PDFView.this.setScrollHandle(scrollHandle); diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PdfFile.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PdfFile.java index fdc104f2..3610bcbb 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PdfFile.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/PdfFile.java @@ -51,6 +51,8 @@ class PdfFile { private SizeF maxHeightPageSize = new SizeF(0, 0); /** Scaled page with maximum width */ private SizeF maxWidthPageSize = new SizeF(0, 0); + /** True if dualPageMode is on*/ + private boolean showTwoPages; /** True if scrolling is vertical, else it's horizontal */ private boolean isVertical; /** Fixed spacing between pages in pixels */ @@ -69,6 +71,8 @@ class PdfFile { * else the largest page fits and other pages scale relatively */ private final boolean fitEachPage; + + private final boolean isLandscape; /** * The pages the user want to display in order * (ex: 0, 2, 2, 8, 8, 1, 1, 1) @@ -76,7 +80,8 @@ class PdfFile { private int[] originalUserPages; PdfFile(PdfiumCore pdfiumCore, PdfDocument pdfDocument, FitPolicy pageFitPolicy, Size viewSize, int[] originalUserPages, - boolean isVertical, int spacing, boolean autoSpacing, boolean fitEachPage) { + boolean showTwoPages, boolean isVertical, int spacing, boolean autoSpacing, boolean fitEachPage, boolean isLandscape) { + this.showTwoPages = showTwoPages; this.pdfiumCore = pdfiumCore; this.pdfDocument = pdfDocument; this.pageFitPolicy = pageFitPolicy; @@ -85,6 +90,7 @@ class PdfFile { this.spacingPx = spacing; this.autoSpacing = autoSpacing; this.fitEachPage = fitEachPage; + this.isLandscape = isLandscape; setup(viewSize); } @@ -122,7 +128,7 @@ public void recalculatePageSizes(Size viewSize) { maxHeightPageSize = calculator.getOptimalMaxHeightPageSize(); for (Size size : originalPageSizes) { - pageSizes.add(calculator.calculate(size)); + pageSizes.add(calculator.calculate(size, showTwoPages, isLandscape)); } if (autoSpacing) { prepareAutoSpacing(viewSize); 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..2faa392b 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 @@ -4,7 +4,7 @@ import android.graphics.Color; import android.graphics.drawable.Drawable; import android.os.Handler; -import android.support.v4.content.ContextCompat; +import androidx.core.content.ContextCompat; import android.util.TypedValue; import android.view.MotionEvent; import android.view.ViewGroup; @@ -78,11 +78,7 @@ public void setupLayout(PDFView pdfView) { } } - if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) { - setBackgroundDrawable(background); - } else { - setBackground(background); - } + setBackground(background); LayoutParams lp = new LayoutParams(Util.getDP(context, width), Util.getDP(context, height)); lp.setMargins(0, 0, 0, 0); @@ -149,7 +145,11 @@ private void calculateMiddle() { pos = getY(); viewSize = getHeight(); pdfViewSize = pdfView.getHeight(); - } else { + } else if (pdfView.isOnDualPageMode()){ + pos = getX(); + viewSize = getWidth() / 2f; + pdfViewSize = pdfView.getWidth() / 2f; + } else { pos = getX(); viewSize = getWidth(); pdfViewSize = pdfView.getWidth(); diff --git a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/PageSizeCalculator.java b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/PageSizeCalculator.java index 4d678c98..e7f35a3b 100644 --- a/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/PageSizeCalculator.java +++ b/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/util/PageSizeCalculator.java @@ -15,6 +15,9 @@ */ package com.github.barteksc.pdfviewer.util; +import android.app.Activity; +import android.util.Log; +import android.content.pm.ActivityInfo; import com.shockwave.pdfium.util.Size; import com.shockwave.pdfium.util.SizeF; @@ -40,11 +43,16 @@ public PageSizeCalculator(FitPolicy fitPolicy, Size originalMaxWidthPageSize, Si calculateMaxPages(); } - public SizeF calculate(Size pageSize) { + public SizeF calculate(Size pageSize, boolean showTwoPages, boolean isLandscape) { if (pageSize.getWidth() <= 0 || pageSize.getHeight() <= 0) { return new SizeF(0, 0); } - float maxWidth = fitEachPage ? viewSize.getWidth() : pageSize.getWidth() * widthRatio; + float maxWidth = 0; + if(showTwoPages && !isLandscape){ + maxWidth = fitEachPage ? viewSize.getWidth() : pageSize.getWidth() / 2 * widthRatio; + } else { + maxWidth = fitEachPage ? viewSize.getWidth() : pageSize.getWidth() * widthRatio; + } float maxHeight = fitEachPage ? viewSize.getHeight() : pageSize.getHeight() * heightRatio; switch (fitPolicy) { case HEIGHT: diff --git a/build.gradle b/build.gradle index 0a9a0ba0..96597d9a 100644 --- a/build.gradle +++ b/build.gradle @@ -1,13 +1,11 @@ - buildscript { repositories { google() jcenter() + maven { url 'https://jitpack.io' } } dependencies { - classpath 'com.android.tools.build:gradle:3.4.2' - classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4' - classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' + classpath 'com.android.tools.build:gradle:4.0.1' } } @@ -15,5 +13,6 @@ allprojects { repositories { google() jcenter() + maven { url 'https://jitpack.io' } } } diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 00000000..2d8d1e4d --- /dev/null +++ b/gradle.properties @@ -0,0 +1 @@ +android.useAndroidX=true \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 3c7abdf1..f3d88b1c 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1a59b22b..671c8396 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sun Aug 18 01:14:14 CEST 2019 +#Tue Aug 04 20:30:19 EEST 2020 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip diff --git a/gradlew b/gradlew index 91a7e269..2fe81a7d 100755 --- a/gradlew +++ b/gradlew @@ -1,4 +1,20 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# 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 +# +# https://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. +# ############################################################################## ## @@ -6,20 +22,38 @@ ## ############################################################################## -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" -warn ( ) { +warn () { echo "$*" } -die ( ) { +die () { echo echo "$*" echo @@ -30,6 +64,7 @@ die ( ) { cygwin=false msys=false darwin=false +nonstop=false case "`uname`" in CYGWIN* ) cygwin=true @@ -40,31 +75,11 @@ case "`uname`" in MINGW* ) msys=true ;; + NONSTOP* ) + nonstop=true + ;; esac -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -90,7 +105,7 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then @@ -110,10 +125,11 @@ if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` @@ -138,27 +154,30 @@ if $cygwin ; then else eval `echo args$i`="\"$arg\"" fi - i=$((i+1)) + i=`expr $i + 1` done case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " } -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 43a9656f..9618d8d9 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,21 +1,18 @@ -@REM -@REM Copyright 2014 Joan Zapata -@REM -@REM This file is part of Android-pdfview. -@REM -@REM Android-pdfview is free software: you can redistribute it and/or modify -@REM it under the terms of the GNU General Public License as published by -@REM the Free Software Foundation, either version 3 of the License, or -@REM (at your option) any later version. -@REM -@REM Android-pdfview is distributed in the hope that it will be useful, -@REM but WITHOUT ANY WARRANTY; without even the implied warranty of -@REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -@REM GNU General Public License for more details. -@REM -@REM You should have received a copy of the GNU General Public License -@REM along with Android-pdfview. If not, see . -@REM +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem @if "%DEBUG%" == "" @echo off @rem ########################################################################## @@ -27,14 +24,14 @@ @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome @@ -65,10 +62,9 @@ echo location of your Java installation. goto fail :init -@rem Get command-line arguments, handling Windowz variants +@rem Get command-line arguments, handling Windows variants if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args :win9xME_args @rem Slurp the command line arguments. @@ -79,11 +75,6 @@ set _SKIP=2 if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ :execute @rem Setup the command line diff --git a/sample/build.gradle b/sample/build.gradle index 133bcdde..d10f0be5 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -1,32 +1,26 @@ -buildscript { - repositories { - google() - jcenter() - } -} - -repositories { - google() - jcenter() -} - apply plugin: 'com.android.application' android { - compileSdkVersion 28 + compileSdkVersion 29 defaultConfig { - minSdkVersion 14 - targetSdkVersion 28 + applicationId "com.pdfviewer" + minSdkVersion 16 + targetSdkVersion 29 versionCode 3 versionName "3.0.0" } + buildTypes { + release { + minifyEnabled true + debuggable true + proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" + } + } } dependencies { implementation project(':android-pdf-viewer') - implementation 'com.android.support:appcompat-v7:28.0.0' - implementation 'org.androidannotations:androidannotations-api:4.6.0' - annotationProcessor "org.androidannotations:androidannotations:4.6.0" + implementation 'androidx.appcompat:appcompat:1.1.0' } diff --git a/sample/src/main/AndroidManifest.xml b/sample/src/main/AndroidManifest.xml index d6ce646c..d3b2dc7f 100644 --- a/sample/src/main/AndroidManifest.xml +++ b/sample/src/main/AndroidManifest.xml @@ -8,7 +8,7 @@ android:label="@string/app_name" android:theme="@style/Theme.AppCompat.Light"> diff --git a/sample/src/main/java/com/github/barteksc/sample/PDFViewActivity.java b/sample/src/main/java/com/github/barteksc/sample/PDFViewActivity.java index d23b0008..16249772 100755 --- a/sample/src/main/java/com/github/barteksc/sample/PDFViewActivity.java +++ b/sample/src/main/java/com/github/barteksc/sample/PDFViewActivity.java @@ -18,17 +18,23 @@ import android.content.ActivityNotFoundException; import android.content.Intent; import android.content.pm.PackageManager; +import android.content.res.Configuration; import android.database.Cursor; import android.graphics.Color; import android.net.Uri; +import android.os.Bundle; import android.provider.OpenableColumns; -import android.support.annotation.NonNull; -import android.support.v4.app.ActivityCompat; -import android.support.v4.content.ContextCompat; -import android.support.v7.app.AppCompatActivity; import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; + import com.github.barteksc.pdfviewer.PDFView; import com.github.barteksc.pdfviewer.listener.OnLoadCompleteListener; import com.github.barteksc.pdfviewer.listener.OnPageChangeListener; @@ -37,18 +43,8 @@ import com.github.barteksc.pdfviewer.util.FitPolicy; import com.shockwave.pdfium.PdfDocument; -import org.androidannotations.annotations.AfterViews; -import org.androidannotations.annotations.EActivity; -import org.androidannotations.annotations.NonConfigurationInstance; -import org.androidannotations.annotations.OnActivityResult; -import org.androidannotations.annotations.OptionsItem; -import org.androidannotations.annotations.OptionsMenu; -import org.androidannotations.annotations.ViewById; - import java.util.List; -@EActivity(R.layout.activity_main) -@OptionsMenu(R.menu.options) public class PDFViewActivity extends AppCompatActivity implements OnPageChangeListener, OnLoadCompleteListener, OnPageErrorListener { @@ -60,18 +56,46 @@ public class PDFViewActivity extends AppCompatActivity implements OnPageChangeLi public static final String SAMPLE_FILE = "sample.pdf"; public static final String READ_EXTERNAL_STORAGE = "android.permission.READ_EXTERNAL_STORAGE"; - @ViewById - PDFView pdfView; + private PDFView pdfView; + + private Uri uri; + + private Integer pageNumber = 0; + + private String pdfFileName; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + initViews(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.options, menu); + return super.onCreateOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.pickFile: + pickFile(); - @NonConfigurationInstance - Uri uri; + break; + } - @NonConfigurationInstance - Integer pageNumber = 0; + return true; + } - String pdfFileName; + private void initViews() { + pdfView = findViewById(R.id.pdfView); + + afterViews(); + } - @OptionsItem(R.id.pickFile) void pickFile() { int permissionCheck = ContextCompat.checkSelfPermission(this, READ_EXTERNAL_STORAGE); @@ -100,7 +124,6 @@ void launchPicker() { } } - @AfterViews void afterViews() { pdfView.setBackgroundColor(Color.LTGRAY); if (uri != null) { @@ -112,6 +135,9 @@ void afterViews() { } private void displayFromAsset(String assetFileName) { + boolean isLandscape = false; + int orientation = this.getResources().getConfiguration().orientation; + isLandscape = orientation == Configuration.ORIENTATION_LANDSCAPE; pdfFileName = assetFileName; pdfView.fromAsset(SAMPLE_FILE) @@ -119,8 +145,14 @@ private void displayFromAsset(String assetFileName) { .onPageChange(this) .enableAnnotationRendering(true) .onLoad(this) + .landscapeOrientation(isLandscape) + .dualPageMode(false) .scrollHandle(new DefaultScrollHandle(this)) - .spacing(10) // in dp + .spacing(0) // in dp + .enableSwipe(true) + .swipeHorizontal(true) + .pageFling(true) + .fitEachPage(false) .onPageError(this) .pageFitPolicy(FitPolicy.BOTH) .load(); @@ -135,12 +167,22 @@ private void displayFromUri(Uri uri) { .enableAnnotationRendering(true) .onLoad(this) .scrollHandle(new DefaultScrollHandle(this)) - .spacing(10) // in dp + .spacing(0) // in dp + .dualPageMode(true) + .enableSwipe(true) + .swipeHorizontal(true) + .pageFling(true) .onPageError(this) .load(); } - @OnActivityResult(REQUEST_CODE) + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + + onResult(resultCode, data); + } + public void onResult(int resultCode, Intent intent) { if (resultCode == RESULT_OK) { uri = intent.getData();