我有自己的自定义视图,该视图扩展了RecyclerView
,并使用它来呈现多页文档。适配器中的每个项目都是一页。
我想添加缩放和平移整个文档的功能(不是每个页面都单独显示)。
我尝试遵循Android指南here,但仍然无法同时缩放和平移。
我目前的做法是:
GestureDetector
来检测平移手势ScaleGestureDetector
来检测捏手势invalidate()
并在Canvas
方法中适当修改drawChild
。这是我不确定如何正确实施的最后一步。
我正在使用此数据类来跟踪视图的当前平移和缩放:
private data class PanAndZoom(
var scaleFactor: Float,
var focusX: Float,
var focusY: Float,
var panX: Float ,
var panY: Float
)
// field in my custom view initialised like this:
private val panAndZoom = PanAndZoom(1f, 0f, 0f, 0f, 0f)
这是接收手势时更新值的方法:
private val scaleGestureDetector = ScaleGestureDetector(context, object : ScaleGestureDetector.SimpleOnScaleGestureListener() {
override fun onScale(detector: ScaleGestureDetector): Boolean {
panAndZoom.scaleFactor *= detector.scaleFactor
panAndZoom.focusX = detector.focusX
panAndZoom.focusY = detector.focusY
invalidate()
return true
}
}
private val gestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
override fun onScroll(e1: MotionEvent?, e2: MotionEvent?, distanceX: Float, distanceY: Float): Boolean {
panAndZoom.panX -= distanceX
panAndZoom.panY -= distanceY
invalidate()
return true
}
}
我在自定义视图中重写了两种方法,一种是将触摸事件传递给手势检测器,另一种是绘制子视图:
override fun onTouchEvent(e: MotionEvent): Boolean {
gestureDetector.onTouchEvent(e)
scaleGestureDetector.onTouchEvent(e)
return super.onTouchEvent(e)
}
override fun drawChild(canvas: Canvas, child: View, drawingTime: Long): Boolean {
val save = canvas.save()
canvas.scale(panAndZoom.scaleFactor, panAndZoom.scaleFactor, panAndZoom.focusX, panAndZoom.focusY)
canvas.translate(panAndZoom.panX, panAndZoom.panY)
val result = super.drawChild(canvas, child, drawingTime)
canvas.restoreToCount(save)
return result
}
但是,这没有得到预期的结果,即:
findFirstVisibleItem()
将返回第二个页面实际上不可见时。