How can I use a CameraView with Jetpack Compose?

前端 未结 1 1901
一整个雨季
一整个雨季 2021-02-15 20:33

Currently there\'s no equivalent to CameraView (and PreviewView) in Compose. Is it possible to wrap it and display it in a compose layout?

相关标签:
1条回答
  • 2021-02-15 21:12

    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

    • @param resId The id of the layout resource to be inflated.
    • @param 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()
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题