首页 > 其他分享 >5.21

5.21

时间:2024-06-19 22:21:02浏览次数:9  
标签:val itemsRepository Flow homeUiState 5.21 HomeViewModel StateFlow

3. 更新界面状态

在此任务中,您将向应用添加一个 LazyColumn 来显示存储在数据库中的数据。

显示商品目录中商品的手机屏幕

HomeScreen 可组合函数演示

  • 打开 ui/home/HomeScreen.kt 文件并查看 HomeScreen() 可组合项。
 
@Composable
fun HomeScreen(
    navigateToItemEntry: () -> Unit,
    navigateToItemUpdate: (Int) -> Unit,
    modifier: Modifier = Modifier,
) {
    val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()

    Scaffold(
        topBar = {
            // Top app with app title
        },
        floatingActionButton = {
            FloatingActionButton(
                // onClick details
            ) {
                Icon(
                    // Icon details
                )
            }
        },
    ) { innerPadding ->

       // Display List header and List of Items
        HomeBody(
            itemList = listOf(),  // Empty list is being passed in for itemList
            onItemClick = navigateToItemUpdate,
            modifier = modifier.padding(innerPadding)
                              .fillMaxSize()
        )
    }

此可组合函数会显示以下各项:

  • 带有应用名称的顶部应用栏
  • 用于向商品目录中添加新商品的悬浮操作按钮 (FAB) 7b1535d90ee957fa.png
  • HomeBody() 可组合函数

HomeBody() 可组合函数会根据传入的列表显示商品目录商品。在起始代码实现中,我们将空列表 (listOf()) 传递给了 HomeBody() 可组合函数。如需将商品目录列表传递给此可组合函数,您必须从存储库中检索商品目录数据,并将其传入 HomeViewModel

在 HomeViewModel 中发出界面状态

当您向 ItemDao 添加用于获取商品的 getItem() 和 getAllItems() 方法时,您将 Flow 指定为返回值类型。回想一下,Flow 代表通用数据流。通过返回 Flow,您只需在指定生命周期内明确调用 DAO 中的方法一次即可。Room 以异步方式处理底层数据的更新。

从数据流中获取数据的过程称为收集数据流。从界面层中的数据流收集数据时,需要考虑一些事项。

  • 配置更改等生命周期事件(例如旋转设备)会导致重新创建 activity,进而导致重组,并从您的 Flow 重新收集数据。
  • 建议您将值缓存为状态,这样现有数据就不会在生命周期事件之间丢失。
  • 如果没有任何观察器(例如在可组合项的生命周期结束后),则应取消数据流。

如需从 ViewModel 公开 Flow,推荐使用 StateFlow。无论界面生命周期如何,使用 StateFlow 均可保存和观察数据。如需将 Flow 转换为 StateFlow,您可以使用 stateIn 操作符。

stateIn 操作符有三个参数,如下所述:

  • scope - viewModelScope 定义了 StateFlow 的生命周期。取消 viewModelScope 后,StateFlow 也会取消。
  • started - 仅当界面可见时,流水线才应有效。为此,请使用 SharingStarted.WhileSubscribed()。如需配置从最后一个订阅者消失到停止共享协程之间的延迟时间(以毫秒为单位),请将 TIMEOUT_MILLIS 传递给 SharingStarted.WhileSubscribed() 方法。
  • initialValue - 将状态流的初始值设置为 HomeUiState()

将 Flow 转换为 StateFlow 后,您可以使用 collectAsState() 方法对其进行收集,并将其数据转换为相同类型的 State

在此步骤中,您将检索 Room 数据库中的所有商品,作为界面状态的 StateFlow 可观察 API。当 Room Inventory 数据发生更改时,界面会自动更新。

  1. 打开 ui/home/HomeViewModel.kt 文件,其中包含一个 TIMEOUT_MILLIS 常量和一个 HomeUiState 数据类,该类将商品列表作为构造函数参数。
 
// No need to copy over, this code is part of starter code

class HomeViewModel : ViewModel() {

    companion object {
        private const val TIMEOUT_MILLIS = 5_000L
    }
}

data class HomeUiState(val itemList: List<Item> = listOf())
  1. 在 HomeViewModel 类中,声明一个名为 homeUiState 且类型为 StateFlow<HomeUiState> 的 val。您很快就要解决初始化错误。
 
val homeUiState: StateFlow<HomeUiState>
  1. 对 itemsRepository 调用 getAllItemsStream(),并将其分配给您刚刚声明的 homeUiState
 
val homeUiState: StateFlow<HomeUiState> =
    itemsRepository.getAllItemsStream()

您现在会收到一个“Unresolved reference: itemsRepository”错误。如需解决“Unresolved reference”错误,您需要将 ItemsRepository 对象传递给 HomeViewModel

  1. 将类型为 ItemsRepository 的构造函数参数添加到 HomeViewModel 类中。
 
import com.example.inventory.data.ItemsRepository

class HomeViewModel(itemsRepository: ItemsRepository): ViewModel() {
  1. 在 ui/AppViewModelProvider.kt 文件的 HomeViewModel 初始化程序中,传递 ItemsRepository 对象,如下所示。
 
initializer {
    HomeViewModel(inventoryApplication().container.itemsRepository)
}
  1. 返回至 HomeViewModel.kt 文件。请注意类型不匹配错误。如需解决此问题,请添加转换映射,如下所示。
 
val homeUiState: StateFlow<HomeUiState> =
    itemsRepository.getAllItemsStream().map { HomeUiState(it) }

Android Studio 仍会显示类型不匹配错误。导致此错误的原因在于,homeUiState 的类型为 StateFlow,而 getAllItemsStream() 却返回了 Flow

  1. 使用 stateIn 操作符将 Flow 转换为 StateFlowStateFlow 是界面状态的可观察 API,可让界面自行更新。
 
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn

val homeUiState: StateFlow<HomeUiState> =
    itemsRepository.getAllItemsStream().map { HomeUiState(it) }
        .stateIn(
            scope = viewModelScope,
            started = SharingStarted.WhileSubscribed(TIMEOUT_MILLIS),
            initialValue = HomeUiState()
        )
  1. 构建应用,确保代码中没有错误。请注意,用户界面不会有任何变化。

标签:val,itemsRepository,Flow,homeUiState,5.21,HomeViewModel,StateFlow
From: https://www.cnblogs.com/galileo9527/p/18257602

相关文章

  • 5.21博客
    又是周一!课这么多spring-boot就先放一放学习内容:安卓packagecom.example.app_02.database;importandroid.util.Log;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.PreparedStatement;importjava.sql.ResultSet;publicclassMySQLCon......
  • 5.21
    import'package:flutter/material.dart';import'package:photo_view/photo_view.dart';voidmain(){runApp(MaterialApp(home:Picture1(),));}classPicture1extendsStatelessWidget{@overrideWidgetbuild(BuildContextcontext){......
  • 2024.05.21
    今日学习时长:83分钟;代码行数:41行博客数量:1篇今天主要开始了数据库实验三的操作,今天的大部分时长都在研究SQLserver数据库中的用户的新建和权限修改。SQLsever中直接用windows验证登录后可以在安全性—>登录名下新建一个用户,但是在切换为用户名+密码登录后,我发现我无法打开查......
  • 5.21
    继续与小组成员讨论如何完善每日心情的记录并且统计出来,根据不同的统计内容进行分析代码行量:166行学习所花时间:0.5h  packagecom.example.memosystem.activity;importandroid.os.AsyncTask;importandroid.os.Bundle;importandroid.widget.ArrayAdapter;importandroid.......
  • 5.21
    地铁查询系统项目1.引言地铁查询系统旨在提供用户方便快捷的地铁线路查询服务,帮助用户准确地规划出行路线,节省时间和精力。2.功能需求2.1路线查询-用户可以输入起点站和终点站,系统将返回最佳的地铁路线,并显示换乘信息和预计耗时。-系统支持最短路线和最少换乘两种查询模......
  • 2024.5.21(周二)
    function[x,val,k]=frcg(fun,gfun,x0)%功能:用共轭梯度法求无约束问题minif(x)%输入:fun,gfun分别是目标函数和梯度,x0是初始点%输出:x,val分别是近似最优点和最优值,k表示迭代次数k=0;maxk=5000;rho=0.6;sigma=0.4;e=1e-6;%精度n=length(x0);while(k<maxk)g=feval(gfun......
  • 5.20 && 5.21
    最近相当有写闲话的想法,不过每次都想把这题调完就写然后这题就调不完了(放假家长不来,我也懒得回去,所以就自己在衡水待着拿到手机发现崩铁和9都要更新,所以就开的原发现不用更新的代价是啥也没有只能把地图探索和深渊打了打nainai滴又只打了6星,手机玩甘雨体验极差我妈还......
  • 5.20 && 5.21
    最近相当有写闲话的想法,不过每次都想把这题调完就写然后这题就调不完了(放假家长不来,我也懒得回去,所以就自己在衡水待着拿到手机发现崩铁和9都要更新,所以就开的原发现不用更新的代价是啥也没有只能把地图探索和深渊打了打nainai滴又只打了6星,手机玩甘雨体验极差我妈还......
  • 5.20 && 5.21
    最近相当有写闲话的想法,不过每次都想把这题调完就写然后这题就调不完了(放假家长不来,我也懒得回去,所以就自己在衡水待着拿到手机发现崩铁和9都要更新,所以就开的原发现不用更新的代价是啥也没有只能把地图探索和深渊打了打nainai滴又只打了6星,手机玩甘雨体验极差我妈还......
  • 5.20 && 5.21
    最近相当有写闲话的想法,不过每次都想把这题调完就写然后这题就调不完了(放假家长不来,我也懒得回去,所以就自己在衡水待着拿到手机发现崩铁和9都要更新,所以就开的原发现不用更新的代价是啥也没有只能把地图探索和深渊打了打nainai滴又只打了6星,手机玩甘雨体验极差我妈还......