【问题标题】:How can I use a PreviewView inside jetpack compose?如何在 jetpack compose 中使用 PreviewView?
【发布时间】:2021-03-21 12:57:38
【问题描述】:

我试图通过AndroidViewComposable 内使用CameraX PreviewView,但预览被拉伸并且右半部分被剪裁,正如您在screenshot 中看到的那样。 然而,视图似乎占据了正确的空间。 此问题仅在纵向模式下发生。 我能够在两部手机和模拟器中重现该问题,所以我怀疑它是特定于硬件的。

我尝试了不同的比例类型,但这似乎不会影响拉伸。 我会报告一个错误,但我不确定这是 compose 还是 cameraX 中的错误。

请看下面我使用的代码:

package com.example.camerapreview

import android.Manifest
import android.graphics.Color
import android.os.Bundle
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.widget.LinearLayout
import androidx.activity.ComponentActivity
import androidx.activity.compose.registerForActivityResult
import androidx.activity.compose.setContent
import androidx.activity.result.contract.ActivityResultContracts
import androidx.camera.core.AspectRatio.RATIO_16_9
import androidx.camera.core.CameraSelector
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.view.PreviewView
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.content.ContextCompat
import androidx.lifecycle.LifecycleOwner
import com.example.pointergun.ui.theme.PointerGunTheme
import com.google.common.util.concurrent.ListenableFuture
import androidx.camera.core.Preview

class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val cameraProviderFuture = ProcessCameraProvider.getInstance(this)

        setContent {
            PointerGunTheme {
                Surface(color = MaterialTheme.colors.background) {
                    var isPermissionGranted by remember {
                        mutableStateOf<Boolean?>(null)
                    }
                    val launcher =
                        registerForActivityResult(contract = ActivityResultContracts.RequestPermission()) { isGranted ->
                            isPermissionGranted = isGranted
                        }
                    when (isPermissionGranted) {
                        true -> CameraPreview(cameraProviderFuture)
                        false -> Text("permission pls")
                        null -> Button(onClick = { launcher.launch(Manifest.permission.CAMERA) }) {
                            Text(text = "Start!")
                        }
                    }
                }
            }
        }
    }
}

fun bindPreview(
    cameraProvider: ProcessCameraProvider,
    lifecycleOwner: LifecycleOwner,
    previewView: PreviewView,
) {
    val preview: Preview = Preview.Builder()
        .setTargetAspectRatio(RATIO_16_9)
        .build()

    val cameraSelector: CameraSelector = CameraSelector.Builder()
        .requireLensFacing(CameraSelector.LENS_FACING_BACK)
        .build()

    preview.setSurfaceProvider(previewView.surfaceProvider)

    var camera = cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, preview)
}

@Composable
fun CameraPreview(cameraProviderFuture: ListenableFuture<ProcessCameraProvider>) {

    val lifecycleOwner = LocalLifecycleOwner.current
    AndroidView(
        factory = { context ->
            PreviewView(context).apply {
                setBackgroundColor(Color.GREEN)
                layoutParams = LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
                scaleType = PreviewView.ScaleType.FILL_START
                post {
                    cameraProviderFuture.addListener(Runnable {
                        val cameraProvider = cameraProviderFuture.get()
                        bindPreview(
                            cameraProvider,
                            lifecycleOwner,
                            this,
                        )
                    }, ContextCompat.getMainExecutor(context))
                }
            }
        }
    )
}

【问题讨论】:

    标签: android android-jetpack-compose android-camerax


    【解决方案1】:

    预览视图需要设置implementation mode

    implementationMode = PreviewView.ImplementationMode.COMPATIBLE
    

    在你的情况下:

    PreviewView(context).apply {
        setBackgroundColor(Color.GREEN)
        layoutParams = LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
        scaleType = PreviewView.ScaleType.FILL_START
        implementationMode = PreviewView.ImplementationMode.COMPATIBLE
        post {
            cameraProviderFuture.addListener(Runnable {
                val cameraProvider = cameraProviderFuture.get()
                bindPreview(
                    cameraProvider,
                    lifecycleOwner,
                    this,
                )
            }, ContextCompat.getMainExecutor(context))
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-02-15
      • 2022-12-09
      • 2021-07-14
      • 2020-04-23
      • 1970-01-01
      • 2022-08-18
      • 1970-01-01
      相关资源
      最近更新 更多