Jetpack Compose 狀態管理指南:從基礎到高級實踐

在Jetpack Compose中,界面狀態管理是構建響應式UI的核心。以下是Compose狀態管理的主要概念和實現方式:

基本狀態管理

1. 使用 mutableStateOf

@Composable
fun Counter() {var count by remember { mutableStateOf(0) }Button(onClick = { count++ }) {Text("Clicked $count times")}
}

2. 使用 rememberrememberSaveable

@Composable
fun LoginScreen() {var username by rememberSaveable { mutableStateOf("") }var password by rememberSaveable { mutableStateOf("") }Column {TextField(value = username,onValueChange = { username = it },label = { Text("Username") })TextField(value = password,onValueChange = { password = it },label = { Text("Password") })}
}

狀態提升 (State Hoisting)

@Composable
fun StatefulCounter() {var count by remember { mutableStateOf(0) }StatelessCounter(count, { count++ })
}@Composable
fun StatelessCounter(count: Int, onIncrement: () -> Unit) {Button(onClick = onIncrement) {Text("Clicked $count times")}
}

ViewModel 集成

class CounterViewModel : ViewModel() {private val _count = mutableStateOf(0)val count: State<Int> = _countfun increment() {_count.value++}
}@Composable
fun CounterScreen(viewModel: CounterViewModel = viewModel()) {val count by viewModel.countButton(onClick = { viewModel.increment() }) {Text("Clicked $count times")}
}

復雜狀態管理

1. 使用數據類管理多個狀態

data class LoginState(val username: String = "",val password: String = "",val isLoading: Boolean = false,val error: String? = null
)@Composable
fun LoginScreen() {var state by remember { mutableStateOf(LoginState()) }Column {if (state.isLoading) {CircularProgressIndicator()}TextField(value = state.username,onValueChange = { state = state.copy(username = it) })TextField(value = state.password,onValueChange = { state = state.copy(password = it) })state.error?.let {Text(it, color = Color.Red)}}
}

2. 使用 StateFlow 和 ViewModel

class LoginViewModel : ViewModel() {private val _state = MutableStateFlow(LoginState())val state: StateFlow<LoginState> = _statefun onUsernameChange(username: String) {_state.update { it.copy(username = username) }}fun onPasswordChange(password: String) {_state.update { it.copy(password = password) }}
}@Composable
fun LoginScreen(viewModel: LoginViewModel = viewModel()) {val state by viewModel.state.collectAsState()Column {TextField(value = state.username,onValueChange = viewModel::onUsernameChange)TextField(value = state.password,onValueChange = viewModel::onPasswordChange)}
}

狀態恢復 (State Restoration)

@Composable
fun RememberSaveableExample() {var selectedTab by rememberSaveable { mutableStateOf(0) }TabRow(selectedTabIndex = selectedTab) {listOf("Tab 1", "Tab 2", "Tab 3").forEachIndexed { index, title ->Tab(selected = selectedTab == index,onClick = { selectedTab = index },text = { Text(title) })}}
}

最佳實踐

  1. 單一數據源:確保每個狀態只有一個可信來源
  2. 最小化狀態:只存儲必要的UI狀態
  3. 狀態提升:將狀態提升到共享的父組件
  4. 不可變狀態:使用copy或新實例來更新狀態
  5. 分離業務邏輯:將復雜邏輯放在ViewModel或業務層

選擇哪種狀態管理方式取決于應用復雜度和團隊偏好。對于簡單組件,mutableStateOf足夠;對于復雜應用,建議使用ViewModel配合StateFlow或類似解決方案。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/75428.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/75428.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/75428.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vant4+vue3上傳一個pdf文件并實現pdf的預覽。使用插件pdf.js

注意下載的插件的版本"pdfjs-dist": "^2.2.228", npm i pdfjs-dist2.2.228 然后封裝一個pdf的遮罩。因為pdf文件有多頁&#xff0c;所以我用了swiper輪播的形式展示。因為用到移動端&#xff0c;手動滑動頁面這樣比點下一頁下一頁的方便多了。 直接貼代碼…

Leetcode hot 100(day 4)

翻轉二叉樹 做法&#xff1a;遞歸即可&#xff0c;注意判斷為空 class Solution { public:TreeNode* invertTree(TreeNode* root) {if(rootnullptr)return nullptr;TreeNode* noderoot->left;root->leftinvertTree(root->right);root->rightinvertTree(node);retu…

C,C++語言緩沖區溢出的產生和預防

緩沖區溢出的定義 緩沖區是內存中用于存儲數據的一塊連續區域&#xff0c;在 C 和 C 里&#xff0c;常使用數組、指針等方式來操作緩沖區。而緩沖區溢出指的是當程序向緩沖區寫入的數據量超出了該緩沖區本身能夠容納的最大數據量時&#xff0c;額外的數據就會覆蓋相鄰的內存區…

大數據(4)Hive數倉三大核心特性解剖:面向主題性、集成性、非易失性如何重塑企業數據價值?

目錄 背景&#xff1a;企業數據治理的困境與破局一、Hive數據倉庫核心特性深度解析1. ?面向主題性&#xff08;Subject-Oriented&#xff09;&#xff1a;從業務視角重構數據?2. ?集成性&#xff08;Integrated&#xff09;&#xff1a;打破數據孤島的統一視圖?3. ?非易失…

A股復權計算_前復權數據計算_終結章

目錄 前置&#xff1a; 計算方法推導 數據&#xff1a; 代碼&#xff1a; 視頻&#xff1a; 前置&#xff1a; 1 本系列將以 “A股復權計算_” 開頭放置在“隨想”專欄 2 權息數據結合 “PostgreSQL_” 系列博文中的股票未復權數據&#xff0c;可以自行計算復權日數據 …

Nature:新發現!首次闡明大腦推理神經過程

人類具有快速適應不斷變化的環境的認知能力。這種能力的核心是形成高級、抽象表示的能力&#xff0c;這些表示利用世界上的規律來支持泛化。然而&#xff0c;關于這些表征如何在神經元群中編碼&#xff0c;它們如何通過學習出現以及它們與行為的關系&#xff0c;人們知之甚少。…

Kotlin 集合函數:map 和 first 的使用場景

Kotlin 提供了豐富的集合操作函數&#xff0c;使開發者可以更加簡潔、高效地處理數據。其中&#xff0c;map 和 first 是兩個常用的函數&#xff0c;分別用于轉換集合和獲取集合中的第一個元素。 1. map 的使用場景 場景 1&#xff1a;對象列表轉換 在開發中&#xff0c;我們…

EIR管理中IMEI和IMSI信息的作用

在EIR&#xff08;設備身份注冊&#xff09;管理中&#xff0c;IMEI&#xff08;國際移動設備身份碼&#xff09;和IMSI&#xff08;國際移動用戶識別碼&#xff09;各自具有重要作用&#xff0c;以下是詳細介紹&#xff1a; IMEI的作用 設備身份識別&#xff1a;IMEI是移動設…

MAUI開發第一個app的需求解析:登錄+版本更新,用于喂給AI

vscode中MAUI框架已經搭好,用MAUI+c#webapi+orcl數據庫開發一個app, 功能是兩個界面一個登錄界面,登錄注冊常用功能,另一個主窗體,功能先空著,顯示“主要功能窗體”。 這是一個全新的功能,需要重零開始涉及所有數據表 登錄后檢查是否有新版本程序,自動更新功能。 1.用戶…

KUKA機器人查看運行日志的方法

對于KUKA機器人的運行日志都是可以查看和導出的&#xff0c;方便查找問題。KUKA機器人的運行日志查看方法如下&#xff1a; 1、在主菜單下&#xff0c;選擇【診斷】-【運行日志】-【顯示】下打開&#xff1b; 2、顯示出之前的機器人運行日志&#xff1b; 3、也可以通過【過濾器…

Kali Linux 2025.1a:主題煥新與樹莓派支持的深度解析

一、年度主題更新與桌面環境升級 Kali Linux 2025.1a作為2025年的首個版本&#xff0c;延續了每年刷新主題的傳統。本次更新包含全新的啟動菜單、登錄界面及桌面壁紙&#xff0c;涵蓋Kali標準版和Kali Purple版本。用戶可通過安裝kali-community-wallpapers包獲取社區貢獻的額…

【UVM學習筆記】更加靈活的UVM—通信

系列文章目錄 【UVM學習筆記】UVM基礎—一文告訴你UVM的組成部分 【UVM學習筆記】UVM中的“類” 文章目錄 系列文章目錄前言一、TLM是什么&#xff1f;二、put操作2.1、建立PORT和EXPORT的連接2.2 IMP組件 三、get操作四、transport端口五、nonblocking端口六、analysis端口七…

uni-app項目上傳至gitee方法詳細教程

1. 準備工作 1.1 安裝 Git 下載并安裝 Git&#xff1a;前往 Git 官網&#xff0c;根據操作系統下載安裝包。 配置用戶名和郵箱&#xff08;需與 Gitee 賬號一致&#xff09;&#xff1a; git config --global user.name "你的Gitee用戶名" git config --global use…

走向多模態AI之路(三):多模態 AI 的挑戰與未來

目錄 前言一、多模態 AI 真的成熟了嗎&#xff1f;二、多模態 AI 的主要挑戰2.1 計算資源消耗&#xff1a;模型復雜度帶來的成本問題2.2 數據標注困難&#xff1a;跨模態數據集的挑戰2.3 對齊和融合的難點2.4 泛化能力與魯棒性2.5 倫理與隱私問題 三、研究方向與未來發展3.1 輕…

STM32單片機入門學習——第12節: [5-2]對射式紅外傳感器計次旋轉編碼器計次

寫這個文章是用來學習的,記錄一下我的學習過程。希望我能一直堅持下去,我只是一個小白,只是想好好學習,我知道這會很難&#xff0c;但我還是想去做&#xff01; 本文寫于&#xff1a;2025.04.03 STM32開發板學習——第12節: [5-2]對射式紅外傳感器計次&旋轉編碼器計次 前言…

匯編學習之《jcc指令》

JCC&#xff08;Jump on Condition Code&#xff09;指的是條件跳轉指令&#xff0c;c中的就是if-else, while, for 等分支循環條件判斷的邏輯。它包括很多指令集&#xff0c;各自都不太一樣&#xff0c;接下來我盡量將每一個指令的c 源碼和匯編代碼結合起來看&#xff0c;加深…

深度解析算法之滑動窗口

12滑動窗口—將 x 減到 0 的最小操作數 題目傳送門 題目描述&#xff1a; 給你一個整數數組 nums 和一個整數 x 。每一次操作時&#xff0c;你應當移除數組 nums 最左邊或最右邊的元素&#xff0c;然后從 x 中減去該元素的值。請注意&#xff0c;需要 修改 數組以供接下來的操…

[MySQL初階]MySQL表的操作

MySQL表的操作 1. 創建表2. 查看表結構3. 修改表&#xff08;修改表的屬性而非表的數據&#xff09;4. 刪除表 1. 創建表 語法&#xff1a; CREATE TABLE table_name (field1 datatype,field2 datatype,field3 datatype ) character set 字符集 collate 校驗規則 engine 存儲…

sqlalchemy詳細介紹以及使用方法

SQLAlchemy是一個Python的ORM&#xff08;對象關系映射&#xff09;工具&#xff0c;它允許開發者使用Python代碼來操作數據庫而不必直接編寫SQL語句。SQLAlchemy提供了一種抽象層&#xff0c;使開發者可以通過簡單的Python對象來表示數據庫表和記錄&#xff0c;從而實現對數據…

圖解AUTOSAR_SWS_LINDriver

AUTOSAR LIN驅動詳解文檔 基于AUTOSAR標準的本地互聯網絡(LIN)驅動程序技術規范解析 目錄 1. 概述 1.1 AUTOSAR LIN驅動簡介1.2 LIN協議基礎2. LIN驅動架構 2.1 類圖結構2.2 狀態機設計3. LIN幀結構 3.1 基本幀組成3.2 PID結構4. LIN驅動配置 4.1 主要配置參數4.2 配置結構5. L…