1.1 PDF View的使用
- 首先我们需要加载依赖库
compile 'com.joanzapata.pdfview:android-pdfview:1.0.4@aar'
- 创建本地文件assets,存放本地的文件 sample.pdf。这里先只讲一下本地的,在线的稍后再提。
- 在layout文件中编写布局文件
<com.joanzapata.pdfview.PDFView
android:id="@+id/pdfview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
- 在代码中引用
例子中的模板是这样的
pdfView.fromFile(file) //设置pdf文件地址
.defaultPage(1) //设置默认显示第1页
.onPageChange(this) //设置翻页监听
.onLoad(this) //设置加载监听
.onDraw(this) //绘图监听
.showMinimap(false) //pdf放大的时候,是否在屏幕的右上角生成小地图
.swipeVertical( false ) //pdf文档翻页是否是垂直翻页,默认是左右滑动翻页
.enableSwipe(true) //是否允许翻页,默认是允许翻
// .pages( 2 , 3 , 4 , 5 ) //把2 , 3 , 4 , 5 过滤掉
.load();
- pages是可选的,它允许您根据需要过滤和排序PDF的页面
- onDraw也是可选的,并且允许您在当前页面上方的提供的画布上绘制某些东西
里面的属性都在代码中有注释,按照你的要求自己定制。
我代码中的是这样的
public class MainActivity extends AppCompatActivity {
<span class="hljs-meta">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onCreate</span><span class="hljs-params">(Bundle savedInstanceState)</span> </span>{
<span class="hljs-keyword">super</span>.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PDFView pdfView = (PDFView) findViewById(R.id.pdfview);
<span class="hljs-comment">// 这个测试例子中,assets目录下sample.pdf</span>
<span class="hljs-comment">// 缺省把该pdf定位到第一页。</span>
pdfView.fromAsset(<span class="hljs-string">"sample.pdf"</span>)
.defaultPage(<span class="hljs-number">1</span>)
.onPageChange(<span class="hljs-keyword">new</span> OnPageChangeListener() {
<span class="hljs-meta">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onPageChanged</span><span class="hljs-params">(<span class="hljs-keyword">int</span> page, <span class="hljs-keyword">int</span> pageCount)</span> </span>{
<span class="hljs-comment">// 当用户在翻页时候将回调。</span>
Toast.makeText(getApplicationContext(), page + <span class="hljs-string">" / "</span> + pageCount, Toast.LENGTH_SHORT).show();
}
}).load();
}
}
运行效果:
加载的pdf文件,来源于 github项目中的文件sample.pdf。我自己下载github项目下来本地编译一直出问题,后面就直接导入依赖库来运行,发现没什么问题。
开源gitgub地址:https://github.com/JoanZapata/android-pdfview
2. 注意
因为看有人评论说项目依赖,或者编译出现问题什么的,然后查看了一下这个开源项目。作者已经在项目里面声明了:
翻译:您可以在这里找到一个很好的替代品,这是一个依靠Pdfium而不是Vudroid / MuPDF的叉解码PDF文件,允许它使用Apache许可证2.0,这给您更多的自由。
所以如果出现问题试用下这个。
github地址:https://github.com/barteksc/AndroidPdfViewer
下载下来了,编译通过没什么问题。使用起来和上面的差不多。
- 导向项目包
compile 'com.github.barteksc:android-pdf-viewer:2.8.0'
- 在layout文件创建你的布局文件
<com.joanzapata.pdfview.PDFView
android:id="@+id/pdfView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
- 在项目中的编写你的需求,还是在你的assets文件下放一个sample.pdf的文件,在java代码中编写需求
public class MainActivity extends AppCompatActivity {
<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String TAG = <span class="hljs-string">"MainActivity.class.getSimpleName()"</span>;
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String SAMPLE_FILE = <span class="hljs-string">"sample.pdf"</span>;
<span class="hljs-keyword">private</span> PDFView pdfView;
<span class="hljs-meta">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onCreate</span><span class="hljs-params">(Bundle savedInstanceState)</span> </span>{
<span class="hljs-keyword">super</span>.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pdfView = (PDFView)findViewById(R.id.PDFView);
pdfView.fromAsset(<span class="hljs-string">"sample.pdf"</span>)
.defaultPage(<span class="hljs-number">0</span>)
.onPageChange(<span class="hljs-keyword">new</span> OnPageChangeListener() {
<span class="hljs-meta">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onPageChanged</span><span class="hljs-params">(<span class="hljs-keyword">int</span> page, <span class="hljs-keyword">int</span> pageCount)</span> </span>{
setTitle(String.format(<span class="hljs-string">"%s %s /%s"</span>,SAMPLE_FILE,page+<span class="hljs-number">1</span>,pageCount));
}
})
.enableAnnotationRendering(<span class="hljs-keyword">true</span>)
.swipeHorizontal(<span class="hljs-keyword">false</span>)
.spacing(<span class="hljs-number">10</span>)
.onPageError(<span class="hljs-keyword">new</span> OnPageErrorListener() {
<span class="hljs-meta">@SuppressLint</span>(<span class="hljs-string">"LongLogTag"</span>)
<span class="hljs-meta">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onPageError</span><span class="hljs-params">(<span class="hljs-keyword">int</span> page, Throwable t)</span> </span>{
Log.e(TAG, <span class="hljs-string">"onPageError: Cannot load page"</span>+page );
}
})
.load();
}
}
3. 其他加载PDF的方式
Android 系统对PDF的支持并不完美,在实际操作中,我们要想PDF能被好好阅读,需要自己采用一些别的方案。
3.1 远程加载的方案
提供一种思路,我们可以在自己的服务器上将PDF作为一个文件放置,然后将服务器上的文件下载到本地,再就是我们将服务器的文件通过上面介绍的方式加载出来。
3.2 通过在WebView调用GoogleDocs功能
这种方式使用起来很简单,就和普通的WebView加载Url一样使用,缺点是,因为我们国内目前无法直接访问Google提供的服务,所以仅供参考。
public void setDocumentPath(final String path) {
WebView webView = (WebView) findViewById(R.id.webview);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setPluginsEnabled(true);
webView.loadUrl("https://docs.google.com/viewer?url=http://www.asce1885.com/cms/wwwroot/ng/downLoad/011615200732.pdf");
}
3.3 调起第三方支持 PDF 阅读的应用
前提条件:
- PDF文件下载到本地
- 手机中安装了PDF阅读的应用
public Intent getPdfFileIntent(File file) {
Intent intent = new Intent("android.intent.action.VIEW");
intent.addCategory("android.intent.category.DEFAULT");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri uri = Uri.fromFile(file);
intent.setDataAndType(uri, "application/pdf");
return Intent.createChooser(intent, "Open File");
}
因为这个不是本应用的,所以会跳出本应用,然后跳转到第三方应用中。
3.4 集成第三方 PDF SDK,在 Native 页面中阅读
第三方应用商提供一些免费或者收费的SDK来供我们选择和使用,集成第三方的PDF,可以有效的加载PDF等文件,但是功能和性能等指标可能存在很大差异。收费的SDK性能指标可能最优,集成体验好,但是费用高,而且不论收费或者免费,对于安装包的大小会显著增加。目前市场是的主要有:Foxit 福昕 ,PlugPDF,PDFium,PdfiumAndroid,AndroidPdfViewer等。
3.4 集成PDF.js,然后再在WebView上加载
我们也可以将PDF文件存放到我们自己的服务器上,将PDF文件通过PDF.js服务端方式 去解析出来 。可以找服务端的同学去完成 ,大致的方案如下:
- 客户端获取到在线 PDF 的链接
- 将该链接作为参数,通过 WebView 向服务端的 PDF 服务发起请求
- PDF 服务将该链接的 PDF 文件下载到服务端缓存目录,并调用 PDF.js 提供的能力将 PDF 渲染出来。
客户端需要把官方提供的 pdf.js 和 pdf.worker.js 拷贝到工程的 assets 目录,同时在客户端本地实现一个离线 H5 页面,该页面通过上述两个 js 文件实现 PDF 的阅读。H5 页面的交互和设计需要设计师给出来,同时可能需要前端同学实现。
pdf.js的github地址:https://github.com/mozilla/pdf.js
3.5 将PDF文件转换成Html或者图片格式等其他方式
有人提出一种可行性方案就是将PDF文件通过pdf2htmlEX转换成Html格式,然后我们在通过WebView来加载。当然这个在服务端完成,然后将转换的链接地址给移动端。这样就很方便了。当然我们也可以转成别的格式。就只是提供一种思路。具体的话有兴趣自己去琢磨琢磨。
4. 总结
各种PDF的选择方式看你的需求是怎样的,根据你的开发实际情况来选择你需要的方式。如果只考虑 PDF 阅读的功能,我们可以考虑调起第三方支持 PDF 阅读的应用这种方法为首选;如果是要查看本地的pdf的话,可以优先考虑PDF.js;如果要考虑在线阅读的话,那就选择服务端实现方案。
本项目github地址:https://github.com/wangxin3119/PdfDemoView