LiveData从入门到实战

2023-12-26 04:08
文章标签 实战 入门 livedata

本文主要是介绍LiveData从入门到实战,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、简介
1、什么是LiveData

LiveData 是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 Activity、Fragment 或 Service)的生命周期。

2、LiveData 优势
  • 确保界面符合数据状态LiveData 遵循观察者模式。

当底层数据发生变化时,LiveData 会通知 Observer 对象。可以整合代码以在这些 Observer 对象中更新界面。这样一来,无需在每次应用数据发生变化时更新界面,因为观察者会替您完成更新。

  • 不会发生内存泄漏

观察者会绑定到 Lifecycle 对象,并在其关联的生命周期遭到销毁后进行自我清理。

  • 不会因 Activity 停止而导致崩溃

如果观察者的生命周期处于非活跃状态(如返回栈中的 Activity),则它不会接收任何 LiveData 事件。

  • 不再需要手动处理生命周期

界面组件只是观察相关数据,不会停止或恢复观察。LiveData 将自动管理所有这些操作,因为它在观察时可以感知相关的生命周期状态变化。

  • 数据始终保持最新状态

如果生命周期变为非活跃状态,它会在再次变为活跃状态时接收最新的数据。例如,曾经在后台的 Activity 会在返回前台后立即接收最新的数据。

  • 适当的配置更改

如果由于配置更改(如设备旋转)而重新创建了 Activity 或 Fragment,它会立即接收最新的可用数据。

  • 共享资源

可以使用单例模式扩展 LiveData 对象以封装系统服务,以便在应用中共享它们。LiveData 对象连接到系统服务一次,然后需要相应资源的任何观察者只需观察 LiveData 对象。

二、代码实战
1、添加依赖
  • 项目build.gradle中
allprojects {repositories {google()jcenter()}
}
  • app模块下build.gradle中
def lifecycle_version = "2.2.0"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
2、创建LiveData对象
class UserViewModel : ViewModel() {val userBean = MutableLiveData<User>()fun requestUserData() {// 协程模拟耗时100msrunBlocking {delay(100)userBean.value = User("张三", 18)}}
}data class User(var name: String, var age: Int)
3、转换LiveData
  • 通过Transformations.map进行转换
  • map操作 对存储在 LiveData 对象中的值应用函数,并将结果传播到下游
        val mNameAll = MutableLiveData<String>()// 设置数据mNameAll.postValue("张三")val mTransformMap = Transformations.map(mNameAll) { nameAll ->"$nameAll, 李四"}mTransformMap.observe(this) {Log.d("tag", "mMapData $it")// D/tag: mMapData 张三, 李四}
  • 通过Transformations.switchMap进行装换
  • switchMap 将结果解封和分派到下游。传递给 switchMap() 的函数必须返回 LiveData 对象
        val mMapUser = MutableLiveData<User>()val mSwitchMapUser = MutableLiveData<User>()val mIsMap = MutableLiveData<Boolean>()val mSwitchMapData = Transformations.switchMap(mIsMap) { mIsMap ->if (mIsMap) {mMapUser.postValue(mUser.value)mMapUser} else {mSwitchMapUser}}mSwitchMapData.observe(this) {Log.d("tag", "mSwitchMapData ${it.name}   ${it.age}")// D/tag: mSwitchMapData 李四   24}// switchMapbtnSwitchMap.setOnClickListener {mSwitchMapUser.postValue(User("李四", 24))mIsMap.postValue(false)}
4、数据合并MediatorLiveData
    val mNameOne = MutableLiveData<String>()val mNameTwo = MutableLiveData<String>()val mediatorLiveData = MediatorLiveData<String>()// 依次给mNameOne和mNameTwo设置值mNameOne.postValue("张三")mNameTwo.postValue("李四")mediatorLiveData.addSource(mNameOne) {Log.d("tag", "mNameOne $it")//  D/tag: mNameOne 张三mediatorLiveData.value = it}mediatorLiveData.addSource(mNameTwo) {Log.d("tag", "mNameTwo $it")// D/tag: mNameTwo 李四mediatorLiveData.value = it}mediatorLiveData.observe(this) {Log.d("tag", "mediatorLiveData  is $it")}
  • 打印日志如下:
// D/tag: mNameOne 张三
// D/tag: mediatorLiveData  is 张三
// D/tag: mNameTwo 李四
// D/tag: mediatorLiveData  is 李四

通过日志可以看到,因为mNameOne和mNameTwo作为mediatorLiveData的source,
mediatorLiveData可以监听到两者的值

5、Activity中使用
class LiveDataDemoActivity : AppCompatActivity() {private lateinit var userViewModel: UserViewModeloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_live_data_demo)// initViewModeluserViewModel = ViewModelProviders.of(this).get(UserViewModel::class.java)initListener()initData()}private fun initListener() {getUserData.setOnClickListener {userViewModel.requestUserData()}// 修改数据btnChange.setOnClickListener {userViewModel.userBean.postValue(User(name = "李四", age = 24))}}private fun initData() {userViewModel.userBean.observe(this, Observer {tvUserInfo.text = "名字是:${it.name},年龄是:${it.age}"})}
}
6、布局文件
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"><TextViewandroid:id="@+id/user"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="用户:"android:textColor="@android:color/black"android:textSize="16sp"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /><TextViewandroid:id="@+id/tvUserInfo"android:layout_width="wrap_content"android:layout_height="20dp"android:text="小明"android:textColor="@android:color/black"android:textSize="16sp"app:layout_constraintStart_toEndOf="@+id/user"app:layout_constraintTop_toTopOf="parent" /><Buttonandroid:id="@+id/btnChange"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginBottom="20dp"android:text="修改用户数据"app:layout_constraintBottom_toTopOf="@+id/getUserData" /><Buttonandroid:id="@+id/getUserData"android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center"android:text="获取用户数据"app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
三、参考
  • https://developer.android.google.cn/topic/libraries/architecture/livedata?hl=zh_cn
  • https://www.itranslater.com/qa/details/2583127127965041664

这篇关于LiveData从入门到实战的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/538037

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

数论入门整理(updating)

一、gcd lcm 基础中的基础,一般用来处理计算第一步什么的,分数化简之类。 LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a; } <pre name="code" class="cpp">LL lcm(LL a, LL b){LL c = gcd(a, b);return a / c * b;} 例题:

Java 创建图形用户界面(GUI)入门指南(Swing库 JFrame 类)概述

概述 基本概念 Java Swing 的架构 Java Swing 是一个为 Java 设计的 GUI 工具包,是 JAVA 基础类的一部分,基于 Java AWT 构建,提供了一系列轻量级、可定制的图形用户界面(GUI)组件。 与 AWT 相比,Swing 提供了许多比 AWT 更好的屏幕显示元素,更加灵活和可定制,具有更好的跨平台性能。 组件和容器 Java Swing 提供了许多

【IPV6从入门到起飞】5-1 IPV6+Home Assistant(搭建基本环境)

【IPV6从入门到起飞】5-1 IPV6+Home Assistant #搭建基本环境 1 背景2 docker下载 hass3 创建容器4 浏览器访问 hass5 手机APP远程访问hass6 更多玩法 1 背景 既然电脑可以IPV6入站,手机流量可以访问IPV6网络的服务,为什么不在电脑搭建Home Assistant(hass),来控制你的设备呢?@智能家居 @万物互联

滚雪球学Java(87):Java事务处理:JDBC的ACID属性与实战技巧!真有两下子!

咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java SE啦,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好习惯,别被干货淹没了哦~ 🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎大家关注&&收藏!持续更新中,up!up!up!! 环境说明:Windows 10

poj 2104 and hdu 2665 划分树模板入门题

题意: 给一个数组n(1e5)个数,给一个范围(fr, to, k),求这个范围中第k大的数。 解析: 划分树入门。 bing神的模板。 坑爹的地方是把-l 看成了-1........ 一直re。 代码: poj 2104: #include <iostream>#include <cstdio>#include <cstdlib>#include <al

MySQL-CRUD入门1

文章目录 认识配置文件client节点mysql节点mysqld节点 数据的添加(Create)添加一行数据添加多行数据两种添加数据的效率对比 数据的查询(Retrieve)全列查询指定列查询查询中带有表达式关于字面量关于as重命名 临时表引入distinct去重order by 排序关于NULL 认识配置文件 在我们的MySQL服务安装好了之后, 会有一个配置文件, 也就