Android应用内加载pdf 使用pdf.js

Android应用内加载pdf 使用pdf.js,第1张

 

当前在Android应用浏览pdf大概几种方式

1、直接打开各种浏览器或者软件(缺点用户无法在应用内直接看到pdf,效果不好)

2、android-pdf-viewer在应用中可以直接看到,通过一系列封装可能实现大部分要求(缺点将pdf转成图片加载,文本性质的pdf无法选择复制)

3、腾讯X5内核腾讯浏览服务-SDK下载;(缺点集成麻烦,部分情况x5内核还需要在应用内下载)

4、mupdf(集成超级麻烦,我连稀得看没稀得看)

5、pdf.js (满足大部分要求了,缺点需要js、h5稍微知道点)

本文重点实现pdf.js

提前把权限获取好什么sd卡读写啊  什么网络啊之类的。

第一步:把pdf.js依赖放入assets;在这里下一下,Getting StartedA general-purpose, web standards-based platform for parsing and rendering PDFs.http://mozilla.github.io/pdf.js/getting_started/#download

 第二步:重写个webview运行


public class PDFView extends WebView {

    public boolean isTop = true, isBottom = false;//用于判断滑动位置

    private final static String PDFJS = "file:///android_asset/pdf_js/web/viewer.html?file=";

    public PDFView(Context context) {
        super(context);
        init();
    }

    public PDFView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public PDFView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return false;
    }

    private void init() {
        WebSettings settings = getSettings();
        settings.setJavaScriptEnabled(true);
        settings.setAllowUniversalAccessFromFileURLs(true);
        settings.setSupportZoom(true);
        settings.setUseWideViewPort(true);
        settings.setBuiltInZoomControls(true);
        settings.setDisplayZoomControls(false);
        
        setWebViewClient(new WebViewClient() {// 注册滑动监听方法viewerContainer为加载pdf的viewid
            @Override
            public void onPageFinished(WebView webView, String s) {
                super.onPageFinished(webView, s);
                //滑动监听
                String startSave = "\n" +
                        "document.getElementById(\"viewerContainer\").addEventListener('scroll',function () {\n" +
                            "if(this.scrollHeight-this.scrollTop - this.clientHeight < 50){\n" +
                                "window.java.bottom(); \n" +
                            "}\n" +
                            "else if(this.scrollTop==0){\n" +
                                "window.java.top(); \n" +
                            "}\n" +
                            "else {\n" +
                                "window.java.scrolling(); \n" +
                            "}\n" +
                        "});";
                webView.loadUrl("javascript:" + startSave);
            }
        });
        addJavascriptInterface(new Object() {
            @JavascriptInterface
            public void bottom() {
                Log.e("msg+++++++", "到了低端");
                isBottom = true;
                isTop = false;
            }

            @JavascriptInterface
            public void scrolling() {
                Log.e("msg+++++++", "滑动中");
                isBottom = false;
                isTop = false;
            }
            @JavascriptInterface
            public void top() {
                Log.e("msg+++++++", "到了顶端");
                isBottom = false;
                isTop = true;
            }
        }, "java");
    }

    @Override
    protected void onCreateContextMenu(ContextMenu menu) {
        super.onCreateContextMenu(menu);
    }

    @Override
    public ActionMode startActionMode(ActionMode.Callback callback) {
        return super.startActionMode(callback);
    }
    //加载本地的pdf
    public void loadLocalPDF(String path) {
        loadUrl(PDFJS + "file://" + path);
    }

    //加载url的pdf
    public void loadOnlinePDF(String url) {
        loadUrl(PDFJS + url);
    }
}

第三步:引用+使用



                
findViewById(R.id.pdfview).loadOnlinePDF(url)

怎么样是不是很简单?

在自定义webview中大家可以看到有一段交互注册代码,解决什么问题呢,滑动冲突!!!

当父view是scrollview时候  嵌套这个webview就会出现上下滑动冲突

这个时候写个事件分发

/**
 * scrollview 与 封装的pdfview  滑动冲突解决
 */
public class DispatchScrollview extends ScrollView {
    private List views = new ArrayList<>();
    private int touchY;

    public DispatchScrollview(Context context) {
        super(context);
    }

    public DispatchScrollview(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public DispatchScrollview(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public void setDispatchView(View view) {
        views.add(view);
    }

    public void clear() {
        views.clear();
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            touchY = (int) ev.getY();
            Log.d("test", "touchY--->" + touchY);
        }
        for (View view : views) {
            int[] viewlocation = new int[2];
            view.getLocationOnScreen(viewlocation);
            int thenx = viewlocation[0];
            int theny = viewlocation[1];
            Log.d("test", "Screenx--->" + thenx + "  " + "Screeny--->" + theny);
            if (touchY > theny && touchY < theny + view.getHeight()) {
                if (ev.getAction() == MotionEvent.ACTION_MOVE && view instanceof PDFView) {
                    int yPath = (int) (ev.getY() - touchY);
                    if (yPath > 0 && ((PDFView) view).isTop) {
                        return super.onInterceptTouchEvent(ev);
                    }
                    if (yPath < 0 && ((PDFView) view).isBottom) {
                        return super.onInterceptTouchEvent(ev);
                    }

                    if (view.getVisibility() == GONE)
                        return super.onInterceptTouchEvent(ev);
                    int[] scrolllocation = new int[2];
                    getLocationInWindow(scrolllocation);
                    int scrolly = scrolllocation[1]; // view距离window 顶边的距离(即y轴方向

                    int[] location = new int[2];
                    view.getLocationInWindow(location);
                    int y = location[1] - scrolly; // view距离window 顶边的距离(即y轴方向)
                    int yh = y + view.getHeight();
                    int touchY = (int) ev.getY();
                    if (view != null && touchY >= y && touchY < yh) {//如果是recyclerview的范围时 不允许接收事件
                        return false;
                    }
                }
            }

        }
        return super.onInterceptTouchEvent(ev);
    }
}

这个时候用这个 替换scrollview,有几个pdfview set进几个这个时候你会发现在pdf区域往上拉的时候pdf不到底先滑pdf ,到底之后整个scrollview上行,在pdf区域往下拉的时候pdf不到顶先滑pdf,到顶之后整个scrollview下行;完美解决

 scrollView.setDispatchView(pdfView);

付上效果,感觉相当丝滑,而且如果pdf不是图片转还可以长按复制之类的,因为人家是网页的

补充:

集成之后,又发现没有双指缩放,用user-scalable=yes的话 又发现带着ui一起缩放,那么没招只能自己加了,进pdf.js源码里翻出点击加减号放大缩小的代码,用java调用

webView.setOnTouchListener(new OnTouchListener() {
            private float OldX1, OldY1, OldX2, OldY2;
            private float NewX1, NewY1, NewX2, NewY2;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_POINTER_2_DOWN:
                        if (event.getPointerCount() == 2) {
                            OldX1 = event.getX(0);
                            OldY1 = event.getY(0);
                            OldX2 = event.getX(1);
                            OldY2 = event.getY(1);
                        }
                        break;
                    case MotionEvent.ACTION_MOVE:
                        if (event.getPointerCount() == 2) {
                            if(OldX1 == -1 && OldX2 == -1)
                                break;
                            NewX1 = event.getX(0);
                            NewY1 = event.getY(0);
                            NewX2 = event.getX(1);
                            NewY2 = event.getY(1);
                            float disOld = (float) Math.sqrt((Math.pow(OldX2
                                    - OldX1, 2) + Math.pow(OldY2 - OldY1, 2)));
                            float disNew = (float) Math.sqrt((Math.pow(NewX2
                                    - NewX1, 2) + Math.pow(NewY2 - NewY1, 2)));
                            Log.e("onTouch", "disOld=" + disOld + "|disNew="
                                    + disNew);
                            if (disOld - disNew >= 25) {
                                // 缩小
//							wv.zoomOut();
                                webView.loadUrl("javascript:PDFViewerApplication.zoomOut()");
                                Log.e("onTouch", "zoomOut");
                            } else if (disNew - disOld >= 25) {
                                // 放大
//							wv.zoomIn();
                                webView.loadUrl("javascript:PDFViewerApplication.zoomIn()");
                                Log.e("onTouch", "zoomIn");
                            }
                            OldX1 = NewX1;
                            OldX2 = NewX2;
                            OldY1 = NewY1;
                            OldY2 = NewY2;
                        }
                        break;
                    case MotionEvent.ACTION_UP:
                        if (event.getPointerCount() < 2) {
                            OldX1 = -1;
                            OldY1 = -1;
                            OldX2 = -1;
                            OldY2 = -1;
                        }
                        break;
                }
                return false;
            }
        });

ok缩放也有了,最后 有点问题  pdf元素多的时候展示页有点卡,在想解决方法

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/992216.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存