Currently there\'s no equivalent to CameraView (and PreviewView) in Compose. Is it possible to wrap it and display it in a compose layout?
At the moment there isn't any official Comosable function for Camerax so we have to inflate the legacy android view inside compose.
To achieve that
we can use AndroidView
composable function,
it accepts two parameters
resId
The id of the layout resource to be inflated.postInflationCallback
The callback to be invoked after the layout
is inflated.and to access the lifecycle and context we use the ambients
val lifecycleOwner = LifecycleOwnerAmbient.current
val context = ContextAmbient.current
As we have everything we need let's do it:
Create a layout camera_host.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.camera.view.PreviewView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/previewView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
and inflate it using AndroidView
Composable function.
@Composable
fun SimpleCameraPreview() {
val lifecycleOwner = LifecycleOwnerAmbient.current
val context = ContextAmbient.current
val cameraProviderFuture = remember { ProcessCameraProvider.getInstance(context) }
AndroidView(resId = R.layout.camera_host) { inflatedLayout ->
//You can call
// findViewById<>() and etc ... on inflatedLayout
// here PreviewView is the root of my layout so I just cast it to
// the PreviewView and no findViewById is required
cameraProviderFuture.addListener(Runnable {
val cameraProvider = cameraProviderFuture.get()
bindPreview(
lifecycleOwner,
inflatedLayout as PreviewView /*the inflated layout*/,
cameraProvider)
}, ContextCompat.getMainExecutor(context))
}
}
fun bindPreview(
lifecycleOwner: LifecycleOwner,
previewView: PreviewView,
cameraProvider: ProcessCameraProvider
) {
var preview: Preview = Preview.Builder().build()
var cameraSelector: CameraSelector = CameraSelector.Builder()
.requireLensFacing(CameraSelector.LENS_FACING_BACK)
.build()
preview.setSurfaceProvider(previewView.createSurfaceProvider())
var camera = cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, preview)
}
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
SimpleCameraPreview()
}
}
}