Android 如何在jetpack compose中使用预览视图?
我试图通过Android 如何在jetpack compose中使用预览视图?,android,android-jetpack-compose,android-camerax,Android,Android Jetpack Compose,Android Camerax,我试图通过AndroidView在Composable内部使用CameraXPreviewView,但是预览被拉伸,右半部分被剪裁,正如您在图中看到的那样。 然而,视图似乎占据了正确的空间。 此问题仅在纵向模式下发生。 我能够在两部手机和模拟器上重现这个问题,所以我怀疑它是硬件特定的 我尝试了不同的比例类型,但这似乎并不影响拉伸。 我会报告一个bug,但我不确定这是compose还是cameraX中的bug 请参阅下面我使用的代码: package com.example.cameraprevi
AndroidView
在Composable
内部使用CameraXPreviewView
,但是预览被拉伸,右半部分被剪裁,正如您在图中看到的那样。
然而,视图似乎占据了正确的空间。
此问题仅在纵向模式下发生。
我能够在两部手机和模拟器上重现这个问题,所以我怀疑它是硬件特定的
我尝试了不同的比例类型,但这似乎并不影响拉伸。
我会报告一个bug,但我不确定这是compose还是cameraX中的bug
请参阅下面我使用的代码:
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))
}
}
}
)
}
package com.example.camerapreview
导入android.Manifest
导入android.graphics.Color
导入android.os.Bundle
导入android.view.ViewGroup.LayoutParams.MATCH_父项
导入android.widget.LinearLayout
导入androidx.activity.ComponentActivity
导入androidx.activity.compose.registerForActivityResult
导入androidx.activity.compose.setContent
导入androidx.activity.result.contract.ActivityResultContracts
导入androidx.camera.core.AspectRatio.RATIO_16_9
导入androidx.camera.core.CameraSelector
导入androidx.camera.lifecycle.ProcessCameraProvider
导入androidx.camera.view.PreviewView
导入androidx.compose.material.Button
导入androidx.compose.material.MaterialTheme
导入androidx.compose.material.Surface
导入androidx.compose.material.Text
导入androidx.compose.runtime*
导入androidx.compose.ui.platform.LocalLifecycleOwner
导入androidx.compose.ui.viewinterop.AndroidView
导入androidx.core.content.ContextCompat
导入androidx.lifecycle.LifecycleOwner
导入com.example.pointergun.ui.theme.PointerGunTheme
导入com.google.common.util.concurrent.ListenableFuture
导入androidx.camera.core.Preview
类MainActivity:ComponentActivity(){
重写创建时的乐趣(savedInstanceState:Bundle?){
super.onCreate(savedInstanceState)
val cameraProviderFuture=ProcessCameraProvider.getInstance(此)
设置内容{
指针式{
表面(颜色=材料颜色.背景){
var IsPermission由remember授予{
可变状态(null)
}
val发射器=
registerForActivityResult(contract=ActivityResultContracts.RequestPermission()){IsGranded->
ispermissiongrated=ispermisted
}
何时(iPermission已授予){
true->CameraPreview(CamerapProviderFuture)
错误->文本(“权限pls”)
null->按钮(onClick={launcher.launch(Manifest.permission.CAMERA)}){
Text(Text=“开始!”)
}
}
}
}
}
}
}
趣味活页夹预览(
cameraProvider:ProcessCameraProvider,
lifecycleOwner:lifecycleOwner,
预览视图:预览视图,
) {
val preview:preview=preview.Builder()
.SetTargetSpectratio(比率为16×9)
.build()
val cameraSelector:cameraSelector=cameraSelector.Builder()
.RequiremensFacing(摄像机选择器镜头面向后)
.build()
preview.setSurfaceProvider(previewView.surfaceProvider)
var camera=cameraProvider.bindToLifecycle(生命周期所有者、摄影机选择器、预览)
}
@组合的
有趣的CameraPreview(CamerapProviderFuture:ListenableFuture){
val lifecycleOwner=LocalLifecycleOwner.current
AndroidView(
工厂={context->
预览视图(上下文)。应用{
setBackgroundColor(颜色:绿色)
layoutParams=LinearLayout.layoutParams(匹配父项,匹配父项)
scaleType=PreviewView.scaleType.FILL\u开始
职位{
cameraProviderFuture.addListener(可运行{
val cameraProvider=cameraProviderFuture.get()
装订预览(
摄影师,
生命周期所有者,
这
)
},ContextCompat.getMainExecutor(上下文))
}
}
}
)
}
请仅包括必要的代码。