如何在整个RecyclerView上实现平移和缩放

时间:2019-05-22 04:49:38

标签: android android-recyclerview android-canvas

我有自己的自定义视图,该视图扩展了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
}

但是,这没有得到预期的结果,即:

  • 我能够完全超出RV范围(我意识到我并没有限制我的平移值,但是我该怎么做)?
  • 放大时,Pan似乎运行得非常快(我如何缩放平移值,以便它们遵守比例因子)?
  • 如果我在文档的第2页上,然后进行放大,然后平移到第3页,则布局管理器不会意识到该视图实际上已滚动(这意味着调用findFirstVisibleItem()将返回第二个页面实际上不可见时。
  • 最可能与以上几点有关:我可以平移页面,并且因为布局管理器没有意识到现在正在显示另一个视图,所以它无法呈现(因为它仍然认为该视图已从视图中隐藏了)因此它通过不呈现来进行优化)。

0 个答案:

没有答案