基礎概念
-
什么是 Jetpack Compose?它與傳統 Android UI 開發有何不同?
- Compose 是 Android 的現代聲明式 UI 工具包,使用 Kotlin 編寫
- 不同于傳統的基于 View 和 XML 的 imperative 方式,Compose 使用聲明式范式
- 主要區別:無 XML 布局、無 findViewById、狀態驅動 UI、組合優于繼承
-
解釋 Compose 中的聲明式 UI 模型
- 描述 UI 應該是什么樣子,而不是如何逐步構建它
- UI 是應用狀態的函數:UI = f(state)
- 當狀態變化時,Compose 自動重新組合(recompose)受影響的組件
-
Composable 函數的特點是什么?
- 使用
@Composable
注解標記 - 可以調用其他 Composable 函數
- 無返回值(返回 Unit),因為它們描述 UI 而不是構造 UI 對象
- 可以接受參數并保持本地狀態
- 應該是冪等的和沒有副作用的
- 使用
狀態管理
-
解釋 Compose 中的狀態和記憶(remember)
- 狀態是隨時間變化的值,當狀態變化時會導致重組
remember
在重組期間保存值,避免每次重組都重新初始化mutableStateOf
創建可觀察狀態,當其值變化時通知 Compose
-
State Hoisting(狀態提升)是什么?為什么重要?
- 將狀態移動到調用者的更高層次,使組件無狀態
- 重要原因:提高可重用性、使組件更容易測試、實現單一數據源
- 模式:用參數傳遞狀態值,用 lambda 傳遞事件回調
-
比較
remember
和rememberSaveable
remember
只在配置更改期間保持狀態(如旋轉屏幕會丟失)rememberSaveable
使用 SavedStateHandle 在進程死亡和配置更改后恢復狀態rememberSaveable
可以自動保存基本類型和 Parcelable 類型,或通過自定義 Saver
主題和樣式
-
如何在 Compose 中實現主題和樣式?
- 使用
MaterialTheme
提供顏色、排版和形狀 - 可以自定義主題屬性:
MaterialTheme(colors = ..., typography = ..., shapes = ...)
- 通過
MaterialTheme.colors.primary
等方式訪問主題值
- 使用
-
解釋 Compose 中的
Modifier
系統- Modifier 是用于裝飾或增強組件的鏈式調用
- 可以添加 padding、大小、背景、點擊行為等
- 順序很重要:
Modifier.padding(10).size(50)
與Modifier.size(50).padding(10)
不同
布局和組合
-
Compose 中的基本布局組件有哪些?
Column
- 垂直排列子項Row
- 水平排列子項Box
- 堆疊子項ConstraintLayout
- 復雜布局,支持相對定位
-
如何創建自定義布局?
- 使用
Layout
可組合函數 - 實現
MeasurePolicy
定義測量和布局邏輯 - 示例:自定義流式布局、環形布局等
- 使用
性能優化
-
解釋 Compose 的重組(Recomposition)機制
- 當輸入變化時,Compose 會智能地只重組必要的組件
- 使用
@Stable
和@Immutable
注解幫助 Compose 做出優化決策 - 通過結構相等性比較 (
equals
) 決定是否需要重組
-
如何優化 Compose 性能?
- 使用
remember
避免不必要的計算 - 將大列表分成更小組件
- 對列表使用
LazyColumn
/LazyRow
- 避免在組合期間執行昂貴操作
- 使用
derivedStateOf
減少不必要的重組
- 使用
高級主題
-
如何在 Compose 中處理副作用?
- 使用副作用 API:
LaunchedEffect
,DisposableEffect
,SideEffect
LaunchedEffect
用于協程作用域內的副作用DisposableEffect
用于需要清理的資源rememberCoroutineScope
獲取與組合生命周期綁定的協程作用域
- 使用副作用 API:
-
解釋 Compose 中的
CompositionLocal
- 隱式傳遞依賴項的機制,避免顯式參數傳遞
- 常見用例:主題、配置、本地化等
- 通過
CompositionLocalProvider
提供值,LocalXXX.current
獲取值
-
如何將傳統 View 集成到 Compose 中?
- 使用
AndroidView
可組合函數 - 通過
update
回調響應狀態變化 - 對于自定義 View,實現
ViewBinding
或AndroidViewBinding
- 使用
實際應用
-
如何在 Compose 中實現導航?
- 使用
Navigation
組件與 Compose 集成 - 定義
NavHost
和可組合目的地 - 通過
rememberNavController()
獲取NavController
- 使用
navigate()
和popBackStack()
管理導航棧
- 使用
-
Compose 中如何處理圖片加載?
- 使用
Coil
或Glide
的 Compose 擴展 AsyncImage
(Coil) 或GlideImage
(Glide)- 支持占位符、錯誤圖像、轉換等
- 使用
-
如何在 Compose 中測試 UI?
- 使用
ComposeTestRule
進行 UI 測試 onNodeWithText
,onNodeWithTag
等查找節點performClick()
,performScrollTo()
等交互操作assertIsDisplayed()
,assertTextEquals()
等斷言
- 使用
架構模式
-
如何在 MVVM 架構中使用 Compose?
- ViewModel 持有和管理狀態
- Compose UI 觀察 ViewModel 的狀態
- 使用
viewModel()
函數獲取 ViewModel 實例 - 事件通過 ViewModel 暴露的方法處理
-
Compose 如何與數據流(如 Flow、LiveData)集成?
- 使用
collectAsState()
將 Flow 轉換為 Compose 狀態 LiveData.observeAsState()
用于 LiveData- 在
LaunchedEffect
中收集流,當鍵變化時取消并重新啟動
- 使用
常見問題解決
-
如何處理 Compose 中的鍵盤和輸入法?
- 使用
SoftwareKeyboardController
控制鍵盤 imePadding()
修飾符避免鍵盤遮擋內容focusRequester
管理輸入焦點
- 使用
-
Compose 中的動畫如何實現?
- 使用
animate*AsState
函數創建簡單動畫 updateTransition
管理多個動畫值AnimatedVisibility
顯示/隱藏動畫rememberInfiniteTransition
無限動畫
- 使用
-
如何調試 Compose 應用?
- 使用
debugInspectorInfo
檢查修飾符 - 重組計數調試:
debugLogRecomposition
- 布局檢查器支持 Compose
- 使用
compositionLocalOf
傳遞調試工具
- 使用
最新特性
-
Compose 1.2+ 中的新特性有哪些?
- 延遲布局改進(LazyLayout API)
- 可下載字體支持
- 嵌套滾動互操作改進
- 新的動畫 API 和效果
-
Compose Multiplatform 的現狀如何?
- 支持 Android、Desktop 和 Web
- 共享 UI 代碼跨平臺
- 特定平臺 API 通過 expect/actual 機制處理
希望這份全面的 Compose 面試題整理對您有所幫助!根據具體職位要求,可以重點準備相關領域的問題。