package com.poqop.document;
import java.util.HashMap;
import java.util.Map;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.PointF;
import android.graphics.RectF;
import android.util.FloatMath;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.widget.Scroller;
import com.poqop.document.events.ZoomListener;
import com.poqop.document.models.CurrentPageModel;
import com.poqop.document.models.DecodingProgressModel;
import com.poqop.document.models.ZoomModel;
import com.poqop.document.multitouch.MultiTouchZoom;
/**
* 屏幕滚动
* 处理用户翻页操作,比如滑动、点击上下左右键等。
* 此时根据具体的用户操作计算需要显示哪几页,通知BaseViewerActivity去显示这些页
* @author Administrator
*
*/
public class DocumentView extends View implements ZoomListener {
final ZoomModel zoomModel;
private final CurrentPageModel currentPageModel;
DecodeService decodeService;
private final HashMap<Integer, Page> pages = new HashMap<Integer, Page>();
private boolean isInitialized = false;
private int pageToGoTo;
private float lastX;
private float lastY;
private VelocityTracker velocityTracker;
private final Scroller scroller;
DecodingProgressModel progressModel;
private RectF viewRect;
private boolean inZoom;
private long lastDownEventTime;
private static final int DOUBLE_TAP_TIME = 500;
private MultiTouchZoom multiTouchZoom;
private static final int MAX_VALUE = 3800;
private static final float MULTIPLIER = 400.0f;
static final int NONE = 0; //空闲
static final int DRAG = 1; //拖动
static final int ZOOM = 2; //缩放
int mode = NONE;
private float oldDist;
private PointF midPoint = new PointF();
private boolean isZoom = false;
private boolean dblclick = true;
public DocumentView(Context context, final ZoomModel zoomModel,
DecodingProgressModel progressModel,
CurrentPageModel currentPageModel) {
super(context);
this.zoomModel = zoomModel;
this.progressModel = progressModel;
this.currentPageModel = currentPageModel;
setKeepScreenOn(true);
scroller = new Scroller(getContext());
setFocusable(true);
setFocusableInTouchMode(true);
}
public void setDecodeService(DecodeService decodeService) {
this.decodeService = decodeService;
}
private void init() {
if (isInitialized) {
return;
}
final int width = decodeService.getEffectivePagesWidth(); //获取试图的宽
final int height = decodeService.getEffectivePagesHeight(); //高
for (int i = 0; i < decodeService.getPageCount(); i++) {
pages.put(i, new Page(this, i));
pages.get(i).setAspectRatio(width, height);
}
isInitialized = true;
invalidatePageSizes();
goToPageImpl(pageToGoTo);
}
private void goToPageImpl(final int toPage) {
scrollTo(0, pages.get(toPage).getTop());
}
/*
* 让视图更新
*/
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
// bounds could be not updated
post(new Runnable() {
public void run() {
currentPageModel.setCurrentPageIndex(getCurrentPage());
}
});
if (inZoom) {
return;
}
// on scrollChanged can be called from scrollTo just after new layout
// applied so we should wait for relayout
post(new Runnable() {
public void run() {
updatePageVisibility();
}
});
}
private void updatePageVisibility() {
for (Page page : pages.values()) {
page.updateVisibility();
}
}
public void commitZoom() {
for (Page page : pages.values()) {
page.invalidate();
}
inZoom = false;
}
public void showDocument() {
// use post to ensure that document view has width and height before
// decoding begin
post(new Runnable() {
public void run() {
init();
updatePageVisibility();
}
});
}
public void goToPage(int toPage) {
if (isInitialized) {
goToPageImpl(toPage);
} else {
pageToGoTo = toPage;
}
}
public int getCurrentPage() {
for (Map.Entry<Integer, Page> entry : pages.entrySet()) {
if (entry.getValue().isVisible()) {
return entry.getKey();
}
}
return 0;
}
/**
* 缩放功能的处理
*/
public void zoomChanged(float newZoom, float oldZoom) {
inZoom = true;
stopScroller();
final float ratio = newZoom / oldZoom;
invalidatePageSizes();
scrollTo(
(int) ((getScrollX() + getWidth() / 2) * ratio - getWidth() / 2),
(int) ((getScrollY() + getHeight() / 2) * ratio - getHeight() / 2));
postInvalidate();
}
/**
* 触摸屏事件
*/
@Override
public boolean onTouchEvent(MotionEvent ev) {
super.onTouchEvent(ev);
if (multiTouchZoom != null) {
if (multiTouchZoom.onTouchEvent(ev)) {
return true;
}
if (multiTouchZoom.isResetLastPointAfterZoom()) {
setLastPosition(ev);
multiTouchZoom.setResetLastPointAfterZoom(false);
}
}
if (velocityTracker == null) {
velocityTracker = VelocityTracker.obtain(); //用obtain()函数来获得类的实例,开始计算速度
}
velocityTracker.addMovement(ev); //这个方法是将motion event 添加到velocityTracker
switch (ev.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
mode = DRAG;
/*
* 双击放大
* 用第一次点击和第二次点击的时间差来判断是否为双击
*/
if ((ev.getEventTime() - lastDownEventTime < DOUBLE_TAP_TIME) && dblclick) {
setCurrentValue(getmagnifyCurrentValues() - (ev.getX() - lastX));
dblclick=false;
mode = DRAG;
/*
* 双击缩小
*/
}else if((ev.getEventTime() - lastDownEventTime < DOUBLE_TAP_TIME) && !dblclick) {
setCurrentValue(getReduceCurrentValues() - (ev.getX() - lastX));
dblclick=true;
}else{
if (!scroller.isFinished()) {
scroller.abortAnimation();
zoomModel.commit();
}
else {
lastDownEventTime = ev.getEventTime();
}
}
stopScroller();
setLastPosition(ev);
/**
* velocityTracker 用来追踪触摸事件(flinging事件和其他手势事件)的速率
* fling(int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, int maxY)
* 方法进行控件滚动时各种位置坐标数值的计算
*/
case MotionEvent.ACTION_UP:
velocityTracker.computeCurrentVelocity(1000); // 初始化速率
scroller.fling(getScrollX(), getScrollY(), (int) -velocityTracker.getXVelocity(),
(int) -velocityTracker.getYVelocity(), getLeftLimit(), getRightLimit(), getTopLimit(), getBottomLimit());
velocityTracker.recycle(); //回收
velocityTracker = null;
mode = DRAG;
break;
/**
* API原文是 A non-primary pointer has gone down. 翻译过来就是:非第一个点按下
*/
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(ev);
midPoint(midPoint, ev);
isZoom = true;
mode = ZOOM;
break;
case MotionEvent.ACTION_POINTER_UP:
mode=DRAG;
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
scrollBy((int) (lastX - ev.getX()), (int) (lastY - ev.getY()));
setLastPosition(ev);
break;
} else if (mode==ZOOM) {
float newDist = spacing(ev);
/**
* 表示新的距离比两个手指刚触碰的距离大》》》放大 ( +10个像素用来延迟一下放大
*/
if (newDist > oldDist + 10) {
oldDist = spacing(ev);
setCurrentValue(getCurrentValue() - (ev.getX() - lastX));
lastX = ev.getX();
}
/**
* 表示新的距离比两个手指刚触碰的距离小:>>>>缩小
*/
if (newDist + 20 < oldDist) {
oldDist = spacing(ev);
setCurrentValue(getRedCurrentValues()
- (ev.getX() - lastX));
lastX = ev.getX();
}
break;
}
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
AndroidDocumentViewer(PDF阅读器).zip项目安卓应用源码下载AndroidDocumentViewer(PDF阅读器).zip项目安卓应用源码下载 1.适合学生毕业设计研究参考 2.适合个人学习研究参考 3.适合公司开发项目技术参考
资源推荐
资源详情
资源评论
收起资源包目录
AndroidDocumentViewer(PDF阅读器).zip项目安卓应用源码下载 (335个子文件)
all-wcprops 2KB
all-wcprops 2KB
all-wcprops 1KB
all-wcprops 1KB
all-wcprops 1KB
all-wcprops 612B
all-wcprops 560B
all-wcprops 560B
all-wcprops 545B
all-wcprops 532B
all-wcprops 532B
all-wcprops 528B
all-wcprops 528B
all-wcprops 428B
all-wcprops 428B
all-wcprops 424B
all-wcprops 424B
all-wcprops 401B
all-wcprops 401B
all-wcprops 393B
all-wcprops 393B
all-wcprops 252B
all-wcprops 252B
all-wcprops 210B
all-wcprops 210B
all-wcprops 210B
all-wcprops 202B
all-wcprops 85B
all-wcprops 83B
all-wcprops 82B
all-wcprops 82B
all-wcprops 82B
resources.ap_ 65KB
DocumentViewer.apk 1.36MB
com.poqop.document.MainBrowserActivity.apk 1.36MB
jarlist.cache 119B
proguard.cfg 1KB
DocumentView.class 12KB
DecodeServiceBase.class 10KB
BaseViewerActivity.class 9KB
PageTreeNode.class 8KB
BaseBrowserActivity.class 5KB
Page.class 4KB
ViewerPreferences.class 3KB
BrowserAdapter.class 3KB
PdfPage.class 3KB
GoToPageDialog.class 3KB
ZoomRoll.class 2KB
UriBrowserAdapter.class 2KB
DecodeServiceBase$DecodeTask.class 2KB
MainBrowserActivity.class 2KB
ZoomModel.class 2KB
PageTreeNode$1$1.class 2KB
DecodeServiceBase$2.class 2KB
PageViewZoomControls.class 2KB
SafeEvent.class 2KB
BaseViewerActivity$1.class 2KB
BaseBrowserActivity$1.class 2KB
DecodeServiceBase$1.class 1KB
MainBrowserActivity$1.class 1KB
BaseBrowserActivity$4.class 1KB
PdfDocument.class 1KB
PathFromUri.class 1KB
MD5StringUtil.class 1KB
PageTreeNode$1.class 1KB
BrowserAdapter$1.class 1KB
EventDispatcher.class 1KB
BaseViewerActivity$2.class 1KB
MultiTouchZoomImpl.class 1KB
DecodingProgressListener$DecodingProgressEvent.class 1KB
PdfContext.class 1KB
GoToPageDialog$2.class 1KB
CurrentPageListener$CurrentPageChangedEvent.class 1014B
DecodingProgressModel.class 957B
BaseBrowserActivity$3.class 951B
BaseBrowserActivity$2.class 947B
BaseViewerActivity$3.class 935B
ZoomChangedEvent.class 915B
BringUpZoomControlsEvent.class 888B
GoToPageDialog$1.class 878B
DocumentView$1.class 876B
ZoomListener$CommitZoomEvent.class 865B
BaseViewerActivity$4.class 864B
R$drawable.class 810B
CurrentPageModel.class 777B
DecodeService.class 726B
DocumentView$3.class 683B
DocumentView$2.class 664B
PdfViewerActivity.class 616B
VuDroidLibraryLoader.class 596B
R$id.class 519B
R.class 468B
R$layout.class 465B
R$string.class 400B
DecodingProgressListener.class 329B
BuildConfig.class 327B
CodecPage.class 323B
R$attr.class 313B
CurrentPageListener.class 313B
CodecContext.class 308B
共 335 条
- 1
- 2
- 3
- 4
资源评论
yxkfw
- 粉丝: 82
- 资源: 2万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- cd35f259ee4bbfe81357c1aa7f4434e6.mp3
- 机器学习金融反欺诈项目数据
- 虚拟串口VSPXD软件(支持64Bit)
- 多边形框架物体检测18-YOLO(v5至v11)、COCO、CreateML、TFRecord、VOC数据集合集.rar
- Python个人财务管理系统(Personal Finance Management System)
- 大数据硬核技能进阶 Spark3实战智能物业运营系统完结26章
- CHM助手:制作CHM联机帮助的插件使用手册
- SecureCRT.9.5.1.3272.v2.CN.zip
- 人大金仓(KingBase)备份还原文档
- 完结17章SpringBoot3+Vue3 开发高并发秒杀抢购系统
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功