Android原生PDF功能实现,Android开发面试书籍

/**

  • 加载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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值