您的位置:首页 > 移动开发 > Android开发

【android开发】手写签名系统的设计与实现之实现解析pdf文件(二)

2014-01-03 10:46 791 查看
上一篇文章,我们介绍了如何去实现读取手机文件及文件夹,并以列表的形式显示出来,今天我们将说说如何读取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对象:

[java] view
plaincopy





/**

* 功能:根据获取的文件路径,解析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:

[java] view
plaincopy





private ReaderView mDocView;

[java] view
plaincopy





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对象:

[java] view
plaincopy





MuPDFPageView pageView = (MuPDFPageView) mDocView.getDisplayedView();

ReaderView包含了对pdf文件的相关操作,比如页面放大缩小、翻页等相关手势:

[java] view
plaincopy





/**

* 用户轻触触摸屏,由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:

[java] view
plaincopy





Intent intent = new Intent(getApplicationContext(), MuPDFActivity.class);

intent.setAction(Intent.ACTION_VIEW);

intent.setData(uri);

startActivity(intent);

最后要在清单文件中注册相应的activity:

[java] view
plaincopy





<activity android:name="com.artifex.mupdf.MuPDFActivity"

android:label="@string/app_name"></activity>

到此我们就可以显示要读取的pdf文件了,并可以对页面就行放大缩小、翻页操作。这个也是从一个开源项目中学到,根据自己的需求实现了其中一部分功能,MuPDF解析pdf远比这些功能要多,这只是一小部分而已。对于具体实现过程,大家可以下载本博客相应的实例源码,这里就不全部贴出来了,在最后边将把代码下载链接留给大家,需要的朋友可以下载看看。明天我们将会介绍如何实现手写画板。欢迎大家继续关注,对于不足之处敬请指正,大家一起进步,上传资源已经运行,没有问题,如果你不能运行,请在博客留言……
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐