CameraXViewfinder

Functions summary

Unit
@Composable
CameraXViewfinder(
    surfaceRequest: SurfaceRequest,
    modifier: Modifier,
    implementationMode: ImplementationMode,
    coordinateTransformer: MutableCoordinateTransformer?,
    alignment: Alignment,
    contentScale: ContentScale,
    onStreamStateChanged: (Int) -> Unit,
    isTapToFocusEnabled: Boolean,
    onTapToFocus: (Offset, Int) -> Unit,
    autoCancelDurationMillis: Long,
    isPinchToZoomEnabled: Boolean,
    onZoomRatioChanged: (Float) -> Unit,
    onScreenFlashReady: (ImageCapture.ScreenFlash) -> Unit,
    onRelease: () -> Unit
)

An adapter composable that displays frames from CameraX by completing provided SurfaceRequests.

Functions

CameraXViewfinder

@Composable
fun CameraXViewfinder(
    surfaceRequest: SurfaceRequest,
    modifier: Modifier = Modifier,
    implementationMode: ImplementationMode = CameraImplementationModeCompat.chooseCompatibleMode(surfaceRequest.camera.cameraInfo),
    coordinateTransformer: MutableCoordinateTransformer? = null,
    alignment: Alignment = Alignment.Center,
    contentScale: ContentScale = ContentScale.Crop,
    onStreamStateChanged: (Int) -> Unit = {},
    isTapToFocusEnabled: Boolean = false,
    onTapToFocus: (Offset, Int) -> Unit = { _, _ -> },
    autoCancelDurationMillis: Long = 5000,
    isPinchToZoomEnabled: Boolean = false,
    onZoomRatioChanged: (Float) -> Unit = {},
    onScreenFlashReady: (ImageCapture.ScreenFlash) -> Unit = {},
    onRelease: () -> Unit = {}
): Unit

An adapter composable that displays frames from CameraX by completing provided SurfaceRequests.

This is a wrapper around Viewfinder that will convert a CameraX SurfaceRequest internally into a ViewfinderSurfaceRequest. Additionally, all interactions normally handled through the ViewfinderSurfaceRequest will be derived from the SurfaceRequest.

If implementationMode is changed while the provided surfaceRequest has been fulfilled, the surface request will be invalidated as if SurfaceRequest.invalidate has been called. This will allow CameraX to know that a new surface request is required since the underlying viewfinder implementation will be providing a new surface.

This specific overload provides full control over advanced viewfinder features such as pinch-to-zoom, tap-to-focus gestures, and screen flash.

Example usage:

import androidx.camera.compose.CameraXViewfinder
import androidx.camera.core.Preview
import androidx.camera.core.SurfaceRequest
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.lifecycle.ViewModel

class PreviewViewModel : ViewModel() {
    private val _surfaceRequests = MutableStateFlow<SurfaceRequest?>(null)

    val surfaceRequests: StateFlow<SurfaceRequest?>
        get() = _surfaceRequests.asStateFlow()

    // Connects a CameraX Preview use case to this ViewModel to publish SurfaceRequests
    fun bindPreview(preview: Preview) {
        preview.setSurfaceProvider { newRequest -> _surfaceRequests.value = newRequest }
    }
}

@Composable
fun MyCameraViewfinder(viewModel: PreviewViewModel, modifier: Modifier = Modifier) {
    val currentSurfaceRequest: SurfaceRequest? by viewModel.surfaceRequests.collectAsState()

    Box(modifier = modifier) {
        currentSurfaceRequest?.let { surfaceRequest ->
            CameraXViewfinder(
                surfaceRequest = surfaceRequest,
                modifier = Modifier.fillMaxSize(),
                isTapToFocusEnabled = true,
                isPinchToZoomEnabled = true,
                onTapToFocus = { offset, state ->
                    // Respond to tap-to-focus (e.g. update focus UI indicator state)
                },
                onZoomRatioChanged = { ratio ->
                    // Respond to zoom ratio changes (e.g. update zoom UI indicator)
                },
                onScreenFlashReady = { screenFlash ->
                    // Coordinate screen flash callbacks with camera capture lifecycle
                },
                onRelease = {
                    // Clear references to screen flash to prevent leaks
                },
            )
        }

        // Draw a focus indicator when a focus point is active.
    }
}

val viewModel = remember { PreviewViewModel() }
MyCameraViewfinder(viewModel = viewModel)
Parameters
surfaceRequest: SurfaceRequest

The surface request from CameraX

modifier: Modifier = Modifier

The Modifier to be applied to this viewfinder

implementationMode: ImplementationMode = CameraImplementationModeCompat.chooseCompatibleMode(surfaceRequest.camera.cameraInfo)

The ImplementationMode to be used by this viewfinder. By default, this is chosen automatically based on the device's capabilities. The default behavior prefers the higher-performance ImplementationMode.EXTERNAL mode, but will fall back to ImplementationMode.EMBEDDED if the camera hardware level is LEGACY, or on devices with other known compatibility issues (such as on API level 24 and below). Explicitly setting a mode will override this compatibility logic and may have performance or correctness implications on some devices.

coordinateTransformer: MutableCoordinateTransformer? = null

The MutableCoordinateTransformer used to map offsets of this viewfinder to the source coordinates of the data being provided to the surface that fulfills surfaceRequest

alignment: Alignment = Alignment.Center

Optional alignment parameter used to place the camera feed in the given bounds of the CameraXViewfinder. Defaults to Alignment.Center.

contentScale: ContentScale = ContentScale.Crop

Optional scale parameter used to determine the aspect ratio scaling to be used to fit the camera feed in the bounds of the CameraXViewfinder. Defaults to ContentScale.Crop.

onStreamStateChanged: (Int) -> Unit = {}

Callback invoked when the preview stream state changes. Provides the current Preview.StreamState.

isTapToFocusEnabled: Boolean = false

Whether the tap-to-focus gesture is enabled.

onTapToFocus: (Offset, Int) -> Unit = { _, _ -> }

A callback invoked when a tap-to-focus action is triggered. It provides the tap Offset and an integer representing the current focus state. See FocusState for possible values.

autoCancelDurationMillis: Long = 5000

The auto-cancel duration of focus/metering in milliseconds. Defaults to 5000L.

isPinchToZoomEnabled: Boolean = false

Whether the pinch-to-zoom gesture is enabled.

onZoomRatioChanged: (Float) -> Unit = {}

A callback invoked when the CameraXViewfinder's pinch-to-zoom gesture scales the zoom ratio, providing the updated zoom ratio. This callback is only invoked during the active zooming state.

onScreenFlashReady: (ImageCapture.ScreenFlash) -> Unit = {}

A callback invoked when the screen flash feature is ready to apply, providing the ImageCapture.ScreenFlash implementation to be used with ImageCapture.

onRelease: () -> Unit = {}

A callback invoked when the CameraXViewfinder is permanently removed from the composition, indicating that any references to resources (like ImageCapture.ScreenFlash) should be cleared.