Flutter中如何将PDF页面以ListView形式展示并实现点击选中取页码
PDF页面列表展示及选中功能实现方案
核心逻辑步骤
- 解析本地选中的PDF文件,读取总页数,逐页渲染生成对应尺寸的缩略图
- 列表组件绑定每一页的缩略图、页码数据,完成列表基础渲染
- 维护全局选中状态变量存储当前选中的页码,给每个列表项绑定点击事件
- 点击列表项时更新选中状态变量,同时刷新列表UI,给命中页码的列表项添加高亮、边框、选中标记等差异化样式,同时向外输出当前选中的页码值
Web端实现示例(基于pdf.js)
依赖说明
使用pdf.js完成PDF解析渲染,实际使用建议下载官方依赖包到本地引入,避免跨域问题。
核心代码
<!-- 页面结构 --> <input type="file" id="filePicker" accept=".pdf"> <div id="pdfPageList" class="list-container"></div> <style> .list-container { width: 200px; height: 100vh; overflow-y: auto; margin-top: 16px; } .page-item { padding: 8px; margin-bottom: 12px; border: 2px solid transparent; border-radius: 4px; cursor: pointer; } .page-item.selected { border-color: #2196F3; background-color: #e3f2fd; } .page-thumb { width: 100%; display: block; } .page-num { text-align: center; margin-top: 4px; font-size: 12px; } </style>
let selectedPage = null; const pdfjsLib = window['pdfjs-dist/build/pdf']; // 替换为本地存放的pdf.worker.js路径 pdfjsLib.GlobalWorkerOptions.workerSrc = './pdf.worker.js'; // 监听文件选择器输入,解析PDF document.querySelector('#filePicker').addEventListener('change', async (e) => { const file = e.target.files[0]; if (file.type !== 'application/pdf') return; const arrayBuffer = await file.arrayBuffer(); const pdf = await pdfjsLib.getDocument(arrayBuffer).promise; renderPageList(pdf); }); // 渲染所有页到列表 async function renderPageList(pdf) { const container = document.querySelector('#pdfPageList'); container.innerHTML = ''; for (let i = 1; i <= pdf.numPages; i++) { const page = await pdf.getPage(i); const viewport = page.getViewport({scale: 0.5}); const canvas = document.createElement('canvas'); const context = canvas.getContext('2d'); canvas.height = viewport.height; canvas.width = viewport.width; await page.render({canvasContext: context, viewport: viewport}).promise; // 生成列表项 const item = document.createElement('div'); item.className = 'page-item'; item.dataset.pageNum = i; item.innerHTML = ` <img src="${canvas.toDataURL()}" class="page-thumb" alt="第${i}页"> <div class="page-num">第${i}页</div> `; // 绑定点击事件 item.addEventListener('click', () => { // 移除之前选中项的样式 document.querySelectorAll('.page-item.selected').forEach(el => el.classList.remove('selected')); // 标记当前选中 item.classList.add('selected'); selectedPage = i; console.log('当前选中页码:', selectedPage); // 此处可获取选中页码做后续业务处理 }); container.appendChild(item); } }
Android端实现示例(基于原生PdfRenderer)
- 声明文件读取权限,通过文件选择器拿到本地PDF的Uri
- 用
PdfRenderer加载PDF文件,逐页渲染生成Bitmap缩略图 - 用RecyclerView承载列表,Adapter中维护
selectedPosition变量存储当前选中的下标(列表下标从0开始) - 给列表项绑定点击事件,点击时更新
selectedPosition,调用notifyDataSetChanged()刷新列表,在onBindViewHolder中判断当前位置是否等于选中位置,给对应item添加选中样式即可 - 选中的页码直接取
selectedPosition + 1即可获取。
内容的提问来源于stack exchange,提问作者Awais MåLik
相关产品推荐
相关产品推荐

