作者 / Google 開發者關系工程師 Jolanda Verhoef
本文是 "相機與媒體 Spotlight Week" 系列的內容之一。此系列中,我們會提供文章、視頻、示例代碼等資源,以幫助您提升應用中的媒體體驗。
我們了解到您喜歡 CameraX 和 Jetpack Compose 庫提供的強大功能,但希望使用更符合語言習慣的 Compose API 來構建相機界面。今年,我們的工程團隊開發了兩個新的 Compose 工件,即低層級 viewfinder-compose 和高層級 camera-compose。兩者現在均已推出 alpha 版本 。
在本系列文章中,我們不僅將為您介紹如何將 camera-compose API 集成到應用中,還將向您展示與 Compose 集成所帶來的一些令人愉悅的界面體驗。所有令人贊嘆的 Compose 功能 (例如自適應 API 和動畫支持) 均已與相機預覽無縫集成。
完成所有這些操作后,我們的最終應用將如下所示:
此外,應用可以順暢地在桌面模式之間切換:
到本文 (該系列第一篇文章) 的末尾,您將構建一個功能齊全的相機取景器,并將在后續系列文章中對其進行擴展。歡迎您跟隨我們一起編寫代碼,在實踐中更好地學習。
添加庫依賴項
假設您已經在應用中設置了 Compose。如果您想繼續,只需在 Android Studio 中新建一個應用即可。我們通常使用最新的 Canary 版本,因為這個版本會提供最新的 Compose 模板。
向您的 libs.versions.toml 中添加以下內容:
[versions] .. camerax = "1.5.0-alpha03" accompanist = "0.36.0" # or whatever matches with your Compose version [libraries] .. # Contains the basic camera functionality such as SurfaceRequest androidx-camera-core = { module = "androidx.camera:camera-core", version.ref = "camerax" } # Contains the CameraXViewfinder composable androidx-camera-compose = { module = "androidx.camera:camera-compose", version.ref = "camerax" } # Allows us to bind the camera preview to our UI lifecycle androidx-camera-lifecycle = { group = "androidx.camera", name = "camera-lifecycle", version.ref = "camerax" } # The specific camera implementation that renders the preview androidx-camera-camera2 = { module = "androidx.camera:camera-camera2", version.ref = "camerax" } # The helper library to grant the camera permission accompanist-permissions = { module = "com.google.accompanist:accompanist-permissions", version.ref = "accompanist" }然后,將這些添加到您的模塊 build.gradle.kts 依賴項塊中:
dependencies { .. implementation(libs.androidx.camera.core) implementation(libs.androidx.camera.compose) implementation(libs.androidx.camera.lifecycle) implementation(libs.androidx.camera.camera2) implementation(libs.accompanist.permissions) }?
為了授予相機權限,我們添加了所有依賴項,然后實際顯示相機預覽。接下來,讓我們看看如何授予正確的權限。
授予相機權限
通過使用 Accompanist 權限庫,我們可以輕松地授予正確的相機權限。首先,我們需要設置 AndroidManifest.xml:
..
Accompanist 權限庫
https://google.github.io/accompanist/permissions/
現在,我們只需按照庫的說明授予正確的權限:
class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { MyApplicationTheme { CameraPreviewScreen() } } } } @OptIn(ExperimentalPermissionsApi::class) @Composable fun CameraPreviewScreen(modifier: Modifier = Modifier) { val cameraPermissionState = rememberPermissionState(android.Manifest.permission.CAMERA) if (cameraPermissionState.status.isGranted) { CameraPreviewContent(modifier) } else { Column( modifier = modifier.fillMaxSize().wrapContentSize().widthIn(max = 480.dp), horizontalAlignment = Alignment.CenterHorizontally ) { val textToShow = if (cameraPermissionState.status.shouldShowRationale) { // If the user has denied the permission but the rationale can be shown, // then gently explain why the app requires this permission "Whoops! Looks like we need your camera to work our magic!" + "Don't worry, we just wanna see your pretty face (and maybe some cats). " + "Grant us permission and let's get this party started!" } else { // If it's the first time the user lands on this feature, or the user // doesn't want to be asked again for this permission, explain that the // permission is required "Hi there! We need your camera to work our magic! " + "Grant us permission and let's get this party started! uD83CuDF89" } Text(textToShow, textAlign = TextAlign.Center) Spacer(Modifier.height(16.dp)) Button(onClick = { cameraPermissionState.launchPermissionRequest() }) { Text("Unleash the Camera!") } } } } @Composable private fun CameraPreviewContent(modifier: Modifier = Modifier) { // TODO: Implement }這樣,我們就得到了一個良好的界面,用戶可以在顯示相機預覽之前授予相機權限:
創建 ViewModel
將業務邏輯與界面分開是一種很好的實踐。為此,我們可以為屏幕創建視圖模型來實現這一點。這個視圖模型設置了 CameraX Preview 用例。請注意,CameraX 中的用例代表了可以使用該庫實現的各種工作流程的配置,即預覽、捕獲、錄制和分析。視圖模型還將界面綁定到相機提供程序:
class CameraPreviewViewModel : ViewModel() { // Used to set up a link between the Camera and your UI. private val _surfaceRequest = MutableStateFlow(null) val surfaceRequest: StateFlow = _surfaceRequest private val cameraPreviewUseCase = Preview.Builder().build().apply { setSurfaceProvider { newSurfaceRequest -> _surfaceRequest.update { newSurfaceRequest } } } suspend fun bindToCamera(appContext: Context, lifecycleOwner: LifecycleOwner) { val processCameraProvider = ProcessCameraProvider.awaitInstance(appContext) processCameraProvider.bindToLifecycle( lifecycleOwner, DEFAULT_FRONT_CAMERA, cameraPreviewUseCase ) // Cancellation signals we're done with the camera try { awaitCancellation() } finally { processCameraProvider.unbindAll() } } }
此處會執行大量操作。代碼定義了一個 CameraPreviewViewModel 類,負責管理相機預覽。此類使用 CameraX Preview 構建器來配置預覽與界面的綁定方式。bindToCamera 函數用于初始化相機,并將其綁定到指定的 LifecycleOwner,以確保相機至少在生命周期處于 "啟動" 狀態時運行,并啟動預覽流。
相機作為相機庫的內部組件,需要渲染到界面提供的 surface。因此,庫需要有一種方法來請求 surface。這正是 SurfaceRequest 的用途。因此,每當相機表示需要 surface 時,就會觸發 surfaceRequest。然后將該請求轉發給界面,以便將 surface 傳遞給請求對象。
最后,我們需要等待界面與相機完成綁定,并確保釋放相機資源以避免資源泄漏。
實現相機預覽界面
現在我們有了一個視圖模型,可以實現 CameraPreviewContent 可組合項。該項從視圖模型中讀取 surface 請求,在可組合項位于組合樹中時綁定到相機,并從庫中調用 CameraXViewfinder。
@Composable fun CameraPreviewContent( viewModel: CameraPreviewViewModel, modifier: Modifier = Modifier, lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current ) { val surfaceRequest by viewModel.surfaceRequest.collectAsStateWithLifecycle() val context = LocalContext.current LaunchedEffect(lifecycleOwner) { viewModel.bindToCamera(context.applicationContext, lifecycleOwner) } surfaceRequest?.let { request -> CameraXViewfinder( surfaceRequest = request, modifier = modifier ) } }
如上部分所述,surfaceRequest 允許相機庫在需要渲染時請求一個 surface。在這段代碼中,我們收集這些 surfaceRequest 實例,并將它們轉發給屬于 camera-compose 組件的 CameraXViewfinder。
結果
就這樣,我們構建了一個功能齊全的全屏取景器。了解完整代碼片段,請訪問相關文檔:
https://gist.github.com/JolandaVerhoef/74d4696b804736c698450bd34b5c9ff8
本文中的代碼段包含以下許可證:
// Copyright 2024 Google LLC. SPDX-License-Identifier: Apache-2.0
-
Google
+關注
關注
5文章
1778瀏覽量
58430 -
相機
+關注
關注
4文章
1410瀏覽量
54337 -
API
+關注
關注
2文章
1545瀏覽量
63195
原文標題:在 Jetpack Compose 中解鎖 CameraX 的強大功能
文章出處:【微信號:Google_Developers,微信公眾號:谷歌開發者】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
深入了解CameraX 1.1版本的視頻拍攝功能
詳解Jetpack Compose 1.1版本的新功能
Jetpack Compose基礎知識科普
Compose在社區中的反響
Jetpack Compose 更新一覽 | 2022 Android 開發者峰會
Google計劃用Jetpack Compose來重建Android系統中的設置應用
Compose for Wear OS 1.1 推出穩定版: 了解新功能!
Kotlin聲明式UI框架Compose Multiplatform支持iOS

在 I/O 看未來 | Jetpack 新功能一覽

Jetpack WindowManager 1.1 穩定版

Jetpack Compose和設備類型的三大重要更新
NVIDIA JetPack 6.0版本的關鍵功能

解析NVIDIA JetPack 6.1的新功能

詳解Jetpack Compose布局流程

評論