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
}
}
我合并了一些 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
}
}