美文网首页Android
android App内部pdf文件阅读

android App内部pdf文件阅读

作者: 子鱼城 | 来源:发表于2018-08-08 19:24 被阅读432次

    --本方法仅仅适合android5以上

    最近项目里面涉及到了 在App内部打开pdf文件进行阅读的需求,没办法,pm不让调用系统的pdf阅读软件打开。
    网上搜了一圈,主要有两种

    1. asce1885
    2. 基于tbs封装的file

    缺点:

    1. 所示的方式 方式虽多,但是要么是服务器来做,要么是引入的包体积太大,要么是本地用webview加载,实现起来并不符合当前项目的需求
    2. 乍一听tbs给的方案 应该很靠谱,方案二实际也是对tbs的封装,但是我这边使用的时候,最开始能够正常加载,后面不知道怎么的,所有的pdf文件都不能加载了,卸载重装也无效,log日志提示某个callback类找不到,tbs官网的论坛上很多人问这个也没人给出解决方案,最后就放弃了这种方案。

    后来再github上自己慢慢找,根据排序、更新、star量找到了这个封装库pdfviewPager
    优点:

    1. 这个库基于android提供的pdfRender 解析pdf文件,把pdf的每一页解析成一张bitmap放到viewpager的每一页,靠谱,比第三方各种ndk功能靠谱。
    2. 在每一页提供基本的手势缩放功能。
    3. 体积小
    4. 集成简单。
    5. 自带pdf文件下载功能(我自己写了,没有用它的下载功能)

    pdfRender 通过传入fileDiscriptor就可以创建一个实例,看看google官网给的示例:

    // create a new renderer
     PdfRenderer renderer = new PdfRenderer(getSeekableFileDescriptor());
    
     // let us just render all pages
     final int pageCount = renderer.getPageCount();
     for (int i = 0; i < pageCount; i++) {
         Page page = renderer.openPage(i);
    
         // say we render for showing on the screen
         page.render(mBitmap, null, null, Page.RENDER_MODE_FOR_DISPLAY);
    
         // do stuff with the bitmap
    
         // close the page
         page.close();
     }
    
     // close the renderer
     renderer.close();
    

    pdfViewPager 的初始化入口

    public PDFViewPager(Context context, String pdfPath) {
            super(context);
            this.context = context;
            init(pdfPath);
    }
    

    initAdapter的时候会创建PDFPagerAdapter() 并设置缓存屏幕数目。

    protected void initAdapter(Context context, String pdfPath) {
            setAdapter(new PDFPagerAdapter.Builder(context)
                    .setPdfPath(pdfPath)
                    .setOffScreenSize(getOffscreenPageLimit())
                    .create());
    }
    

    PDFPagerAdapter继承了BasePDFPagerAdapter,在BasePDFPagerAdapter的构造函数里面会执行如下代码:

    protected void init() {
            try {
                renderer = new PdfRenderer(getSeekableFileDescriptor(pdfPath));
                inflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
                PdfRendererParams params = extractPdfParamsFromFirstPage(renderer, renderQuality);
                bitmapContainer = new SimpleBitmapPool(params);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    

    主要是通过pdf文件的路径获得FileDescriptor,传入PdfRender获得一个对pdf文件的渲染对象,通过这个对象我们可以获取pdf文件的各种信息,例如每一页宽高等信息,代码在这里新建了一个离屏数目* 2 + 1的bitmap对象池(默认与viewpager一致)

    前面的准备工作已经做完了,接下来我们再看看PDFPagerAdapter里面的逻辑

     public Object instantiateItem(ViewGroup container, int position) {
            View v = inflater.inflate(R.layout.view_pdf_page, container, false);
            ImageView iv = (ImageView) v.findViewById(R.id.imageView);
    
            if (renderer == null || getCount() < position) {
                return v;
            }
    
            PdfRenderer.Page page = getPDFPage(renderer, position);
    
            Bitmap bitmap = bitmapContainer.get(position);
            page.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
            page.close();
    
            PhotoViewAttacher attacher = new PhotoViewAttacher(iv);
            attacher.setScale(scale.getScale(), scale.getCenterX(), scale.getCenterY(), true);
            attacher.setOnMatrixChangeListener(this);
    
            attachers.put(position, new WeakReference<PhotoViewAttacher>(attacher));
    
            iv.setImageBitmap(bitmap);
            attacher.setOnPhotoTapListener(new PhotoViewAttacher.OnPhotoTapListener() {
                @Override
                public void onPhotoTap(View view, float x, float y) {
                    pageClickListener.onClick(view);
                }
            });
            attacher.update();
            ((ViewPager) container).addView(v, 0);
    
            return v;
        }
    

    在PDFPagerAdapter里面初始化item的时候会从bitmap对象池里面取出一个bitmap对象,并从加载到布局文件上。 同时这里把image交给了PhotoView,方便实现根据手势缩放的需求。

    相关文章

      网友评论

      本文标题:android App内部pdf文件阅读

      本文链接:https://www.haomeiwen.com/subject/gkvtbftx.html