You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Android Studio中通过barteksc的Android PdfViewer访问PDF目录

解决barteksc Android PdfViewer获取PDF目录的问题

barteksc的Android PdfViewer底层依赖PdfiumAndroid,控制台打印的目录其实是PDF的大纲(Bookmark/Outline),但库本身没有直接暴露获取大纲的API,需要通过PdfiumCore的原生方法来解析:

实现步骤

1. 确认依赖配置

如果尚未添加相关依赖,在项目的build.gradle中加入:

implementation 'com.github.barteksc:android-pdf-viewer:3.2.0-beta.1'
// 或直接依赖Pdfium核心库
implementation 'com.github.barteksc:piumcore:1.9.0'

2. 读取Assets中的PDF并解析大纲

直接使用PdfiumCore打开Assets内的PDF文件,通过递归遍历大纲节点提取目录信息:

import com.shockwave.pdfium.PdfDocument;
import com.shockwave.pdfium.PdfiumCore;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

// 在Activity/Fragment中实现
private List<DirectoryItem> directoryList = new ArrayList<>();

private void loadPdfDirectory() {
    PdfiumCore pdfiumCore = new PdfiumCore(this);
    try {
        // 打开Assets中的目标PDF
        InputStream inputStream = getAssets().open("target_file.pdf");
        PdfDocument pdfDocument = pdfiumCore.newDocument(inputStream);
        
        // 获取大纲根节点
        PdfDocument.Bookmark rootBookmark = pdfiumCore.getBookmarks(pdfDocument);
        
        // 遍历所有大纲节点,收集目录数据
        traverseBookmarks(rootBookmark);
        
        // 关闭文档释放资源
        pdfiumCore.closeDocument(pdfDocument);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

// 递归遍历大纲节点
private void traverseBookmarks(PdfDocument.Bookmark bookmark) {
    if (bookmark == null) return;
    
    // 提取标题和页码(Pdfium返回的pageIdx是0索引,转成用户习惯的1-based)
    String chapterTitle = bookmark.getTitle();
    int displayPage = bookmark.getPageIdx() + 1;
    
    // 将目录项存入集合
    directoryList.add(new DirectoryItem(chapterTitle, displayPage));
    
    // 遍历子目录节点
    for (PdfDocument.Bookmark child : bookmark.getChildren()) {
        traverseBookmarks(child);
    }
}

// 自定义数据类存储目录项
public static class DirectoryItem {
    public String title;
    public int page;
    
    public DirectoryItem(String title, int page) {
        this.title = title;
        this.page = page;
    }
}

3. 关键注意事项

  • 页码转换:Pdfium返回的pageIdx是0起始索引,需加1才能和控制台显示的1-based页码一致;
  • 资源释放:必须调用pdfiumCore.closeDocument()关闭文档,避免内存泄漏;
  • 异常处理:需捕获IO异常,处理文件读取失败的场景。

替代方案(不推荐)

如果已经通过PdfView加载了PDF,也可以通过反射获取内部的PdfDocument实例,但该方式依赖库的内部实现,存在版本兼容风险:

import com.shockwave.pdfium.PdfDocument;
import com.shockwave.pdfium.PdfiumCore;
import java.lang.reflect.Field;

private void getDirectoryFromLoadedPdfView(PdfView pdfView) {
    try {
        Field mPdfDocumentField = pdfView.getClass().getDeclaredField("mPdfDocument");
        mPdfDocumentField.setAccessible(true);
        PdfDocument pdfDocument = (PdfDocument) mPdfDocumentField.get(pdfView);
        
        PdfiumCore pdfiumCore = new PdfiumCore(this);
        PdfDocument.Bookmark rootBookmark = pdfiumCore.getBookmarks(pdfDocument);
        traverseBookmarks(rootBookmark);
    } catch (NoSuchFieldException | IllegalAccessException e) {
        e.printStackTrace();
    }
}

内容的提问来源于stack exchange,提问作者Shani74

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 18:23:01