当前在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元素多的时候展示页有点卡,在想解决方法
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)