CameraX:如何添加捏合缩放和点击对焦? onClickListener 和 onTouchListener

CameraX: How to add pinch to zoom AND tap to focus? onClickListener and onTouchListener

我合并了一些 CameraX 教程,使其具有捏合缩放和轻点对焦功能。 单独使用时,它们运行良好,但 OnClickListener 和 OnTouchListener 一起使用时会相互干扰。

我想在单个 OnClickListener 方法下合并它们,其中在 ACTION_DOWN 上执行缩放缩放,在 ACTION_UP 上执行点击聚焦,但只有点击聚焦是 运行。即使它确实有效,也感觉有点笨拙,我希望能得到更高级的指导。

zoomAndFocus 由 onCreate 中的“viewFinder.setOnClickListener{zoomAndFocus()}”触发。

private fun zoomAndFocus(){
    Log.d("onclick","detecting clck?")

    viewFinder.setOnTouchListener { _, event ->

        return@setOnTouchListener when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                val listener = object : ScaleGestureDetector.SimpleOnScaleGestureListener() {
                    override fun onScale(detector: ScaleGestureDetector): Boolean {
                        val zoomRatio = camera?.cameraInfo?.zoomState?.value?.zoomRatio ?: 0f
                        val scale = zoomRatio * detector.scaleFactor
                        camera!!.cameraControl.setZoomRatio(scale)
                        return true
                    }
                }

                val scaleGestureDetector = ScaleGestureDetector(this, listener)

                scaleGestureDetector.onTouchEvent(event)


                true
            }
            MotionEvent.ACTION_UP -> {
                val factory: MeteringPointFactory = SurfaceOrientedMeteringPointFactory(
                    viewFinder.width.toFloat(), viewFinder.height.toFloat()
                )
                val autoFocusPoint = factory.createPoint(event.x, event.y)
                try {
                    camera?.cameraControl?.startFocusAndMetering(
                        FocusMeteringAction.Builder(
                            autoFocusPoint,
                            FocusMeteringAction.FLAG_AF
                        ).apply {
                            //focus only when the user tap the preview
                            disableAutoCancel()
                        }.build()
                    )
                } catch (e: CameraInfoUnavailableException) {
                    Log.d("ERROR", "cannot access camera", e)
                }
                viewFinder.performClick()
                true
            }
            else -> false // Unhandled event.
        }

    }

使用它来添加双指缩放和点击对焦:

private fun setupZoomAndTapToFocus() {
    val listener = object : ScaleGestureDetector.SimpleOnScaleGestureListener() {
        override fun onScale(detector: ScaleGestureDetector): Boolean {
            val currentZoomRatio: Float = cameraInfo.zoomState.value?.zoomRatio ?: 1F
            val delta = detector.scaleFactor
            cameraControl.setZoomRatio(currentZoomRatio * delta)
            return true
        }
    }

    val scaleGestureDetector = ScaleGestureDetector(viewFinder.context, listener)

    viewFinder.setOnTouchListener { _, event ->
        scaleGestureDetector.onTouchEvent(event)
        if (event.action == MotionEvent.ACTION_DOWN) {
            val factory = viewFinder.createMeteringPointFactory(cameraSelector)
            val point = factory.createPoint(event.x, event.y)
            val action = FocusMeteringAction.Builder(point, FocusMeteringAction.FLAG_AF)
                .setAutoCancelDuration(5, TimeUnit.SECONDS)
                .build()
            cameraControl.startFocusAndMetering(action)
        }
        true
    }
}