Android原生PDF功能实现

pdfView.fromUri(uri)
.defaultPage(pageNumber)
.onPageChange(this)
.enableAnnotationRendering(true)
.onLoad(this)
.scrollHandle(new DefaultScrollHandle(this))
.spacing(10) // 单位 dp
.onPageError(this)
.load();
}

/**

  • 当成功加载PDF:
  • 1、可获取PDF的目录信息
  • @param nbPages the number of pages in this PDF file
    */
    @Override
    public void loadComplete(int nbPages) {
    //获得文档书签信息
    List<PdfDocument.Bookmark> bookmarks = pdfView.getTableOfContents();
    if (catelogues != null) {
    catelogues.clear();
    } else {
    catelogues = new ArrayList<>();
    }
    //将bookmark转为目录数据集合
    bookmarkToCatelogues(catelogues, bookmarks, 1);
    }

/**

  • 将bookmark转为目录数据集合(递归)
  • @param catelogues 目录数据集合
  • @param bookmarks 书签数据
  • @param level 目录树级别(用于控制树节点位置偏移)
    */
    private void bookmarkToCatelogues(List catelogues, List<PdfDocument.Bookmark> bookmarks, int level) {
    for (PdfDocument.Bookmark bookmark : bookmarks) {
    TreeNodeData nodeData = new TreeNodeData();
    nodeData.setName(bookmark.getTitle());
    nodeData.setPageNum((int) bookmark.getPageIdx());
    nodeData.setTreeLevel(level);
    nodeData.setExpanded(false);
    catelogues.add(nodeData);
    if (bookmark.getChildren() != null && bookmark.getChildren().size() > 0) {
    List treeNodeDatas = new ArrayList<>();
    nodeData.setSubset(treeNodeDatas);
    bookmarkToCatelogues(treeNodeDatas, bookmark.getChildren(), level + 1);
    }
    }
    }

@Override
public void onPageChanged(int page, int pageCount) {
pageNumber = page;
}

@Override
public void onPageError(int page, Throwable t) {
}

/**

  • 从缩略图、目录页面带回页码,跳转到指定PDF页面
  • @param requestCode
  • @param resultCode
  • @param data
    */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_OK) {
    int pageNum = data.getIntExtra(“pageNum”, 0);
    if (pageNum > 0) {
    pdfView.jumpTo(pageNum);
    }
    }
    }

@Override
protected void onDestroy() {
super.onDestroy();
//是否内存
if (pdfView != null) {
pdfView.recycle();
}
}
}

PDF阅读页面的布局文件:activity_pdf.xml

<?xml version="1.0" encoding="utf-8"?>


<com.github.barteksc.pdfviewer.PDFView
android:id=“@+id/pdfView”
android:layout_width=“match_parent”
android:layout_height=“match_parent”
android:layout_below=“@+id/rl_top”/>

7、PDF目录树的实现

目录树的数据(目录名称、页码…),已在上个页面获取了,所以此页面只需考虑目录树控件的实现。

注意:之所以没在这个页面单独获取目录树的数据,主要考虑到android-pdfview、pdfium内存占用太大了,不想再次创建Pdf的相关对象。

7.1、PDF目录树效果图

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

7.2、树形控件如何实现?

安卓默认没有树形控件,不过我们可以使用RecyclerView或ListView实现。
如上图所示:

列表每一行为一条目录数据,主要包括:名称、页码;
如果有子目录,则出现箭头图片,该项可折叠、展开,箭头方向随之改变;
子目录的名称文本随目录树级别递增向右偏移;

当前Demo实现方式为RecyclerView,应该如何实现上面的效果?
可在adapter中处理页面效果、事件效果:
1、列表项内容展示

1、使用垂直线性布局管理器;
2、每个item包含:箭头图片(如果有子目录,则显示)、命令名称文本、页码文本;

2、折叠效果

1、控制adapter数据集合的内容即可,如果某节点折叠了,就把对应的子目录数据删除即可,
反之,加上,再notifyDataSetChanged通知数据源改变;
2、除此之外,还需有一个状态来标记当前节点是展开还是折叠,用于控制箭头图片方向的显示;

3、目录文本向右偏移效果

可通过目录树层级 * 固定左侧间隔(如: 20dp),然后为目录的textview控件设置偏移即可;

目录树层级树如何获取? 可选方案:
1、递归集合自动获取(需要遍历,效率低一点,如果是可编辑的目录结构,建议选择)
2、创建数据的时候,直接写死(因当前demo的PDF目录结构不会被编辑,所以直接选择这个方案吧)

7.3、代码实现:

树形控件的数据对象TreeNodeData:

/**

  • 树形控件数据类(会用于页面间传输,所以需实现Serializable 或 Parcelable)
  • 作者:齐行超
  • 日期:2019.08.07
    */
    public class TreeNodeData implements Serializable {
    //名称
    private String name;
    //页码
    private int pageNum;
    //是否已展开(用于控制树形节点图片显示,即箭头朝向图片)
    private boolean isExpanded;
    //展示级别(1级、2级…,用于控制树形节点缩进位置)
    private int treeLevel;
    //子集(用于加载子节点,也用于判断是否显示箭头图片,如集合不为空,则显示)
    private List subset;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getPageNum() {
return pageNum;
}

public void setPageNum(int pageNum) {
this.pageNum = pageNum;
}

public boolean isExpanded() {
return isExpanded;
}

public void setExpanded(boolean expanded) {
isExpanded = expanded;
}

public int getTreeLevel() {
return treeLevel;
}

public void setTreeLevel(int treeLevel) {
this.treeLevel = treeLevel;
}

public List getSubset() {
return subset;
}

public void setSubset(List subset) {
this.subset = subset;

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值