Android pdf解析方案

来源:互联网 发布:腿姐政治怎么样 知乎 编辑:程序博客网 时间:2024/05/20 10:53

最近在做一个健康类项目,要求用pdf展示体检报告,ios webview支持展示pdf,android的不支持,后来只能把pdf下载下来,再在程序中嵌入pdf查看,本来采用pdfViewer,但是发现有的pdf会报错,不稳定,上网搜了好久,也没有解决方案,后来换成了mupdf,按理说应该去github找star和fork最多的,说得好有道理的样子,我就是这样做的,然而还是没有解决,后来google到了一个帖子,说这个可以,下面进入正题,上链接:

https://github.com/geek5nan/AndroidMuPDFDemo

这个是可以解析pdf的但是项目要求pdf上下滑动翻页,但这个项目是左右滑动的,别着急,博主有办法:

将项目中onLayout2方法换成下面这个

protected void onLayout2(boolean changed, int left, int top, int right, int bottom) {
// super.onLayout(changed, left, top, right, bottom);


// "Edit mode" means when the View is being displayed in the Android GUI
// editor. (this class
// is instantiated in the IDE, so we need to be a bit careful what we
// do).
if (isInEditMode())
return;


View cv = mChildViews.get(mCurrent);
Point cvOffset;


if (!mResetLayout) {
// Move to next or previous if current is sufficiently off center
if (cv != null) {
cvOffset = subScreenSizeOffset(cv);
// cv.getRight() may be out of date with the current scale
// so add left to the measured width for the correct position
// if (cv.getLeft() + cv.getMeasuredWidth() + cvOffset.x + GAP/2
// + mXScroll < getWidth()/2 && mCurrent + 1 <
// mAdapter.getCount()) {
if (cv.getTop() + cv.getMeasuredHeight() + cvOffset.y + GAP / 2 + mYScroll < getHeight() / 2
&& mCurrent + 1 < mAdapter.getCount()) {
postUnsettle(cv);
// post to invoke test for end of animation
// where we must set hq area for the new current view
mStepper.prod();


onMoveOffChild(mCurrent);
mCurrent++;
onMoveToChild(mCurrent);
}


// if (cv.getLeft() - cvOffset.x - GAP/2 + mXScroll >=
// getWidth()/2 && mCurrent > 0) {
if (cv.getTop() - cvOffset.y - GAP / 2 + mYScroll >= getHeight() / 2 && mCurrent > 0) {
postUnsettle(cv);
// post to invoke test for end of animation
// where we must set hq area for the new current view
mStepper.prod();


onMoveOffChild(mCurrent);
mCurrent--;
onMoveToChild(mCurrent);
}
}


// Remove not needed children and hold them for reuse
int numChildren = mChildViews.size();
int childIndices[] = new int[numChildren];
for (int i = 0; i < numChildren; i++)
childIndices[i] = mChildViews.keyAt(i);


for (int i = 0; i < numChildren; i++) {
int ai = childIndices[i];
if (ai < mCurrent - 1 || ai > mCurrent + 1) {
View v = mChildViews.get(ai);
onNotInUse(v);
mViewCache.add(v);
removeViewInLayout(v);
mChildViews.remove(ai);
}
}
} else {
mResetLayout = false;
mXScroll = mYScroll = 0;


// Remove all children and hold them for reuse
int numChildren = mChildViews.size();
for (int i = 0; i < numChildren; i++) {
View v = mChildViews.valueAt(i);
onNotInUse(v);
mViewCache.add(v);
removeViewInLayout(v);
}
mChildViews.clear();


// Don't reuse cached views if the adapter has changed
if (mReflowChanged) {
mReflowChanged = false;
mViewCache.clear();
}


// post to ensure generation of hq area
mStepper.prod();
}


// Ensure current view is present
int cvLeft, cvRight, cvTop, cvBottom;
boolean notPresent = (mChildViews.get(mCurrent) == null);
cv = getOrCreateChild(mCurrent);
// When the view is sub-screen-size in either dimension we
// offset it to center within the screen area, and to keep
// the views spaced out
cvOffset = subScreenSizeOffset(cv);
if (notPresent) {
// Main item not already present. Just place it top left
cvLeft = cvOffset.x;
cvTop = cvOffset.y;
} else {
// Main item already present. Adjust by scroll offsets
cvLeft = cv.getLeft() + mXScroll;
cvTop = cv.getTop() + mYScroll;
}
// Scroll values have been accounted for
mXScroll = mYScroll = 0;
cvRight = cvLeft + cv.getMeasuredWidth();
cvBottom = cvTop + cv.getMeasuredHeight();


if (!mUserInteracting && mScroller.isFinished()) {
Point corr = getCorrection(getScrollBounds(cvLeft, cvTop, cvRight, cvBottom));
cvRight += corr.x;
cvLeft += corr.x;
cvTop += corr.y;
cvBottom += corr.y;
} else if (cv.getMeasuredWidth() <= getWidth()) {
// // When the current view is as small as the screen in height,
// clamp
// // it vertically
// Point corr = getCorrection(getScrollBounds(cvLeft, cvTop,
// cvRight, cvBottom));
// cvTop += corr.y;
// cvBottom += corr.y;


// When the current view is as small as the screen in width, clamp
// it horizontally
Point corr = getCorrection(getScrollBounds(cvLeft, cvTop, cvRight, cvBottom));
cvRight += corr.x;
cvLeft += corr.x;
}


cv.layout(cvLeft, cvTop, cvRight, cvBottom);


if (mCurrent > 0) {
View lv = getOrCreateChild(mCurrent - 1);
Point leftOffset = subScreenSizeOffset(lv);
/*
* int gap = leftOffset.x + GAP + cvOffset.x; lv.layout(cvLeft -
* lv.getMeasuredWidth() - gap, (cvBottom + cvTop -
* lv.getMeasuredHeight())/2, cvLeft - gap, (cvBottom + cvTop +
* lv.getMeasuredHeight())/2);
*/


int gap = leftOffset.y + GAP + cvOffset.y;
lv.layout((cvRight + cvLeft - lv.getMeasuredWidth()) / 2, cvTop - lv.getMeasuredHeight() - gap,
(cvRight + cvLeft + lv.getMeasuredWidth()) / 2, cvTop - gap);


}


if (mCurrent + 1 < mAdapter.getCount()) {
View rv = getOrCreateChild(mCurrent + 1);
Point rightOffset = subScreenSizeOffset(rv);
/*
* int gap = cvOffset.x + GAP + rightOffset.x; rv.layout(cvRight +
* gap, (cvBottom + cvTop - rv.getMeasuredHeight())/2, cvRight +
* rv.getMeasuredWidth() + gap, (cvBottom + cvTop +
* rv.getMeasuredHeight())/2);
*/


int gap = cvOffset.y + GAP + rightOffset.y;
rv.layout((cvRight + cvLeft - rv.getMeasuredWidth()) / 2, cvBottom + gap,
(cvRight + cvLeft + rv.getMeasuredWidth()) / 2, cvBottom + rv.getMeasuredHeight() + gap);


}


invalidate();
}

你以为这样就可以了么,no,还需要将onFling方法换成如下方法:

public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if (mScaling)
return true;


View v = mChildViews.get(mCurrent);
if (v != null) {
Rect bounds = getScrollBounds(v);
switch (directionOfTravel(velocityX, velocityY)) {


case MOVING_UP:
if (bounds.top >= 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_DOWN:
if (bounds.bottom <= 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;
// If the page has been dragged out of bounds then we want to spring
// back
// nicely. fling jumps back into bounds instantly, so we don't want
// to use
// fling in that case. On the other hand, we don't want to forgo a
// fling
// just because of a slightly off-angle drag taking us out of bounds
// other
// than in the direction of the drag, so we test for out of bounds
// only
// in the direction of travel.
//
// Also don't fling if out of bounds in any direction by more than
// fling
// margin
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);
mStepper.prod();
}
}


return true;
}

这样就完美实现了解析PDF+上下滑动翻页,做这个耗费了博主好久,只想分享给大家帮助更多想博主一样迷茫的人。


0 0
原创粉丝点击