基于AndroidPDFViewer实现PDF点击标记点位功能的技术咨询
嗨,我刚好折腾过AndroidPDFViewer的自定义标记功能,给你一步步拆解怎么实现点击加标记点的需求:
实现AndroidPDFViewer点击添加标记点的方案
1. 先搞定坐标转换核心逻辑
这个库的屏幕坐标和PDF内部坐标是分离的,所以第一步要搞懂怎么把用户点击的屏幕位置,转换成PDF页面里的真实坐标。库本身提供了现成的转换方法,不用自己算缩放和偏移,省心很多。
2. 定义标记点数据结构
先创建一个简单的数据类,用来存每个标记点的关键信息:
data class MarkerPoint( val pageNumber: Int, // 标记所在的PDF页码 val pdfX: Float, // PDF页面内的X坐标 val pdfY: Float // PDF页面内的Y坐标 )
然后用一个可变列表来维护所有标记点:private val markers = mutableListOf<MarkerPoint>()
3. 捕获点击事件并保存标记点
给PDFView设置触摸监听,捕获用户的点击动作,同时完成坐标转换和数据存储:
pdfView.setOnTouchListener { v, event -> // 只处理手指抬起的动作,避免重复触发 if (event.action == MotionEvent.ACTION_UP) { val currentPage = pdfView.currentPage // 把屏幕点击坐标转换成当前PDF页面内的坐标 val pdfPoint = pdfView.convertScreenPointToPdfPoint(event.x, event.y) // 将标记点加入列表 markers.add(MarkerPoint(currentPage, pdfPoint.x, pdfPoint.y)) // 触发重绘,让标记点显示出来 pdfView.invalidate() return@setOnTouchListener true } false }
4. 叠加绘制标记点
通过库的OnDrawListener,在PDF内容绘制完成后,叠加绘制我们的标记点:
pdfView.setOnDrawListener { canvas, pageWidth, pageHeight, displayedPage -> // 只绘制当前显示页面的标记点 val currentPageMarkers = markers.filter { it.pageNumber == displayedPage } // 配置标记点的画笔样式 val markerPaint = Paint().apply { color = Color.RED style = Paint.Style.FILL strokeWidth = 8f isAntiAlias = true } // 遍历绘制每个标记点 currentPageMarkers.forEach { marker -> // 把PDF内部坐标转回屏幕画布坐标 val screenPoint = pdfView.convertPdfPointToScreenPoint(marker.pdfX, marker.pdfY, displayedPage) // 画一个圆形标记,大小可以自己调整 canvas.drawCircle(screenPoint.x, screenPoint.y, 16f, markerPaint) } }
给后续测距功能留的小铺垫
现在你存储的每个标记点都带着PDF页面的真实坐标,后续做两点测距时:
- 先通过
pdfView.getPageWidth(pageNumber)和pdfView.getPageHeight(pageNumber)获取PDF页面的真实尺寸(单位是点,1点=1/72英寸) - 计算两个标记点的坐标差,再结合页面尺寸换算成你需要的物理单位(比如厘米、英寸)就行
小提示:如果需要支持跨页面标记,记得在页面切换时触发一次重绘,确保标记点能在对应页面正确显示。
内容的提问来源于stack exchange,提问作者Vincent Herreros




