当前位置: 首页 > news >正文

android pdf框架-10,相册浏览

MupdfViewer 这是最后apk,源码在前面的文章已经贴过了本站下载地址,只是不是最新的.可能不少是旧的内容.

subsampling-scale-image-view这是一个大图片的分块加载的实现.比较不错的.滑动方面我觉得使用flinger的效果比它要流畅,惯性要好.

也有人把这个作成pdf渲染器.但翻页就不好了.

现在的手机相册现在可能使用的是opengl实现的.

本项目中的,自定义flinger在滚动惯性上比其它要强一些.惯性太高,也会看到加载过程,反而会让人觉得慢...

多数的pdf阅读器都会用缓存.下文说到把块的缓存去了,原因之一是无法处理被回收的问题.另一个,缓存如果直接在主线程读取,因为它是同步的,会造成页面卡顿,滚动过程尤其明显.barteksc就是这样的,把它从scroller换成flinger实现滚动,就会明显感觉到卡顿,尤其在放大倍数提升到10倍后,对于barteksc,的10倍还不如我这边缩放4倍大,因为它是以最大的图片去计算的.

所以从这方面来说,我对改造后的效果还是挺满意的.

相册有很多,几乎全部是单张图片的浏览. 并不方便连续的浏览.

需求可能是这样的:

我在微博下了一些长图片,每一张在相册中查看当然可以,能放大,但是比较麻烦.

如果要生成pdf,会占了不少空间,而且照片会增加,比如拍照,会持续拍,总不能一直生成pdf,当然可以使用追加式的.

在浏览目录时,长按菜单,出现相册功能.按时间倒序排列查看.与pdf一样,所有的照片默认是同一个宽.不像barteksc它们都是保留原始宽,这样滑动后,可能容易内容滑出去了.这不是一个阅读器的好的体验方式.因为中间有一张特别宽的图片,会导致内容经常滑出去.

在pdf程序写好以后,我发现,既然生成的pdf可以,我也可以用pdf的浏览方式去查看相册.

相册图片解码速度比pdf还是要快不少的.目前没有针对三星这种拍照方向不对的照片处理.国内已经很少有三星手机了.

由于原来的pdfpage实现的接口,document等接口,添加一种实现即可.

class AlbumViewerActivity extends BaseViewerActivity {protected ProgressDialog progressDialog;@Overrideprotected DecodeService createDecodeService() {return new DecodeServiceBase(new AlbumContext());}protected void loadDocument(String path) {progressDialog=new ProgressDialog(this);progressDialog.setMessage("Loading");progressDialog.show();AppExecutors.Companion.getInstance().diskIO().execute(() -> {decodeService.open(path);AppExecutors.Companion.getInstance().mainThread().execute(() -> {progressDialog.dismiss();documentView.showDocument();});});}
}

对activity作一次重构,把加载文档放到异步线程中,因为这不是加载pdf文档,是加载一个目录下的所有图片,有可能比较耗时.

加一个context

class AlbumContext implements CodecContext {public CodecDocument openDocument(String fileName) {return AlbumDocument.openDocument(fileName);}public void setContentResolver(ContentResolver contentResolver) {}public void recycle() {}
}

然后就是文档

class AlbumDocument implements CodecDocument {ArrayList<File> files;int count = 0;private static FileFilter createFileFilter() {return pathname -> {if (pathname.isHidden()) {return false;}if (pathname.isDirectory())return false;String fname = pathname.getName().toLowerCase(Locale.ROOT);return AdapterUtils.INSTANCE.isImage(fname);};}public static AlbumDocument openDocument(String fname) {File[] fileArray = new File(fname).listFiles(createFileFilter());ArrayList<File> files = new ArrayList<>(fileArray != null ? Arrays.asList(fileArray) : Collections.<File>emptyList());Collections.sort(files, (o1, o2) -> {if (o1 == null && o2 == null) {return 0;}if (o1.isDirectory() && o2.isFile()) return -1;if (o1.isFile() && o2.isDirectory()) return 1;if (o1.lastModified() - o2.lastModified() > 0) {return -1;} else if (o1.lastModified() - o2.lastModified() < 0) { //jdk7以上需要对称,自反,传递性.return 1;} else {return 0;}});AlbumDocument document = new AlbumDocument(files);return document;}public AlbumDocument(ArrayList<File> files) {this.files = files;if (null != files) {count = files.size();}}public CodecPage getPage(int pageNumber) {return AlbumPage.createPage(files.get(pageNumber).getAbsolutePath(), pageNumber);}public int getPageCount() {return count;}@Overrideprotected void finalize() throws Throwable {recycle();super.finalize();}public synchronized void recycle() {}@Overridepublic Outline[] loadOutline() {return new Outline[0];}
}

要过滤出支持解码的图片类型,svg目前不行.

最关键的还是解码部分. 这里对每一块解码都可能重新生成一个decoder,可以优化一下.

class AlbumPage implements CodecPage {private long pageHandle = -1;int pageWidth;int pageHeight;private BitmapRegionDecoder decoder;private String path;static AlbumPage createPage(String fname, int pageno) {AlbumPage pdfPage = new AlbumPage(pageno, fname);return pdfPage;}public AlbumPage(long pageno, String fname) {this.pageHandle = pageno;this.path = fname;}public int getWidth() {if (pageWidth == 0) {decodeBound();}return pageWidth;}private void decodeBound() {BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeFile(path, options);pageWidth = options.outWidth;pageHeight = options.outHeight;}public int getHeight() {
http://www.lryc.cn/news/327972.html

相关文章:

  • 基于SSM的高校普法系统(有报告)。Javaee项目。ssm项目。
  • 数据结构刷题篇 之 【力扣二叉树基础OJ】详细讲解(含每道题链接及递归图解)
  • Jackson 2.x 系列【6】注解大全篇二
  • 在低成本loT mcu上实现深度神经网络端到端自动部署-深度神经网络、物联网、边缘计算、DNN加速——文末完整资料
  • 【linux】基础IO |文件操作符
  • 探索 2024 年 Web 开发最佳前端框架
  • 解决: MAC ERROR [internal] load metadata for docker.io/library/openjdk:17
  • View事件分发
  • 监听页面的使用时间
  • 【 yolo红外微小无人机-直升机-飞机-飞鸟目标检测】
  • Redis与数据库的一致性
  • 使用maxwell实时同步mysql数据到kafka
  • 知识图谱与大数据:区别、联系与应用
  • Nagios工具
  • 微信小程序全局数据共享
  • 算法训练营第24天|回溯算法理论基础 LeetCode 77.组合
  • pip永久修改镜像地址
  • RK3588平台开发系列讲解(硬件篇-功能外设2)
  • SpringBoot学习记录
  • 财富池指标--通达信顾比均线实战指标免费源码
  • AJAX(一):初识AJAX、http协议、配置环境、发送AJAX请求、请求时的问题
  • idea常用的快捷键总结:
  • LeetCode 热题 100 题解(一):哈希部分
  • C语言 | qsort()函数使用
  • 继承的特点 | java
  • 6、jenkins项目构建类型-项目类型介绍
  • 指针函数的应用——找出哪些学生有不及格的科目
  • 【微服务】Gateway
  • 王道C语言督学营OJ课后习题(课时14)
  • Filter、Listener、AJAX