[android开发]手写签名系统的设计与实现之实现解析pdf文件(二)
上一篇文章,我们介绍了如何去实现读取手机文件及文件夹,并以列表的形式显示出来,今天我们将说说如何读取pdf文件。先看效果图:
选择pdf文件 显示pdf文件主界面
一、实现原理:
手机端解析pdf的实例并不是很多,android系统本身没有解析的类,就需要第三方开发库,现在常用的两种方式:一种是利用动态链接库libmupdf.so;另一种是利用动态链接库libvudroid.so。两者各有自己的优缺点,前者解析速度快,但是比较耗内存;后者省内存,但是解析比较慢。本项目是利用前者动态库来解析pdf的,这两个在网上都可以下载,也有一个相关的实例。本人感觉,前者比较简单,后者实现的相对复杂,之前有人说前者动态库是在后者的基础上写的,等待求证。下面我们就介绍libmupdf.so动态库:MUPDF是一个轻量级pdf显示阅读器,大家需要把limupdf.so导入到项目中,建立一个包名为com.artifex.mupdf,目录结构如下:
在com.artifex.mupdf包中新建这几个类,我们重点介绍MuPDFActivity、ReaderView、PageView、MuPDFCore。
在MuPDFActivity类中获取要读取的pdf地址,传给MuPDFCore对象:
/** * 功能:根据获取的文件路径,解析pdf,并返回core * @param path * @return core */ private MuPDFCore openFile(String path) { PATH = path; int lastSlashPos = path.lastIndexOf('/'); mFileName = new String(lastSlashPos == -1 ? path : path.substring(lastSlashPos+1)); System.out.println("Trying to open "+path); try { core = new MuPDFCore(path); // New file: drop the old outline data } catch (Exception e) { System.out.println(e); return null; } return core; }MuPDFCore开始解析pdf,最后将其实例传给ReaderView:
private ReaderView mDocView;
mDocView = new ReaderView(this) { private boolean showButtonsDisabled; public boolean onSingleTapUp(MotionEvent e) { if (e.getX() < super.getWidth()/TAP_PAGE_MARGIN) { super.moveToPrevious(); } else if (e.getX() > super.getWidth()*(TAP_PAGE_MARGIN-1)/TAP_PAGE_MARGIN) { super.moveToNext(); } else if (!showButtonsDisabled) { int linkPage = -1; if (mLinkState != LinkState.INHIBIT) { MuPDFPageView pageView = (MuPDFPageView) mDocView.getDisplayedView(); if (pageView != null) {// XXX linkPage = pageView.hitLinkPage(e.getX(), e.getY()); } } if (linkPage != -1) { mDocView.setDisplayedViewIndex(linkPage); } else { if (!mButtonsVisible) { showButtons(); } else { hideButtons(); } } } return super.onSingleTapUp(e); } public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { if (!showButtonsDisabled) hideButtons(); return super.onScroll(e1, e2, distanceX, distanceY); } public boolean onScaleBegin(ScaleGestureDetector d) { showButtonsDisabled = true; return super.onScaleBegin(d); } public boolean onTouchEvent(MotionEvent event) { if (event.getActionMasked() == MotionEvent.ACTION_DOWN){ showButtonsDisabled = false; } return super.onTouchEvent(event); } protected void onChildSetup(int i, View v) { ((PageView)v).setLinkHighlighting(mLinkState == LinkState.HIGHLIGHT); } protected void onMoveToChild(int i) { if (core == null) return; mPageNumberView.setText(String.format("%d/%d", i+1, core.countPages())); mPageSlider.setMax(core.countPages()-1); mPageSlider.setProgress(i); } protected void onSettle(View v) { // When the layout has settled ask the page to render // in HQ ((PageView)v).addHq(); } protected void onUnsettle(View v) { // When something changes making the previous settled view // no longer appropriate, tell the page to remove HQ ((PageView)v).removeHq(); } }; mDocView.setAdapter(new MuPDFPageAdapter(this, core));ReaderView获取pdf的页面信息后传给PageView,这样pdf文件就显示出来了,其原来就是将每一页转成一个bitmap对象:
MuPDFPageView pageView = (MuPDFPageView) mDocView.getDisplayedView();
ReaderView包含了对pdf文件的相关操作,比如页面放大缩小、翻页等相关手势:
/** * 用户轻触触摸屏,由1个MotionEvent ACTION_DOWN触发 * */ public boolean onDown(MotionEvent arg0) { mScroller.forceFinished(true); //Log.e("info", "-->onDown"); return true; } /* * 用户按下触摸屏、快速移动后松开, * 由1个MotionEvent ACTION_DOWN, * 多个ACTION_MOVE, 1个ACTION_UP触发 * */ public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { if (mScrollDisabled) return true; View v = mChildViews.get(mCurrent); if (v != null) { Rect bounds = getScrollBounds(v); switch(directionOfTravel(velocityX, velocityY)) { case MOVING_LEFT: if (bounds.left >= 0) { // Fling off to the left bring next view onto screen View vl = mChildViews.get(mCurrent+1); if (vl != null) { slideViewOntoScreen(vl); return true; } } break; case MOVING_RIGHT: if (bounds.right <= 0) { // Fling off to the right bring previous view onto screen View vr = mChildViews.get(mCurrent-1); if (vr != null) { slideViewOntoScreen(vr); return true; } } break; } mScrollerLastX = mScrollerLastY = 0; Rect expandedBounds = new Rect(bounds); expandedBounds.inset(-FLING_MARGIN, -FLING_MARGIN); if(withinBoundsInDirectionOfTravel(bounds, velocityX, velocityY) && expandedBounds.contains(0, 0)) { mScroller.fling(0, 0, (int)velocityX, (int)velocityY, bounds.left, bounds.right, bounds.top, bounds.bottom); post(this); } } return true; } /** * 用户长按触摸屏,由多个MotionEvent ACTION_DOWN触发 * */ public void onLongPress(MotionEvent e) { } /** * 功能:扑捉屏幕手势滑动动作 * 用户按下触摸屏,并拖动,由1个MotionEvent ACTION_DOWN, * 多个ACTION_MOVE触发。 * */ public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { //Log.e("info", "-->onScroll"); //这里控制pdf文件翻页 if (!mScrollDisabled) { mXScroll -= distanceX; mYScroll -= distanceY; requestLayout(); } return true; } /** * 用户轻触触摸屏,尚未松开或拖动,由一个1个MotionEvent ACTION_DOWN触发 * 注意和onDown()的区别,强调的是没有松开或者拖动的状态 . * */ public void onShowPress(MotionEvent e) { //Log.e("info", "-->onShowPress"); } /** * 用户(轻触触摸屏后)松开,由一个1个MotionEvent ACTION_UP触发 * */ public boolean onSingleTapUp(MotionEvent e) { return false; } /** * 处理对屏幕的缩放比例 * */ public boolean onScale(ScaleGestureDetector detector) { //截屏视图不显示时,手势操作可以进行 float previousScale = mScale; mScale = Math.min(Math.max(mScale * detector.getScaleFactor(), MIN_SCALE), MAX_SCALE); scalingFactor = mScale/previousScale;//缩放比例 //Log.e("info", "--->scalingFactor="+scalingFactor); View v = mChildViews.get(mCurrent); if (v != null) { // Work out the focus point relative to the view top left int viewFocusX = (int)detector.getFocusX() - (v.getLeft() + mXScroll); int viewFocusY = (int)detector.getFocusY() - (v.getTop() + mYScroll); // Scroll to maintain the focus point mXScroll += viewFocusX - viewFocusX * scalingFactor; mYScroll += viewFocusY - viewFocusY * scalingFactor; requestLayout(); } return true; } public boolean onScaleBegin(ScaleGestureDetector detector) { mScaling = true; // Ignore any scroll amounts yet to be accounted for: the // screen is not showing the effect of them, so they can // only confuse the user mXScroll = mYScroll = 0; // Avoid jump at end of scaling by disabling scrolling // until the next start of gesture mScrollDisabled = true; return true;//一定要返回true才会进入onScale()这个函数 } public void onScaleEnd(ScaleGestureDetector detector) { mScaling = false; } /* * 在onTouch()方法中,我们调用GestureDetector的onTouchEvent()方法,将捕捉到的MotionEvent交给GestureDetector * 来分析是否有合适的callback函数来处理用户的手势 */ @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub return mGestureDetector.onTouchEvent(event); } @Override public boolean onTouchEvent(MotionEvent event) { mScaleGestureDetector.onTouchEvent(event); if (!mScaling) mGestureDetector.onTouchEvent(event); if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { mUserInteracting = true; } if (event.getActionMasked() == MotionEvent.ACTION_UP) { mScrollDisabled = false; mUserInteracting = false; if(event.getAction() == MotionEvent.ACTION_UP){ View v = mChildViews.get(mCurrent); if (v != null) { if (mScroller.isFinished()) { slideViewOntoScreen(v); } if (mScroller.isFinished()) { postSettle(v); } } } } requestLayout(); return true; }
这里我们说到了手势的相关操作,手势操作是比较流行的,主要是要实现OnGestureListener接口,例如Fling,Scroll等等。这些Gesture会使用户体验大大提升。
这些完成之后,我们就要在FileActivity类中调用MuPDFActivity:
Intent intent = new Intent(getApplicationContext(), MuPDFActivity.class); intent.setAction(Intent.ACTION_VIEW); intent.setData(uri); startActivity(intent);
最后要在清单文件中注册相应的activity:
到此我们就可以显示要读取的pdf文件了,并可以对页面就行放大缩小、翻页操作。这个也是从一个开源项目中学到,根据自己的需求实现了其中一部分功能,MuPDF解析pdf远比这些功能要多,这只是一小部分而已。对于具体实现过程,大家可以下载本博客相应的实例源码,这里就不全部贴出来了,在最后边将把代码下载链接留给大家,需要的朋友可以下载看看。明天我们将会介绍如何实现手写画板。欢迎大家继续关注,对于不足之处敬请指正,大家一起进步,上传资源已经运行,没有问题,如果你不能运行,请在博客留言……
【android开发】手写签名系统的设计与实现之实现解析pdf文件(二)
鎶ュ悕瀛︿範鍔犲井淇�/QQ 1602007锛屽叧娉ㄣ€婁笢鏂硅仈鐩熺綉銆嬪井淇″叕浼楀彿
>更多相关文章
首页推荐
佛山市东联科技有限公司一直秉承“一切以用户价值为依归
- 01-11全球最受赞誉公司揭晓:苹果连续九年第一
- 12-09罗伯特·莫里斯:让黑客真正变黑
- 12-09谁闯入了中国网络?揭秘美国绝密黑客小组TA
- 12-09警示:iOS6 惊现“闪退”BUG
- 03-08消息称微软开发内部AI推理模型,或将成为Op
- 03-08美国法院驳回马斯克请求,未阻止OpenAI转型
- 03-08饿了么成立即时配送算法专家委员会 持续全局
- 03-08长安汽车:预计今年底长安飞行汽车将完成试
- 03-08谷歌推出虚拟试穿、AR美妆新功能
相关文章
24小时热门资讯
24小时回复排行
热门推荐
最新资讯
操作系统
黑客防御