制作一个扩展ConstraintLayout的自定义pannable和可缩放的ViewGroup

我试图合并一个自定义布局(即一个ViewGroup),它扩展了ConstraintLayout(这样我就可以添加具有位置约束的子视图),用户应该能够平移和放大。 我尝试了很多方法来达到这个目的。 包含:

  • 尝试调整Google的示例以便在此平移/缩放视图。

  • 根据触摸事件移动画布(如下是我的onTouchEvent类)。

     override fun onTouchEvent(event: MotionEvent): Boolean { // These two are the coordinates of the user's finger whenever onTouchEvent is called val x: Float = event.x val y: Float = event.y when(event.action and ACTION_MASK) { ACTION_DOWN -> { // Might not be necessary; check out later dragging = true // We want to store the coords of the user's finger as it is before they move // in order to calculate dx and dy initX = x initY = y } ACTION_MOVE -> { // Self explanatory; the difference in x- and y-coords between successive calls to // onTouchEvent val dx: Float = x - initX val dy: Float = y - initY if (dragging) { // Move the canvas dx units right and dy units down // dx and dy are divided by scaleFactor so that panning speeds are consistent // with the zoom level canvasX += dx/scaleFactor canvasY += dy/scaleFactor invalidate() // Re-draw the canvas // Change initX and initY to the new x- and y-coords initX = x initY = y } } ACTION_POINTER_UP -> { // This sets initX and initY to the position of the pointer finger so that the // screen doesn't jump when it's lifted with the main finger still down initX = x initY = y } ACTION_UP -> dragging = false // Again, may be unnecessary } detector.onTouchEvent(event) // Listen for scale gestures (ie pinching or double tap+drag // Just some useful coordinate data Log.d("TOUCHEVENT", "x: $x, y: $y,\ninitY: $initX, initY,\n" + "canvasX: $canvasX, canvasY: $canvasY,\nwidth: $dispWidth, height: $dispHeight\n" + "focusX: ${detector.focusX}, focusY: ${detector.focusY}") // Data pertaining to fingers for responsiveness and stuff Log.d("TOUCHEVENT", "Action: ${event.action and MotionEvent.ACTION_MASK}\n") return true } 

我已经取得了这样一个常规视图的效果(第二个链接中的代码只是我为视图编写的代码的稍微修改版本),但是我需要一个ViewGroup来达到我的目的。 我已经搜索了一个库来完成这个任务,但是即使进行了大量的修改,我也找不到任何适合我的用例的东西,另外,我宁愿尝试自己做,所以我不必依赖库一切。 我已经通过了许多关于类似问题的StackOverflow文章,但是我再一次无法让代码在我的最后工作。

我认为只是使用某种2D图形或游戏开发库来实现这样的布局,但我觉得这样会增加不必要的膨胀到我的应用程序。

注意:我正在使用Kotlin(正如你可以在上面的代码中看到的那样),但是即使有人可以用Java来帮助我,我总是可以自己转换它。