当前位置: 首页 > wzjs >正文

哪个网站有淘宝做图的素材贵州百度推广优化报告

哪个网站有淘宝做图的素材,贵州百度推广优化报告,网站用html模拟图片,创意设计与制作作品一 stateFlow和sharedFlow企业中使用 在企业级 Kotlin 项目中,StateFlow 和 SharedFlow 是 状态管理 与 事件分发 的核心工具,尤其在 MVVM 架构中扮演着极为关键的角色。 ✅ 企业中如何使用 StateFlow 和 SharedFlow 场景工具示例UI 状态同步&#xff…

一 stateFlow和sharedFlow企业中使用

在企业级 Kotlin 项目中,StateFlowSharedFlow状态管理事件分发 的核心工具,尤其在 MVVM 架构中扮演着极为关键的角色。


✅ 企业中如何使用 StateFlowSharedFlow

场景工具示例
UI 状态同步(如加载中、错误、成功)StateFlow显示进度条、内容或错误页
表单数据、选择器、筛选条件StateFlow用户输入姓名、选择性别
一次性事件(Toast、导航)SharedFlow登录成功跳转、提示
通用事件总线(EventBus 替代)SharedFlow多页面间通信

✅ 核心概念回顾

StateFlow

  • 持有一个状态值 value
  • 是热流,始终存储并发射最新状态
  • 类似于 LiveData,但更强大
  • 适合 UI 状态同步
private val _uiState = MutableStateFlow(UiState.Loading)
val uiState: StateFlow<UiState> = _uiState.asStateFlow()

SharedFlow

  • 不持有状态,没有 value
  • 默认不回放旧值(除非设置 replay)
  • 适合“一次性事件”传递(Toast、导航)
private val _events = MutableSharedFlow<UiEvent>()
val events = _events.asSharedFlow()

✅ 常用的高级操作符(transforming 操作)

这些 API 和普通 Flow 的操作符完全一样,只不过用在 StateFlow/SharedFlow 上。


1. map —— 映射转换值

val userNameLength: StateFlow<Int> = userName.map { it.length }.stateIn(viewModelScope, SharingStarted.Eagerly, 0)
  • 将字符串长度映射为 Int 状态
  • stateIn 是将转换结果转为新的 StateFlow

2. filter / filterNot —— 条件过滤

val nonEmptyName: Flow<String> = userName.filter { it.isNotBlank() }
  • 仅当用户名非空时,才往下游传递

3. combine —— 多个 Flow 合并成一个

val canSubmit: StateFlow<Boolean> = combine(userName, password) { name, pwd ->name.isNotBlank() && pwd.length >= 6
}.stateIn(viewModelScope, SharingStarted.Eagerly, false)
  • 多表单条件满足才能提交

4. distinctUntilChanged —— 状态去重,避免重复 UI 更新

val state = userName.distinctUntilChanged()
  • 如果两次值一样,不发射;适合 UI 避免重复绘制

5. debounce —— 延迟发射(防抖)

val searchQuery = MutableStateFlow("")val debouncedQuery = searchQuery.debounce(300).filter { it.isNotBlank() }.distinctUntilChanged()
  • 防止用户快速输入触发大量搜索请求
  • 类似 RxJava 的 debounce 功能

6. onEach —— 收到值时做一些操作(比如打日志)

val filtered = userName.onEach {Log.d("Flow", "Username changed to $it")
}

7. flatMapLatest —— 响应式请求场景(新请求来了取消旧的)

val userDetails = userId.flatMapLatest { id -> repository.loadUserDetail(id) }.stateIn(viewModelScope, SharingStarted.Lazily, null)
  • 类似 Retrofit 请求,用户快速切换 ID 时,自动取消旧请求

8. stateIn / shareIn —— Flow → StateFlow / SharedFlow

这些是 Flow 转为热流的关键:

val state: StateFlow<Int> = coldFlow.stateIn(viewModelScope, SharingStarted.Eagerly, 0)
val shared: SharedFlow<String> = coldFlow.shareIn(viewModelScope, SharingStarted.Lazily, 1)

✅ 实战建议(企业级写法)

🔒 封装可变性

private val _uiState = MutableStateFlow(UiState())
val uiState: StateFlow<UiState> = _uiState

🚀 触发事件

viewModelScope.launch {_events.emit(UiEvent.ShowToast("保存成功"))
}

💡 在 UI 中 collect

lifecycleScope.launchWhenStarted {viewModel.uiState.collect { state ->// render UI}
}

✅ 小结对比

操作符用途建议
map转换数据类型构造只读 ViewModel 状态
combine多源合并复杂表单、多个依赖状态
filter条件筛选防止无效数据流动
distinctUntilChanged避免重复 UI 渲染性能优化
debounce防止快速频繁事件搜索输入场景
flatMapLatest请求取消与替换API 请求、搜索
stateIn/shareInFlow 转热流ViewModel 转发数据给 UI

二 关于distinctUntilChanged和debounce方法

在 300ms 内发射最后一个值

  1. 关于 distinctUntilChanged()
  • "两次"指的是连续两次发射的值,没有时间间隔的概念
  • 只要前一次发射的值和后一次发射的值相同(通过 equals() 比较),就不会再次发射
  • 示例:如果 userName 依次发射 “A”, “A”, “B”, “B”, “B”, “A”
    • 实际发射:“A”, “B”, “A” (连续重复的被过滤)
  • 适合 UI 避免重复绘制:比如用户名没变化时就不需要重新绘制界面
  1. 关于 debounce(300)distinctUntilChanged 组合:
  • debounce(300):防抖 300 毫秒
    • 只有在 300ms 内没有新值时,才会发射最后一个值
    • 示例:快速输入 “abc”(假设每个字母间隔 100ms)
      • 只会在停止输入 300ms 后发射最后的 “abc”
  • filter { it.isNotBlank() }:过滤掉空字符串
  • distinctUntilChanged():确保最终发射的值与前一次不同
    • 示例:输入 “test” → 删除 → 再输入 “test”
      • 如果两次 “test” 之间没有其他值,第二次 “test” 不会被发射

总结区别:

  • debounce:处理高频事件,只关心稳定后的值
  • distinctUntilChanged:过滤连续重复的值
  • 组合使用时:先防抖,再过滤连续重复,非常适合搜索框等场景

这种组合能有效优化性能,避免不必要的网络请求或 UI 更新。

三 distinctUntilChanged()与时间间隔没有关系

  1. 关于时间间隔的影响

    • 即使两次发射间隔半小时(或任意长时间),只要中间没有发射过其他不同的值,第二次发射的 A 不会触发界面刷新。
    • distinctUntilChanged() 只比较相邻两次发射的值,与时间间隔完全无关。
    • 示例流程:
      // 时间轴 | 发射值 | 是否触发下游/界面刷新
      t0  | A   | 是 (首次发射)
      t30min | A   | 否 (与前一次相同)
      t35min | B   | 是 (与前一次不同)
      t60min | B   | 否 (与前一次相同)
      
  2. 关于比较规则

    • 只与内容有关:默认通过 equals() 方法比较值是否相同
    • 与以下因素无关
      • 发射时间间隔
      • 发射次数
      • 流的生命周期
    • 特殊用法:可以自定义比较器
      .distinctUntilChanged { old, new ->// 例如:忽略大小写比较字符串old.equals(new, ignoreCase = true)
      }
      

典型应用场景

// 用户输入搜索词时避免重复请求
searchTermFlow.debounce(300).distinctUntilChanged() // 连续输入相同词时只发一次.collect { term ->fetchResults(term) // 网络请求}

总结:distinctUntilChanged() 是一个内容感知而非时间感知的操作符,它的唯一职责就是过滤掉连续的重复值。

四 企业中使用stateflow和sharedFlow示例

import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.activity.R
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.ViewModel
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch// 表示 UI 的状态数据类,包括加载中、数据内容和错误信息
data class UiState(val loading: Boolean = false,val data: String = "",val error: String? = null
)// UI 事件的封装类,使用密封类进行分类表示
sealed class UiEvent {data class ShowToast(val message: String) : UiEvent()  // 显示 Toast 消息事件object NavigateToNext : UiEvent()                      // 导航事件
}class MainViewModel : ViewModel() {// 可变的状态流,用于内部更新 UI 状态private val _uiState = MutableStateFlow(UiState())// 暴露只读的 StateFlow 给 UI 层,避免外部修改状态val uiState: StateFlow<UiState> = _uiState.asStateFlow()// 用于发送一次性事件的 SharedFlow,配置了缓冲策略private val _uiEvent = MutableSharedFlow<UiEvent>(replay = 0,extraBufferCapacity = 1,onBufferOverflow = BufferOverflow.DROP_OLDEST)val uiEvent: SharedFlow<UiEvent> = _uiEvent.asSharedFlow()fun loadData() {viewModelScope.launch {Log.d("MainViewModel", "Start loading data")_uiState.update { it.copy(loading = true) }  // 更新状态为加载中try {delay(1000)  // 模拟网络延迟val response = fetchRemoteData()  // 获取模拟数据_uiState.update { it.copy(loading = false, data = response) }  // 更新数据加载完成_uiEvent.emit(UiEvent.ShowToast("加载成功"))  // 发送 Toast 事件} catch (e: Exception) {Log.e("MainViewModel", "Error loading data", e)_uiState.update { it.copy(loading = false, error = e.message) }  // 出现错误时更新错误信息}}}private suspend fun fetchRemoteData(): String {// 模拟网络请求返回的数据return "Hello Flow!"}fun onNavigateClicked() {viewModelScope.launch {Log.d("MainViewModel", "Navigate button clicked")_uiEvent.emit(UiEvent.NavigateToNext)  // 发送导航事件}}
}class MainFragment : Fragment() {private val viewModel: MainViewModel by viewModels()  // 通过委托方式获取 ViewModel 实例override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)// 启动生命周期感知的协程作用域viewLifecycleOwner.lifecycleScope.launch {viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {// 收集 UI 状态流并处理更新launch {viewModel.uiState.collect { state ->Log.d("MainFragment", "uiState collected: $state")  // 打印当前 UI 状态// 此处可绑定 UI 状态到视图控件}}// 收集 UI 事件流并执行相应操作launch {viewModel.uiEvent.collect { event ->Log.d("MainFragment", "uiEvent collected: $event")when (event) {is UiEvent.ShowToast ->Toast.makeText(requireContext(), event.message, Toast.LENGTH_SHORT).show()is UiEvent.NavigateToNext -> {// 使用传统 Intent 方式跳转 Activityval intent = Intent(requireContext(), NextActivity::class.java)startActivity(intent)}}}}}}Log.d("MainFragment", "Calling viewModel.loadData()")viewModel.loadData()  // 启动加载数据逻辑}
}
http://www.dtcms.com/wzjs/838750.html

相关文章:

  • 百度推广关键词价格查询网络seo招聘
  • 取名网站开发wordpress 积分系统
  • 网站营销单页怎么做吉安建设网站
  • 企业网站建设费用摊销中国交通建设集团
  • 电商网站 技术自助建站网站建设设计公司
  • 金属材料网站建设网页预览手机网站效果
  • 石景山网站建设公司排行建设 云服务器 网站
  • 酒店设计的网站建设wordpress 小工具 修改
  • 蛋糕网站建设淘宝上网站建设是什么
  • 优惠券网站要怎么做推广网页版梦幻西游是网易的吗
  • 营销型网站建设公司哪家好如何注册一个网站域名备案
  • 山西省建设执业资格注册中心网站手机设计
  • 铜陵建设行业培训学校网站熊猫办公ppt模板下载
  • 虚拟电子商务网站建设前期规划方案网页版游戏哪个好玩
  • 网站域名注册要多少钱wordpress手机版设置
  • 保定公司做网站wordpress 评分
  • 免费建站平台哪个稳定专题类响应式网站建设
  • 建筑网上招工平台哪个好网站百度推广和优化
  • 记录网站 自己做上海市建筑网
  • 青岛网站排名优化公司哪家好静安网站建设关键词优化seo
  • 网站建设的网站定位个人官网网站源码
  • 花都网站制作公司广东东莞职业技术学院
  • 免费建网站 建站之星全国企业工商信息查询官网
  • 佛山顺德网站设计公司江苏城乡建设职业学院网站
  • 做电影网站投资多少应用网站模板
  • 福建住房和城乡建设部网站首页做一个门户网站要多少钱
  • 注册网站怎么注册不了网站模板源代码下载
  • 那个旅游网站可以做行程合理规划网站
  • 网站大全vs怎么建手机网站
  • 北京建设工程建设交易信息网站数据推广公司