Jetpack Compose - MutableStateFlow、LaunchedEffect 函数

Jetpack Compose - MutableStateFlow、LaunchedEffect 函数

MutableStateFlow

1、基本介绍
  1. MutableStateFlow 是 Kotlin 协程库中专门用于状态管理的热流

  2. MutableStateFlow 可以看作 MutableLiveData 的协程版本,它们的设计目标一致,持有可观察的可变数据

  3. StateFlow 是只读的,MutableStateFlow 是可读可写的

2、演示
classMyViewModel{// 私有可写,对外可读privateval_counter=MutableStateFlow(0)valcounter:StateFlow<Int>=_counter.asStateFlow()privateval_message=MutableStateFlow("")valmessage:StateFlow<String>=_message.asStateFlow()funincrement(){_counter.value=_counter.value+1_message.value="点击了${_counter.value}次"}funreset(){_counter.value=0_message.value=""}}
  1. 使用 collectAsState 函数
// 记住状态,不然它每次都会重新创建valmyViewModel=remember{MyViewModel()}// 订阅数据,数据更新时,自动刷新 UIvalcounterbymyViewModel.counter.collectAsState()valmessagebymyViewModel.message.collectAsState()Column(modifier=Modifier.fillMaxSize().padding(16.dp),verticalArrangement=Arrangement.Center){Text(text="计数:$counter",fontSize=24.sp)Spacer(modifier=Modifier.height(8.dp))Text(text=message,fontSize=16.sp)Spacer(modifier=Modifier.height(16.dp))Button(onClick={myViewModel.increment()}){Text("增加")}Spacer(modifier=Modifier.height(8.dp))Button(onClick={myViewModel.reset()}){Text("重置")}}
  1. 使用 collect 函数
// 记住状态,不然它每次都会重新创建valmyViewModel=remember{MyViewModel()}varcounterbyremember{mutableStateOf(0)}varmessagebyremember{mutableStateOf("")}LaunchedEffect(Unit){myViewModel.counter.collect{newValue->counter=newValue}}LaunchedEffect(Unit){myViewModel.message.collect{newValue->message=newValue}}Column(modifier=Modifier.fillMaxSize().padding(16.dp),verticalArrangement=Arrangement.Center){Text(text="计数:$counter",fontSize=24.sp)Spacer(modifier=Modifier.height(8.dp))Text(text=message,fontSize=16.sp)Spacer(modifier=Modifier.height(16.dp))Button(onClick={myViewModel.increment()}){Text("增加")}Spacer(modifier=Modifier.height(8.dp))Button(onClick={myViewModel.reset()}){Text("重置")}}

LaunchedEffect 函数

1、基本介绍
  • 在 Compose 中,LaunchedEffect 函数专门用来安全执行挂起函数,生命周期自动绑定到可组合项
场景说明
进入组合启动协程,执行代码块
退出组合自动取消协程
键值变化时重组先取消旧协程,再启动新协程
  • 键值选择如下
键值行为
Unit只执行一次,不重启
key (变量)变量变化时重启
2、演示
@ComposablefunMainPage(){varmessagebyremember{mutableStateOf("首页加载中")}LaunchedEffect(Unit){delay(2000)message="首页加载完成"}Text(message,fontSize=24.sp)}
  1. 首页加载,只执行一次

  2. 在这个例子中,LaunchedEffect 绑定到了 MainPage 这个可组合函数

@ComposablefunMainPage(){varkeywordbyremember{mutableStateOf("")}varsearchResultsbyremember{mutableStateOf(listOf<String>())}LaunchedEffect(keyword){delay(2*1000)if(keyword.isNotBlank()){searchResults=keyword.map{it.toString()}}else{searchResults=emptyList()}}Column{TextField(value=keyword,onValueChange={keyword=it})searchResults.forEach{Text(it)}}}
  1. 搜索防抖,用户每次输入,keyword 变化触发 LaunchedEffect

  2. 每次都会等待 2 秒

  3. 如果在 2 秒内 keyword 再次变化,会取消之前的协程,重新开始计时

  4. 只有稳定 2 秒没有新输入,才会执行更新 searchResults

@ComposablefunMainPage(){valalpha=remember{Animatable(1f)}LaunchedEffect(Unit){while(isActive){delay(1000)alpha.animateTo(0f,tween(300))// 将 alpha 值从 1f 动画到 0f,时长 300msalpha.animateTo(1f,tween(300))// 将 alpha 值从 0f 动画到 1f,时长 300ms}}Box(modifier=Modifier.size(100.dp).background(Color.Red.copy(alpha=alpha.value)))}
  • 呼吸灯效果,循环重复,isActive 检查协程是否还在运行