Fragment/Activity的uiState类设计规模相关疑问
嘿,你的理解基本没错!按照Google推荐的应用架构,单个Fragment/Activity的UI状态确实通常用一个单独的UiState类来封装——就像你看到的NewsUiState那样,把和当前屏幕相关的所有状态都打包进去。
你提到NewsUiState同时包含了数据表示(NewItemUiState)和屏幕相关状态(比如isSignedIn),这其实是完全合理的:UI状态本来就需要涵盖两部分内容——要展示的业务数据,以及界面自身的交互状态(是否登录、是否加载中、有没有错误提示等)。把这些放在一起,UI层才能一次性拿到渲染整个界面需要的所有信息,避免出现数据和状态不匹配的尴尬情况(比如数据已经加载完成,但加载状态还没更新,导致UI还在转圈)。
至于你担心的“复杂UI会让UiState类有几百个属性”,其实完全不用焦虑!咱们可以通过嵌套子状态类的方式来拆分,而不是把所有属性平铺在一个大类里。举个例子,如果是一个包含顶部导航区、内容列表、侧边栏、底部操作栏的复杂页面,咱们可以这样设计:
data class ComplexScreenUiState( val navBarState: NavBarUiState, val contentListState: ContentListUiState, val sidebarState: SidebarUiState, val bottomBarState: BottomBarUiState, val isGlobalLoading: Boolean, val globalErrorMessage: String? ) // 顶部导航栏的专属状态 data class NavBarUiState( val isSignedIn: Boolean, val userName: String?, val notificationCount: Int ) // 内容列表的专属状态 data class ContentListUiState( val items: List<ItemUiState>, val isRefreshing: Boolean, val hasMoreItems: Boolean ) // 其他子模块的状态类同理
拆分的核心原则是按UI区域或功能模块划分:只要某一组状态是服务于同一个UI部分的,就把它们封装成一个子UiState。这样一来,主UiState就只是把各个子状态组合起来,结构清晰,既不会出现几百个属性堆在一起的情况,维护起来也方便——当某个模块的状态变化时,完全不会影响到其他无关的部分。
总的来说,Google的架构建议里,单UI对应单UiState类是核心,但咱们可以通过合理的嵌套拆分来应对复杂场景,既符合规范又能保持代码的整洁易维护。
备注:内容来源于stack exchange,提问作者citizen_code

