Android加载PDF文件的使用

Android PdfViewer

AndroidPdfViewer 1.x可在AndroidPdfViewerV1 repo上获得,可以独立开发。版本1.x使用不同的引擎在画布上绘制文档,因此如果您不喜欢2.x版本,请尝试1.x.

图书馆在Android上显示的PDF文档,用animationsgestureszoomdouble tap支持。它基于PdfiumAndroid来解码PDF文件。适用于API 11(Android 3.0)及更高版本。在Apache License 2.0下获得许可。

3.1.0-beta.1有什么新功能?

  • 合并拉取请求#557用于捕捉页面(逐页滚动)
  • 合并拉出请求#618用于夜间模式
  • 合并拉取请求#566 OnLongTapListener
  • 将PdfiumAndroid更新为1.9.0,而c++_shared不是使用gnustl_static
  • 更新Gradle插件
  • 将编译SDK和支持库更新到26
  • 将最低SDK更改为14

3.0 API的变化

  • 换成Contants.PRELOAD_COUNTPRELOAD_OFFSET
  • 删除PDFView#fitToWidth()(没有参数的变体)
  • 删除Configurator#invalidPageColor(int)方法,因为无法呈现无效页面
  • OnRenderListener#onInitiallyRendered(int)方法中删除了页面大小参数,因为文档可能具有不同的页面大小
  • 删除PDFView#setSwipeVertical()方法

安装

添加到build.gradle

compile 'com.github.barteksc:android-pdf-viewer:3.1.0-beta.1'

或者如果你想使用更稳定的版本:

compile 'com.github.barteksc:android-pdf-viewer:2.8.2'

库在jcenter存储库中可用,可能它很快就会在Maven Central中。

ProGuard的

如果您使用的是ProGuard,请将以下规则添加到proguard配置文件中:

1
-keep class com.shockwave.**

在布局中包含PDFView

1
2
3
4
<com.github.barteksc.pdfviewer.PDFView
android:id="@+id/pdfView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

加载PDF文件

所有可用选项都带有默认值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
pdfView.fromUri(Uri)
or
pdfView.fromFile(File)
or
pdfView.fromBytes(byte[])
or
pdfView.fromStream(InputStream) // stream is written to bytearray - native code cannot use Java Streams
or
pdfView.fromSource(DocumentSource)
or
pdfView.fromAsset(String)
.pages(0, 2, 1, 3, 3, 3) // all pages are displayed by default
.enableSwipe(true) // allows to block changing pages using swipe
.swipeHorizontal(false)
.enableDoubletap(true)
.defaultPage(0)
// allows to draw something on the current page, usually visible in the middle of the screen
.onDraw(onDrawListener)
// allows to draw something on all pages, separately for every page. Called only for visible pages
.onDrawAll(onDrawListener)
.onLoad(onLoadCompleteListener) // called after document is loaded and starts to be rendered
.onPageChange(onPageChangeListener)
.onPageScroll(onPageScrollListener)
.onError(onErrorListener)
.onPageError(onPageErrorListener)
.onRender(onRenderListener) // called after document is rendered for the first time
// called on single tap, return true if handled, false to toggle scroll handle visibility
.onTap(onTapListener)
.onLongPress(onLongPressListener)
.enableAnnotationRendering(false) // render annotations (such as comments, colors or forms)
.password(null)
.scrollHandle(null)
.enableAntialiasing(true) // improve rendering a little bit on low-res screens
// spacing between pages in dp. To define spacing color, set view background
.spacing(0)
.autoSpacing(false) // add dynamic spacing to fit each page on its own on the screen
.linkHandler(DefaultLinkHandler)
.pageFitPolicy(FitPolicy.WIDTH)
.pageSnap(true) // snap pages to screen boundaries
.pageFling(false) // make a fling change only a single page like ViewPager
.nightMode(false) // toggle night mode
.load();

注意

pages 是可选的,它允许您根据需要过滤和排序PDF页面

滚动手柄

Scroll handle是从1.x分支替换ScrollBar

从版本2.1.0将PDFView放在RelativeLayout中以使用ScrollHandle不是必需的,您可以使用任何布局。

要使用滚动手柄,只需使用方法注册它Configurator#scrollHandle()。此方法接受ScrollHandle接口的实现。

AndroidPdfViewer附带默认实现,您可以使用它 .scrollHandle(new DefaultScrollHandle(this))DefaultScrollHandle位于右侧(垂直滚动时)或底部(水平滚动时)。通过使用带有第二个参数(new DefaultScrollHandle(this, true))的构造函数,可以将句柄放在左侧或顶部。

您还可以创建自定义滚动句柄,只需实现ScrollHandle界面。所有方法都记录为接口上的Javadoc注释。

文件来源

2.3.0版引入了文档源,它们只是PDF文档的提供者。每个提供程序都实现DocumentSource接口。预定义的提供程序可以在com.github.barteksc.pdfviewer.source包中找到,可以用作创建自定义提供程序的示例。

预定义的提供程序可以与速记方法一起使用:

1
2
3
4
5
pdfView.fromUri(Uri)
pdfView.fromFile(File)
pdfView.fromBytes(byte[])
pdfView.fromStream(InputStream)
pdfView.fromAsset(String)

自定义提供程序可与pdfView.fromSource(DocumentSource)方法一起使用。

链接

3.0.0版引入了对PDF文档中链接的支持。默认情况下,使用DefaultLinkHandler 并单击引用同一文档中的页面的链接会导致跳转到目标页面并单击以某个URI为目标的链接导致在默认应用程序中打开它。

您还可以创建自定义链接处理程序,只需实现LinkHandler接口并使用Configurator#linkHandler(LinkHandler)方法进行设置 。查看DefaultLinkHandler 源以实现自定义行为。

页面符合政策

从版本3.0.0开始,库支持以3种模式将页面装入屏幕:

  • 宽度 - 最宽页面的宽度等于屏幕宽度
  • 高度 - 最高页面的高度等于屏幕高度
  • BOTH - 基于最宽和最高的页面,每个页面都缩放为在屏幕上完全可见

除了选定的策略之外,每个页面都会缩放到相对于其他页面的大小。

可以使用适合的策略进行设置Configurator#pageFitPolicy(FitPolicy)。默认策略是WIDTH

其他选项

位图质量

默认情况下,生成的位图使用格式压缩RGB_565以减少内存消耗。ARGB_8888可以使用pdfView.useBestQuality(true)方法强制渲染。

双击缩放

有三种缩放级别:分钟(默认1),中间(默认1.75)和最大(默认3)。在第一次双击时,视图缩放到中等水平,在第二个到最大水平,第三个返回到最低水平。如果您处于中级和最高级别之间,则双击会导致缩放到最大值,依此类推。

可以使用以下方法更改缩放级别:

1
2
3
void setMinZoom(float zoom);
void setMidZoom(float zoom);
void setMaxZoom(float zoom);

可能的问题

为什么导致apk太大了?

Android PdfViewer依赖于PdfiumAndroid,它是许多架构的本机库集(大约16 MB)。Apk必须包含所有这些库,以便在市场上的每个设备上运行。幸运的是,Google Play允许我们上传多个apks,例如每个架构一个。有一篇关于自动将您的应用程序拆分为多个apks的文章,可在此处获得。最重要的部分是使用APK Splits改进多个APK创建和版本代码处理,但整篇文章值得一读。您只需要在您的应用程序中执行此操作,无需分支PdfiumAndroid等。

为什么我无法从URL打开PDF?

下载文件是一个长时间运行的过程,必须知道Activity生命周期,必须支持一些配置,数据清理和缓存,因此创建这样的模块可能最终会成为新的库。

如何在配置更改后显示上次打开的页面?

您必须存储当前页码然后进行设置pdfView.defaultPage(page),请参阅示例应用程序

如何将文档放入屏幕宽度(例如,方向更改)?

FitPolicy.WIDTH如果要在具有不同页面大小的文档中放置所需页面,请使用策略或添加以下代码段:

1
2
3
4
5
6
Configurator.onRender(new OnRenderListener() {
@Override
public void onInitiallyRendered(int pages, float pageWidth, float pageHeight) {
pdfView.fitToWidth(pageIndex);
}
});

如何像ViewPager一样滚动浏览单个页面?

您可以使用以下设置的组合来获得类似于ViewPager的滚动和拖动行为:

1
2
3
4
.swipeHorizontal(true)
.pageSnap(true)
.autoSpacing(true)
.pageFling(true)

Demo地址:https://github.com/zhangmiaocc/AndroidPDFView

参考:https://github.com/barteksc/AndroidPdfViewer

坚持原创技术分享,您的支持将鼓励我继续创作!