/**
- 加载PDF文件
*/
private void loadPdf() {
Intent intent = getIntent();
if (intent != null) {
assetsFileName = intent.getStringExtra(“AssetsPdf”);
if (assetsFileName != null) {
displayFromAssets(assetsFileName);
} else {
uri = intent.getData();
if (uri != null) {
displayFromUri(uri);
}
}
}
}
/**
- 基于assets显示 PDF 文件
- @param fileName 文件名称
*/
private void displayFromAssets(String fileName) {
pdfView.fromAsset(fileName)
.defaultPage(pageNumber)
.onPageChange(this)
.enableAnnotationRendering(true)
.onLoad(this)
.scrollHandle(new DefaultScrollHandle(this))
.spacing(10) // 单位 dp
.onPageError(this)
.pageFitPolicy(FitPolicy.BOTH)
.load();
}
/**
- 基于uri显示 PDF 文件
- @param uri 文件路径
*/
private void displayFromUri(Uri uri) {
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