前言

        最近项目上有一个需求,需要在Android端加载显示pdf文档,因为没有相关的经验,在刚接到需求的时候,第一想法就是打开程序员的第二大脑进行搜索,搜索结果还是蛮理想的,了解到了MuPDF,它支持多种文档格式,例如 PDF、XPS、OpenXPS、CBZ、EPUB 和 FictionBook 2。 
        我这里要记录的是 android-pdfview。PDFView是这个库中最核心的类,用于加载pdf文件,PDFView是的实现是继承于SurfaceView来实现的。主要用到了建造者模式来设置相关的属性。

        另外还可以通过浏览器进行加载pdf等等。

效果图

Android 读写PDF文件 android加载pdf文件_加载PDF

 引用

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>

文档下载

Android 读写PDF文件 android加载pdf文件_Android开发_02

         看到上边这个图片,顾名思义要开始撸代码了!!!

 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下载地址!

        传送门!