Android的ViewModel

news2024/12/23 10:37:07

前言

在Compose的学习中,我们在可组合函数中使用rememberSaveable​​​​​​​保存应用数据,但这可能意味着将逻辑保留在可组合函数中或附近。随着应用体量不断变大,您应将数据和逻辑从可组合函数中移出。

而在之前的应用架构学习中,我们接触到了MVVM架构,他将应用数据存储在了ViewModel中,它是Android Jetpack 库中的架构组件之一。

当框架在配置更改或其他事件期间销毁并重新创建 activity 时,存储的数据不会丢失。不过,如果 activity 因进程终止而被销毁,数据将会丢失。ViewModel 只能通过快速重新创建 activity 缓存数据。

了解应用架构

架构原则

最常用的架构原则包括:分离关注点通过模型驱动界面

  • 分离关注点:该原则指出,应将应用分为函数类,每个类有各自的职责
  • 通过模型驱动界面:该原则指出,应该通过模型驱动界面,最好是持久性模型

模型是负责处理应用数据的组件。它们独立于应用中的界面元素和应用组件,因此不受应用的生命周期以及相关的关注点的影响。

推荐的应用架构 

基于上面两点原则,每个应用应至少有两个层:

  • 界面层:屏幕上显示应用数据,但独立于数据层的层
  • 数据层:用于存储、检索和提供应用数据的层

每当数据因用户互动(例如按了某个按钮)而发生变化时,界面都应随之更新,以反映这些变化。

界面层由以下组件组成:

  • 界面元素:用于在屏幕上呈现数据的组件。您将使用 Compose 构建这些元素。
  • 状态容器:用于保存数据、向界面提供数据以及处理应用逻辑的组件。此处我们使用 ViewModel

ViewModel

简介

ViewModel组件用于存储和公开界面所使用的状态(UI State)。

界面状态(UI State)是经过ViewModel转换的应用数据。界面(UI)是相对于用户而言的,界面状态是相对于应用而言的,例如一个开关switch展现在用户面前,而switch是开还是关,就是switch的界面状态。因此,对于界面状态的任何改变,都会直接影响界面。

ViewModel会存储应用相关的数据,这些数据不会在activity被销毁并重新创建时被销毁。应用会在配置更改期间自动保留ViewModel对象,以便在重组时ViewModel存储的数据可以立即被使用。

与Compose梦幻联动

在使用Compose时,ViewModel是向可组合项展示界面状态的主要方式。过去我们将数据的存储和处理方式留在activity或fragment中,臃肿而不直观;如今在混合应用中,activity和fragment仅用于托管可组合函数。

添加ViewModel

以下是用户掷骰子屏幕的 ViewModel 实现示例。

1. 打开app模块下的build.gradle.kts,在dependencies块添加如下内容:

dependencies {
// other dependencies

    implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1")
//...
}

2. 添加一个数据类存储各项值,并创建一个类继承ViewModel:

//数据类,存储游戏的值
data class DiceUiState(
    val firstDieValue: Int? = null,
    val secondDieValue: Int? = null,
    val numberOfRolls: Int = 0,
)

class DiceRollViewModel : ViewModel() {

    // 展示界面状态
    // 此处的StateFlow是数据容器式可观察数据流,其value属性反映了当前的状态值
    // 有了它,可组合函数就可以监听界面状态更新

    //防止外部类修改ViewModel的数据,设置为private,同时val类型不包含setter,为只读属性
    private val _uiState = MutableStateFlow(DiceUiState())
    //asStateFlow方法使可变状态流变为只读状态流,界面通过只读属性的uiState读取值
    val uiState: StateFlow<DiceUiState> = _uiState.asStateFlow()

    // 处理业务逻辑
    fun rollDice() {
        _uiState.update { currentState ->
            //调用 copy 方法来创建新的 DiceState 对象,并将其赋值给 uiState 变量。
            //这将触发 UI 的重新渲染。
            currentState.copy(
                firstDieValue = Random.nextInt(from = 1, until = 7),
                secondDieValue = Random.nextInt(from = 1, until = 7),
                numberOfRolls = currentState.numberOfRolls + 1,
            )
        }
    }
}

3. 从activity访问ViewModel:

import androidx.activity.viewModels

class DiceRollActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        // 在系统第一次调用Activity的onCreate()方法时创建一个 ViewModel实例
        // 重新创建的activity会收到相同的、第一次创建activity时留下的ViewModel实例

        // 此处使用了'by viewModels()'的Kotlin属性委托
        // 他创建并初始化与activity相关联的ViewModel
        val viewModel: DiceRollViewModel by viewModels()
        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.uiState.collect {
                    // 在此处更新ui元素
                }
            }
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1462012.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Duilib显示gif颜色背景与原图不符GifUI

//xml <GifUI name"gif_option_new" float"true" pos"608,28,0,0" width"28" height"14" gif"new.gif"/>遇到两个问题。 1、图片背景只有第一帧显示&#xff0c;每一帧的背景色一样&#xff0c;字不同&…

FISCO BCOS(十七)利用脚本进行区块链系统监控

要利用脚本进行区块链系统监控&#xff0c;你可以使用各种编程语言编写脚本&#xff0c;如Python、Shell等 利用脚本进行区块链系统监控可以提高系统的稳定性、可靠性&#xff0c;并帮助及时发现和解决潜在问题&#xff0c;从而确保区块链网络的正常运行。本文可以利用脚本来解…

Redis-内存管理

Redis是基于内存存储的&#xff0c;非关系型&#xff0c;键值对数据库。因此&#xff0c;对Redis来说&#xff0c;内存空间的管理至关重要。那Redis是如何内存管理的呢&#xff1f; 一、最大内存限制 Redis 提供了 maxmemory 参数允许用户设置 Redis 可以使用的最大内存大小。…

【2024.02.22】定时执行专家 V7.0 发布 - TimingExecutor V7.0 Release - 龙年春节重大更新版本

目录 ▉ 新版本 V7.0 下载地址 ▉ V7.0 新功能 ▼2024-02-21 V7.0 - 更新日志▼ ▉ V7.0 新UI设计 ▉ 新版本 V7.0 下载地址 BoomWorks软件的最新版本-CSDN博客文章浏览阅读10w次&#xff0c;点赞9次&#xff0c;收藏41次。▉定时执行专家—毫秒精度、专业级的定时任务执行…

psp游戏存档收集SAVEDATA

不想从头开始 ppsspp存档目录 pc&#xff1a;ppsspp解压目录\memstick\PSP\SAVEDATA 安卓&#xff1a;根目录\PSP\SAVEDATA 噬神者2(日版) NPJH50832099c645531020001000 風燐-https://wwl.lanzouq.com/iI1R01owozxa 咲夜-https://wwl.lanzouq.com/id1tX1owp2uf につてのぬ…

Laravel01 课程介绍以及Laravel环境搭建

Laravel01 课程介绍 1. Laravel2. mac开发环境搭建(通过Homebrew)3. 创建一个项目 1. Laravel 公司中面临着PHP项目与Java项目并行&#xff0c;所以需要我写PHP的项目&#xff0c;公司用的框架就是Laravel&#xff0c;所以在B站上找了一门课学习。 Laravel中文文档地址 https…

(っ•̀ω•́)っ 如何在PPT中为文本框添加滚动条

本人在写技术分享的PPT时&#xff0c;遇到问题&#xff1a;有一大篇的代码&#xff0c;如何在一张PPT页面上显示&#xff1f;急需带有滚动条的文本框&#xff01;百度了不少&#xff0c;自己也来总结一篇&#xff0c;如下&#xff1a; 1、找到【文件】-【选项】 2、【自定义功…

数据库管理-第153期 Oracle Vector DB AI-05(20240221)

数据库管理153期 2024-02-21 数据库管理-第153期 Oracle Vector DB & AI-05&#xff08;20240221&#xff09;1 Oracle Vector的其他特性示例1&#xff1a;示例2 2 简单使用Oracle Vector环境创建包含Vector数据类型的表插入向量数据 总结 数据库管理-第153期 Oracle Vecto…

如何修改docker容器的端口映射

要修改 Docker 容器的端口映射&#xff0c;你需要停止并删除现有的容器&#xff0c;然后使用新的端口映射重新运行容器。以下是详细步骤&#xff1a; 停止容器&#xff1a; 使用 docker stop 命令停止正在运行的容器。替换 <container_id> 为你要停止的容器的 ID 或者容器…

物联网在智慧景区中的应用:提升游客体验与运营效率

目录 一、物联网技术概述 二、物联网在智慧景区中的应用 1、智能门票系统 2、智能导览系统 3、智能安全监控系统 4、智能环保系统 三、物联网在智慧景区中提升游客体验 1、提高游览便捷性 2、个性化服务体验 3、提升游客安全感 四、物联网在智慧景区中提升运营效率 …

Python爬虫实战入门:爬取360模拟翻译(仅实验)

文章目录 需求所需第三方库requests 实战教程打开网站抓包添加请求头等信息发送请求&#xff0c;解析数据修改翻译内容以及实现中英互译 完整代码 需求 目标网站&#xff1a;https://fanyi.so.com/# 要求&#xff1a;爬取360翻译数据包&#xff0c;实现翻译功能 所需第三方库 …

零基础学习8051单片机(十五)

本次先看书学习&#xff0c;并完成了课后习题&#xff0c;题目出自《单片机原理与接口技术》第五版—李清朝 答: &#xff08;1&#xff09;当 CPU正在处理某件事情的时候&#xff0c;外部发生的某一件事件请求 CPU 迅速去处理&#xff0c;于是&#xff0c;CPU暂时中止当前的工…

【前端】夯实基础 css/html/js 50个练手项目(持续更新)

文章目录 前言Day 1 expanding-cardsDay 2 progress-steps 前言 发现一个没有用前端框架的练手项目&#xff0c;很适合我这种纯后端开发夯实基础&#xff0c;内含50个mini project&#xff0c;学习一下&#xff0c;做做笔记。 项目地址&#xff1a;https://github.com/bradtr…

纯血鸿蒙来画龙!基于HarmonyOS ArkTS来操作SVG图片

大家好&#xff0c;龙年报喜&#xff0c;大地回春&#xff0c;作为程序员&#xff0c;以代码之名&#xff0c;表达对于龙年的祝福。本节将演示如何在基于HarmonyOS ArkTS的Image组件来实现画一条中国龙&#xff0c;祝大家“码”上“鸿”福到&#xff01; 本文涉及的所有源码&a…

Java Web演化史:从Servlet到SpringBoot的技术进程及未来趋势

引言 在快速演进的IT世界里&#xff0c;Java Web开发始终屹立不倒&#xff0c;它不仅承担着历史的厚重&#xff0c;也始终面向未来。 自诞生之日起&#xff0c;Java Web技术就在不断地进化&#xff0c;以适应不同时代的需求。 本文将回顾Java Web开发的重要里程碑&#xff0c;…

Stable diffusion UI 介绍-文生图

1.提示词&#xff1a; 你希望图中有什么东西 2.负面提示词&#xff1a;你不希望图中有什么东西 选用了什么模型 使用参数 1.采样器 sampling method 使用什么算法进行采样 2.采样迭代步数 sampling steps 生成图像迭代的步数&#xff0c;越多越好&#xff0c;但是生成速度越大越…

qt-OPENGL-星系仿真

qt-OPENGL-星系仿真 一、演示效果二、核心程序三、下载链接 一、演示效果 二、核心程序 #include "model.h"Model::Model(QOpenGLWidget *_glWidget) { glWidget _glWidget;glWidget->makeCurrent();initializeOpenGLFunctions(); }Model::~Model() {destroyV…

如何添加或编辑自定义WordPress侧边栏

WordPress侧边栏是许多WordPress网站上的固定装置。它为您的内容提供了一个垂直空间&#xff0c;您可以在其中帮助读者导航、增加电子邮件列表或社交关注、展示广告等。 因为它是许多WordPress网站不可或缺的一部分&#xff0c;所以我们认为侧边栏值得拥有自己的大型指南。在这…

JS前端高频面试

JS数据类型有哪些&#xff0c;区别是什么 js数据类型分为原始数据类型和引用数据类型。 原始数据类型包括&#xff1a;number&#xff0c;string&#xff0c;boolean&#xff0c;null&#xff0c;undefined&#xff0c;和es6新增的两种类型&#xff1a;bigint 和 symbol。&am…

五种多目标优化算法(MOGWO、MOJS、NSWOA、MOPSO、MOAHA)性能对比,包含6种评价指标,9个测试函数(提供MATLAB代码)

一、5种多目标优化算法简介 1.1MOGWO 1.2MOJS 1.3NSWOA 1.4MOPSO 1.5MOAHA 二、5种多目标优化算法性能对比 为了测试5种算法的性能将其求解9个多目标测试函数&#xff08;zdt1、zdt2 、zdt3、 zdt4、 zdt6 、Schaffer、 Kursawe 、Viennet2、 Viennet3&#xff09;&#xff0…