?? ??? ?最近项目上有一个需求,需要在Android端加载显示pdf文档,因为没有相关的经验,在刚接到需求的时候,第一想法就是打开程序员的第二大脑进行搜索,搜索结果还是蛮理想的,了解到了MuPDF,它支持多种文档格式,例如 PDF、XPS、OpenXPS、CBZ、EPUB 和 FictionBook 2。? ?? ??? ?我这里要记录的是 android-pdfview。PDFView是这个库中最核心的类,用于加载pdf文件,PDFView是的实现是继承于SurfaceView来实现的。主要用到了建造者模式来设置相关的属性。
? ? ? ? 另外还可以通过浏览器进行加载pdf等等。
-
?引用 android-pdfview的依赖为:? ? ? ?
compile 'com.joanzapata.pdfview:android-pdfview:1.0.4@aar'
? ? ? ? 这里需要添加网络权限,将服务器上的pdf文档下载到本地保存。
<!-- 网络权限 -->
<uses-permission android:name="android.permission.INTERNET" />
? ? ? ? 另外还需要添加文件读写的权限。
<!-- 写入外部存储权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 读取外部存储权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
? ? ? ? 本文编辑时,对应的demo是在我们公司定制的开发板上边运行的,所有权限只需在manifest里边添加,无需手动申请权限,这里需要注意,自己进行文件读写权限的申请。
? ? ? ? 布局文件就非常简单了,直接在activity对应的布局中,添加一个PDFView控件,宽高均设置为match_parent就可以了。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="cn.load.pdfview.LoadPdfViewActivity">
<com.joanzapata.pdfview.PDFView
android:id="@+id/loadPdfView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
? ? ? ? ?看到上边这个图片,顾名思义要开始撸代码了!!!
-
?View层 override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_load_pdf_view)
//找控件
loadPdfView = findViewById(R.id.loadPdfView)
onLoadingView = findViewById(R.id.onLoadingView)
//下载文档的Presenter
mLoadFilePresenter = LoadFilePresenter()
//绑定页面
mLoadFilePresenter?.attachView(this)
//下载文档
mLoadFilePresenter?.downLoadFile("要加载的文档对应的服务器链接地址。")
} 在页面onCreate完成之后,将服务器上的pdf文档进行下载至本地。 -
Presenter层 override fun downLoadFile(fileUrl: String) {
//提示正在加载文档
view?.downLoadingFile()
//创建下载完成的回调
val mLoadFileModel: DloadFileInterface.LoadFileModelInterface = LoadFileModel()
//开始下载pdf文档
mLoadFileModel.downLoadFile(object : DownLoadFileListener {
//是否下载成功的监听
override fun onDownLoadListen(isSuccessFlag: Boolean, filePath: String) {
if (isAvailable()!!)//判断view是都可见
view?.downLoadFileComplete(isSuccessFlag, filePath)//告诉view层,文档已经下载完了
}
}, fileUrl)
} -
Model层 //开始下载文档
override fun downLoadFile(mDownLoadFileListener: DloadFileInterface.DownLoadFileListener, fileUrl: String) {
val mDownLoadFileUtils = DownLoadFileUtils(
"training_plan.pdf",//下载文档完成后本地存储文档的名称
fileUrl,//服务器上文档的url
object : DownLoadFileUtils.DownLoadCompleteListener {//下载完成的回调
override fun onDownLoadCompleteListener(isSuccessFlag: Boolean, filePath: String?) {
if (filePath != null)//判空处理
mDownLoadFileListener.onDownLoadListen(isSuccessFlag, filePath)
}
}
)
//这里要在子线程进行文档的下载
val scheduledExecutorService = Executors.newSingleThreadScheduledExecutor()
scheduledExecutorService.execute(mDownLoadFileUtils)
}
? ? ? ? 因为下载文档这地方,既有文件存储又有网络加载的过程,为了避免ANR,所有要在子线程中进行。?
fun loadPdfFile2Show(filePath: String) {
//判断当前页面是否已经销毁
if (!isAvailable())
return
val file = File(filePath)
if (!file.exists() || !file.isFile) {
toastMessage("文件不存在或文件已损坏!")
return
}
loadPdfView?.fromFile(file)
?.defaultPage(1)//默认加载文档的第defaultPage页 默认设置为第一页
?.showMinimap(false)//pdf放大的时候,是否在右上角生成引导图 默认设置为不生成
?.enableSwipe(true)//是否允许翻页,默认为允许翻页
?.onDraw(object : OnDrawListener {
//正在绘制图像的监听
override fun onLayerDrawn(canvas: Canvas?, pageWidth: Float, pageHeight: Float, displayedPage: Int) {
LogUtils.d(TAG, "onLayerDrawn====")
}
})
?.onLoad(object : OnLoadCompleteListener {
//加载完成的监听
override fun loadComplete(nbPages: Int) {
LogUtils.d(TAG, "loadComplete====")
}
})
?.onPageChange(object : OnPageChangeListener {
//翻页的监听
override fun onPageChanged(page: Int, pageCount: Int) {
LogUtils.d(TAG, "onPageChanged===")
}
})
?.load()
}
????????在加载对应的pdf文档之前一定要进行判断,文档是否存在,否则你要加载的文档不存在的话,应用会直接crash掉。
if (!file.exists() || !file.isFile) {
toastMessage("文件不存在或文件已损坏!")
return
}
?????????android-pdfview使用起来还是比较简单的,而且功能比较强大,如果有兴趣或者有更高层次的需求可以研究一下,本人现在只局限于加载并显示文档这里,后边会进行深层次的学习后进行相关分享。
? ? ? ? 最后附上demo下载地址!
????????传送门!
|