CameraX: Как добавить щепотку для увеличения и коснуться для фокусировки? onClickListener и onTouchListener - PullRequest
0 голосов
/ 01 августа 2020

Я объединил несколько руководств по CameraX, чтобы у них было щипок для увеличения и касание для фокусировки. Сами по себе они работают хорошо, но вместе, OnClickListener и OnTouchListener мешают друг другу.

Я подумал объединить их в рамках одного метода OnClickListener, где масштабирование выполняется на ACTION_DOWN, а нажатие на сфокусироваться на ACTION_UP, но работает только касание для фокусировки. Даже если бы это сработало, это выглядит немного неуклюже, и я был бы признателен за более подробное руководство.

zoomAndFocus запускается: "viewFinder.setOnClickListener {zoomAndFocus ()}" в onCreate.

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.
        }

    }

1 Ответ

0 голосов
/ 01 августа 2020

Используйте это, чтобы добавить щепотку для увеличения и коснитесь для одновременной фокусировки:

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
    }
}
...