android pdf框架-4,分析vudroid源码1

前言

上文基于recyclerview修改,没有自定义layoutmanager,其实并不是一个好的阅读器,缩放功能有限,放大了容易内存溢出.

本文,从修改vudroid源码来完成一个阅读器.

为什么是vudroid?

  • 它是基于view系统的
  • 相对完整的功能
  • 代码没有那么抽象,简洁容易修改
  • 功能没有完善,有修改空间
  • 可以容易做一个sdk对外提供

原作者ebookdroid更好,基于opengl实现的,修改更麻烦,代码非常抽象.已经是一个完整的项目,各项功能都完善了,也没有修改的必要.

先理解它的页面结构

策略模式的应用,让外部的uri在内部不同的策略中选一个显示的activity.

而在解码时又提供了策略模式,针对不同的类型,提供不同的解码实现.

页面分割

它对页面进行了抽象rect(0,0,1.0,1.0);然后对它进行分割.分割的算法按层级.如果当前的缩放度加大了,达到层级需要再放大一级时,就会再分裂.

比如一个页面,分裂成4个,4个页面中的第一块区域,随时缩放级别加大,不满足了,就会继续分裂为4个,层级加一级.

默认的 PageTreeNode里面

private static final int SLICE_SIZE = 256 * 256 * 1;,这里1是旧设备,屏蔽较小,当前的设备都已经1080的了,可以设置为4.

对于page与pagetreenode现在没有什么要修改了.

private void invalidateChildren() {boolean isThresholdHit = thresholdHit();boolean isVisible = isVisible();if (isThresholdHit && children == null && isVisible) {final int newThreshold = treeNodeDepthLevel * 2;children = new PageTreeNode[]{new PageTreeNode(documentView, new RectF(0, 0, 0.5f, 0.5f), page, newThreshold, this),new PageTreeNode(documentView, new RectF(0.5f, 0, 1.0f, 0.5f), page, newThreshold, this),new PageTreeNode(documentView, new RectF(0, 0.5f, 0.5f, 1.0f), page, newThreshold, this),new PageTreeNode(documentView, new RectF(0.5f, 0.5f, 1.0f, 1.0f), page, newThreshold, this)};}if (!isThresholdHit && getBitmap() != null || !isVisible) {recycleChildren();}}

当缩放级别大了,需要再分钱时,它会生成4个新的子节点,那么当前的节点就不再有bitmap了.

这是页面的逻辑分割,到具体的物理分割需要一个映射.

getTargetRect(),这个方法是对page.bounds与逻辑大小进行映射,得到一个目标rect.这样达到分块渲染的效果.
Page对象

一个页面包含一个页面树

Page(DocumentView documentView, int index) {this.documentView = documentView;this.index = index;node = new PageTreeNode(documentView, new RectF(0, 0, 1, 1), this, ZOOM_THRESHOLD, null);
}

页与页码都存起来了,子节点在node中,page本身没有画bitmap,它会调用node实现具体的绘图.

它处理长宽比例,页面宽度,背景绘制

invalidate方法,就是与view的同名,刷新视图用的.在外部的view调用.
DocumentView

这是view,处理滚动,绘制,页面加载,缩放等一切与view相关的.

因为它只是普通的view,那么layout后,高宽是固定的,如何实现多页面的滚动,就是scroll实现的,这样就会有偏移量.在滚动绘制时,需要处理每一个page的绘制.但如果每一个page都要绘制,性能是极差的.所以需要判断page是否在可见区.

先看它的流程:

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);}System.out.println("DecodeService:" + pages.size() + " pageToGoTo:" + pageToGoTo);isInitialized = true;currentPageModel.setPageCount(decodeService.getPageCount());invalidatePageSizes();goToPageImpl(pageToGoTo);}

先把所有页面的物理高宽计算出,存起来,然后初始化页面的view显示时的大小.这一步操作比较耗时,可以考虑进入非ui线程,而且页面的高宽是固定的,除非pdf被修改,这是可以缓存在文件中的.

invalidatePageSizes,初始化页面的实际显示的高宽,这个高宽是一个pdf根据dpi=72得到的高宽,显示在当前的view系统上多大,这时就会涉及到缩放了.
float heightAccum = 0;int width = getWidth();float zoom = zoomModel.getZoom();for (int i = 0; i < pages.size(); i++) {Page page = pages.get(i);float pageHeight = page.getPageHeight(width, zoom);page.setBounds(new RectF(0, heightAccum, width * zoom, heightAccum + pageHeight));heightAccum += pageHeight;}

zoom默认是1,因为还没有进入缩放操作.但是这里的getpageheight却是根据view的宽高与pdf页面的宽高计算的.这个很好理解

float getPageHeight(int mainWidth, float zoom) {return mainWidth / getAspectRatio() * zoom;
}

计算出所有页面高宽后,以后每一个页面,滚动到哪里就有数了.

接着它就开始跳转到页面.

上面是构造函数调用时的初始化.在布局后也会进行一次初始化

protected void onL

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/698506.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于正则中的Pattern和Matcher的使用

关于正则中的Pattern和Matcher的使用 1 简介2 语法3 案例 在项目中, 经常需要对请求的数据进行格式,内容校验, 而使用正则表达式, 比较简单优雅实现校验功能. 故记录一下正则中Pattern和Matcher的使用. 1 简介 ​ java.util.regex包下的Pattern和Matcher都是Java中用于正则表达…

Spring启动生命周期

Spring Boot 生命周期详解 Spring Boot 应用程序的生命周期包含几个阶段&#xff0c;每个阶段都有特定的事件和钩子&#xff0c;允许开发者在应用程序的不同生命周期阶段插入自定义逻辑。以下是 Spring Boot 生命周期的主要阶段和对应的事件&#xff1a; 准备阶段&#xff1a;…

【Docker实操】部署php项目

概述 最终达成的容器部署结构和原理如下图&#xff1a; 一、获取nginx、php官方镜像 docker pull nginx //拉取nginx官方镜像 docker pull php:7.4-fpm //拉取php官方镜像需要获取其他可用的php版本&#xff0c;可以上【docker hub】搜索【php】&#xff0c;所有的【xxx-fp…

【工具】阿莫智能设备之脱机烧录器K202C-1

注意&#xff0c;本文档仅仅是介绍烧录器的资料构成&#xff0c;并非烧录器的说明书&#xff0c;详细请看各对说明书及视频。 1. 资料图解 首先需要下载资料&#xff0c;通常稳定发布版本可以从 www.amomcu.cn 下载&#xff0c; 也可以向我们客服获取最新版本&#xff0c; 获…

浅谈redis之SDS

SDS 什么是SDSSDS结构len的作用free的作用buf的作用简单示例 SDS机制重新分配内存分配内存机制小于1MB情况大于1MB情况为什么这样分配 惰性释放内存 什么是SDS SDS&#xff1a;全名 simple dynamic string&#xff0c;意为简单动态字符串&#xff0c;作为redis里的一种数据结构…

六.生成makefile文件 并基于makefile文件编译opencv

1.点击【Generate】 生成makefile文件 2.进入目录下编译opencv源码&#xff0c;mingw32-make -j 8 3..编译出现报错 4.取消[WITH_OPENCL_D3D11_NV]选项&#xff0c;再次【configure】【generate】 然后再次编译&#xff1a;mingw32-make -j 8

科技守护大唐遗宝,预防保护传承千年

​ 一、“大唐遗宝——何家村窖藏出土文物展” 陕西历史博物馆的“唐朝遗宝——何家村窖藏出土文物展”算得上是博物馆展览的典范。展览不仅在于展现了数量之多、等级之高、种类之全&#xff0c;更在于对唐朝历史文化的深入揭露。 走入大唐财产展厅&#xff0c;好像穿越千年前…

解决TCP中Bind failed烦恼

文章目录 概要样例代码 概要 当第一次运行服务端时正常&#xff0c;第二次运行时出现Bind failed问题。 在实际使用中&#xff0c;如果您尝试启动一个服务端程序并且遇到了 “Bind failed” 的错误信息&#xff0c;这通常意味着尝试绑定&#xff08;bind&#xff09;的端口已…

Boss直聘聊天问答

主动打招呼常用语&#xff1a; 1.您好&#xff0c;我看到贵公司的招聘需求很符合我的技术栈&#xff0c;方便约个面试聊一聊嘛&#xff1f; 2.我叫郭治江&#xff0c;2022年毕业&#xff0c;物联网工程专业&#xff0c;目前从事Java开发工作已经三年了&#xff0c;上家公司是…

推理任务稳定提点大揭秘:力大砖飞背后的科学

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

GB/T 17639-2023 长丝纺粘针刺非织造土工布检测

长丝纺粘针刺非织造土工布是指以聚酯或聚丙烯为原料&#xff0c;经纺丝、铺网、针刺加固而成的长丝纺粘针刺非织造布。 GB/T 17639-2023 长丝纺粘针刺非织造土工布测试项目&#xff1a; 测试要求 测试标准 纵横向抗拉强度 GB/T 15788 纵横向最大负荷下伸长率 GB/T 15788 …

Nginx相关命令

进入nginx程序目录&#xff0c;使用cmd在本目录下打开&#xff0c; 启动nginx&#xff1a;使用命令start nginx 本地重启nginx&#xff1a;nginx -s reload 停止&#xff1a;nginx -s stop 或者 nginx.exe -s quit 查看Nginx版本&#xff1a;nginx -v

功率MOSFET体二极管的连续载流能力

功率MOSFET体二极管的连续载流能力 1.概述2.MOSFET 漏源电压限制3.体二极管电流能力4.计算案例5.降额 tips&#xff1a;资料主要来自网络&#xff0c;仅供学习使用。 在电力电子领域或者在大功率应用场境下&#xff0c;我们经常会用到开关管功率MOSFET以及其内部的二极管。 那…

Nginx是什么?怎么用?

Nginx介绍 Nginx (读作 “engine-x”) 是一款高性能的HTTP和反向代理服务器&#xff0c;同时也可用作IMAP/POP3/SMTP代理服务器。由俄罗斯程序员Igor Sysoev开发&#xff0c;首次公开发布于2004年。Nginx以其稳定性、高性能和低内存消耗闻名&#xff0c;尤其擅长处理静态文件、…

2.23学习总结

铅球杯https://www.luogu.com.cn/problem/B3911 题目描述 蓝边铅球组织了“铅球杯”数据标注大赛。为了实现 Au 大满贯的宏大征途&#xff0c;LeAuingZ 报名参加了比赛。 蓝边铅球给出了 &#xfffd;N 个 int 类型变量的名字及其值&#xff0c;并要求 LeAuingZ 对 &#xfffd…

安全生产:AI视频智能分析网关V4如何应用在企业安全生产场景中?

随着科技的不断进步&#xff0c;视频智能分析技术在安全生产领域中的应用越来越广泛。这种技术通过计算机视觉和人工智能算法&#xff0c;可以对监控视频进行自动分析和处理&#xff0c;以实现多种功能&#xff0c;如目标检测、行为识别、异常预警等。今天我们以TSINGSEE青犀AI…

Boom 3D for Mac 破解版(3D环绕立体声音效增强软件)2.0.2中文支持M3

Mac上想要听一场极致的音乐或看一场畅快淋漓的电影&#xff1f;这些Boom 3D for Mac都可以帮您实现&#xff0c;是一款Mac音效增强工具&#xff0c;可以将二维度的音效转换成三维度&#xff0c;让您彻底的享受一下极致的听觉盛宴&#xff01; Boom 3D 2.0.2 Mac版主打音乐播放器…

【Rust】——控制流(if-else,循环)

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…

centos7 arm服务器编译安装onnxruntime-gpu

前言 ONNX Runtime是适用于Linux,Windows和Mac上ONNX格式的机器学习模型的高性能推理引擎,但在arm服务器上,onnxruntime只有CPU版的,GPU版的没有,因此需要自行去编译GPU版本的才可以。 环境准备 1、python3.8 2、cmake:2.26.0版本以上,可以直接下载aarch64版本的进行…

[VulnHub靶机渗透] HA: Narak

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【java】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏 …