Android Composable - PreviewView 上的宽度/高度不正确

问题描述

目前正在使用 Composable 为 CameraX 构建 PreviewView。但是,正如您在图像中看到的,实际视图没有正确渲染,需要多次切换相机才能正确渲染。为什么是这样?我附上了我的源代码以供参考。

Incorrect width and height

class CameraPreview {
private var cameraProvider: ProcessCameraProvider? = null
private var lensFacing: Int = CameraSelector.LENS_FACING_BACK
private var camera: Camera? = null
private lateinit var displayManager: displayManager
private var preview: Preview? = null


@RequiresApi(Build.VERSION_CODES.R)
@Composable
fun displayCamera() {
    val context = LocalContext.current
    val lifecycleOwner = LocalLifecycleOwner.current
    val cameraProviderFuture = remember { ProcessCameraProvider.getInstance(context) }
    displayManager = context.getSystemService(Context.disPLAY_SERVICE) as displayManager
    lateinit var previewView: PreviewView
    var executor: Executor
    Scaffold(topBar = { },floatingActionButton = {
            FloatingActionButton(
                onClick = {
                    lensFacing = if (CameraSelector.LENS_FACING_FRONT == lensFacing) {
                        CameraSelector.LENS_FACING_BACK
                    } else {
                        CameraSelector.LENS_FACING_FRONT
                    }
                    bindCameraUseCases(previewView,lifecycleOwner,context)
                },modifier = Modifier.padding(20.dp)
            ) {
                Icon(Icons.Default.SwitchCamera,"")
            }
        },content = {
            AndroidView(modifier = Modifier.fillMaxSize(),factory = { _context ->
                previewView = PreviewView(_context)
                executor = ContextCompat.getMainExecutor(_context)
                cameraProviderFuture.addListener({
                    cameraProvider = cameraProviderFuture.get()
                    lensFacing = when {
                        hasBackCamera() -> CameraSelector.LENS_FACING_BACK
                        hasFrontCamera() -> CameraSelector.LENS_FACING_FRONT
                        else -> throw IllegalStateException("Back and front camera are unavailable")
                    }

                    bindCameraUseCases(previewView,context)

                },ContextCompat.getMainExecutor(context))
                previewView
            })
        }
    )
}

@RequiresApi(Build.VERSION_CODES.R)
private fun bindCameraUseCases(previewView: PreviewView,lifecycleOwner: LifecycleOwner,context: Context) {

    val metrics: displayMetrics = context.getResources().getdisplayMetrics()
    val screenAspectRatio = aspectRatio(metrics.widthPixels,metrics.heightPixels)
    val rotation = displayManager.displays[0].rotation
    val cameraProvider = cameraProvider
        ?: throw IllegalStateException("Camera initialization Failed.")
    val cameraSelector = CameraSelector.Builder().requireLensFacing(lensFacing).build()
    preview = Preview.Builder()
        .setTargetAspectRatio(screenAspectRatio)
        .setTargetRotation(rotation)
        .build()
    cameraProvider.unbindAll()
    try {
        camera = cameraProvider.bindToLifecycle(
            lifecycleOwner,cameraSelector,preview)
        preview?.setSurfaceProvider(previewView.surfaceProvider)
    } catch (exc: Exception) {
        Log.e("PEOPLE DETECTOR","Use case binding Failed",exc)
    }
}

private fun aspectRatio(width: Int,height: Int): Int {
    val previewRatio = max(width,height).todouble() / min(width,height)
    if (abs(previewRatio - RATIO_4_3_VALUE) <= abs(previewRatio - RATIO_16_9_VALUE)) {
        return AspectRatio.RATIO_4_3
    }
    return AspectRatio.RATIO_16_9
}

private fun hasBackCamera(): Boolean {
    return cameraProvider?.hasCamera(CameraSelector.DEFAULT_BACK_CAMERA) ?: false
}

private fun hasFrontCamera(): Boolean {
    return cameraProvider?.hasCamera(CameraSelector.DEFAULT_FRONT_CAMERA) ?: false
}

companion object {
    private const val RATIO_4_3_VALUE = 4.0 / 3.0
    private const val RATIO_16_9_VALUE = 16.0 / 9.0
}

}

您是否看到任何可能导致问题的原因?这让我难以置信。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)