This blog post written by a Google engineer explains exactly how to do it (in Kotlin).
This is how to achieve the same in Java:
private void setUpTapToFocus() {
textureView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() != MotionEvent.ACTION_UP) {
/* Original post returns false here, but in my experience this makes
onTouch not being triggered for ACTION_UP event */
return true;
}
TextureViewMeteringPointFactory factory = new TextureViewMeteringPointFactory(textureView);
MeteringPoint point = factory.createPoint(event.getX(), event.getY());
FocusMeteringAction action = FocusMeteringAction.Builder.from(point).build();
cameraControl.startFocusAndMetering(action);
return true;
}
});
}
The cameraControl
object can be instantiated like this:
CameraControl cameraControl = CameraX.getCameraControl(CameraX.LensFacing.BACK);
but make sure you have
implementation "androidx.camera:camera-view:1.0.0-alpha03"
within your build.gradle
dependencies.
For reference, here's the original Kotlin code from Husayn Hakeem blog post:
private fun setUpTapToFocus() {
textureView.setOnTouchListener { _, event ->
if (event.action != MotionEvent.ACTION_UP) {
return@setOnTouchListener false
}
val factory = TextureViewMeteringPointFactory(textureView)
val point = factory.createPoint(event.x, event.y)
val action = FocusMeteringAction.Builder.from(point).build()
cameraControl.startFocusAndMetering(action)
return@setOnTouchListener true
}
}