【Jetpack】LiveData 架构组件 ( LiveData 简介 | LiveData 使用方法 | ViewModel + LiveData 示例 )

article/2025/11/11 4:33:28

文章目录

  • 一、LiveData 简介
  • 二、LiveData 使用方法
  • 三、ViewModel + LiveData 简单示例
    • 1、ViewModel + LiveData 代码
    • 2、Activity 组件代码
    • 3、运行效果展示
  • 四、ViewModel + LiveData + Fragment 通信示例
    • 1、ViewModel + LiveData 代码
    • 2、Activity 组件代码
      • Activity 代码
      • 布局文件
    • 3、Fragment 代码
      • 第一个 Fragment 代码
      • 第一个 Fragment 布局文件
      • 第二个 Fragment 代码
      • 第二个 Fragment 布局文件
    • 4、运行效果展示





一、LiveData 简介



视图 View数据模型 Model 通过 ViewModel 架构组件 进行绑定后 , 可以立即 将 ViewModel 中的数据设置到 UI 界面中 ,

运行过程中 , 在 UI 界面中 , 可以 修改 ViewModel 中的值 , 并 将新的值设置在 视图 View 中 ;

但是 , 如果 数据是在 ViewModel 中发生的改变 , 那么如何 通知 UI 来进行 视图 View 的更新 操作呢 ?

这里引入 LiveData 架构组件 , 在 ViewModel 中 , 可以 通过 LiveData 将数据修改的信息发送给 视图 View , 通知 UI 界面进行修改 ;

在这里插入图片描述

场景举例 :ViewModel 中申请 HTTP 服务器数据 , 请求发送后 , 不知道什么时候才能获得响应 , 如果 过一段时间服务器才反馈响应数据 , 此时只能 通过 LiveData 将 ViewModel 的数据修改通知给 视图 View ;





二、LiveData 使用方法



首先 ,ViewModel 视图模型 中定义 LiveData 数据 , 如 MutableLiveData<T> ,

class MyViewModel: ViewModel {var second: MutableLiveData<Int> = MutableLiveData<Int>()constructor() {second.value = 0}
}

在该类中提供了 postValuesetValue 两个函数 ,

  • UI 主线程 中调用 setValue 函数 ,
  • 非 UI 线程的子线程 中调用 postValue 函数 更新数据 ;
public class MutableLiveData<T> extends LiveData<T> {@Overridepublic void postValue(T value) @Overridepublic void setValue(T value)
}

然后 , 在 Activity 组件中 , 调用 LiveData#observe 函数 , 添加数据变化监听器 androidx.lifecycle.Observer<T> , 一旦 LiveData 数据发生了改变 , 就会 回调 Observer 监听器中的 onChanged 函数 ;

// 设置 LiveData 监听
myViewModel.second.observe(this, object : androidx.lifecycle.Observer<Int> {override fun onChanged(t: Int?) {// 将 ViewModel 中的数据设置到 视图 View 组件中textView.setText("${myViewModel.second.value}")}
})




三、ViewModel + LiveData 简单示例



设置一个定时器 , 定时更新数据 , 在 ViewModel 中数据发生了改变 , 需要 主动通知 视图 View 进行修改 ;

使用 传统的开发方式 , 可以使用 线程通信 , Handler 或者 广播 等形式 , 在子线程中通知主线程更新 UI ;

使用 LiveData 后 , 将数据定义在 LiveData 中 , 然后在 Activity 中 为 LiveData 添加 Observer 监听器 , 当 LiveData 数据发生改变时 , 会自动回调该监听器的 onChange 方法 ;


1、ViewModel + LiveData 代码


自定义 ViewModel 子类继承 ViewModel , 在 ViewModel 中 , 定义 LiveData 类型的数据 , 此处选择使用 MutableLiveData<Int> 数据类型 , 维护一个 Int 类型的数据 , 当该 Int 值发生改变时 , 会触发 LiveData 设置的 Observer 监听器 ;

package kim.hsl.livedatademoimport androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModelclass MyViewModel: ViewModel {var second: MutableLiveData<Int> = MutableLiveData<Int>()constructor() {second.value = 0}
}

2、Activity 组件代码


在 Activity 系统组件中 , 绑定 ViewModel , 从 ViewModel 中获取 LiveData 显示到 UI 界面中 , 并为该 LiveData 设置 Observer 监听器 , 监听 LiveData 的数据变化 ;

启动 Timer 定时器 , 修改 ViewModel 中的 LiveData 数据 , 在 LiveData 数据发生改变时 , 会自动回调 Observer 监听器的 onChanged 函数 ;

package kim.hsl.livedatademoimport androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView
import androidx.lifecycle.ViewModelProvider
import java.util.*class MainActivity : AppCompatActivity() {lateinit var textView: TextViewlateinit var myViewModel: MyViewModeloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)// 获取 视图 View 组件textView = findViewById(R.id.textView)// 获取 ViewModelmyViewModel = ViewModelProvider(this,ViewModelProvider.AndroidViewModelFactory(application)).get(MyViewModel::class.java)// 将 ViewModel 中的数据设置到 视图 View 组件中textView.setText("${myViewModel.second.value}")// 设置 LiveData 监听myViewModel.second.observe(this, object : androidx.lifecycle.Observer<Int> {override fun onChanged(t: Int?) {// 将 ViewModel 中的数据设置到 视图 View 组件中textView.setText("${myViewModel.second.value}")}})// 启动定时器, 将 ViewModel 中的数据自增startTimer()}fun startTimer() {Timer().schedule(object : TimerTask(){override fun run() {// 获取 ViewModel 中的数据var second: Int? = myViewModel.second.value// 将 ViewModel 中的数据自增 1myViewModel.second.postValue(second?.plus(1))}}, 1000, 1000)}
}

3、运行效果展示


应用启动后 , 在界面中启动定时器 , 对 ViewModel 中的 LiveData 数据进行累加 , LiveData 设置了 Observer 监听 , 数据改变时回调 Observer#onChanged 函数更新 UI 显示 ;

执行时切换屏幕方向 , 不影响数据累加显示 ;

请添加图片描述





四、ViewModel + LiveData + Fragment 通信示例



在 Activity 系统组件中 设置两个 Fragment , 两个 Fragment 之间通过 ViewModel + LiveData 进行通信 ;

在其中一个 Fragment 中设置 SeekBar 拖动条 , 将数值设置到另外一个 Fragment 中的 TextView 中显示 ;


1、ViewModel + LiveData 代码


自定义 ViewModel 子类继承 ViewModel , 在 ViewModel 中 , 定义 LiveData 类型的数据 , 此处选择使用 MutableLiveData<Int> 数据类型 , 维护一个 Int 类型的数据 , 当该 Int 值发生改变时 , 会触发 LiveData 设置的 Observer 监听器 ;

package kim.hsl.livedatademoimport androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModelclass MyViewModel: ViewModel {var progress: MutableLiveData<Int> = MutableLiveData<Int>()constructor() {progress.value = 0}
}

2、Activity 组件代码


在该 Activity 组件中 , 维护了两个 Fragment , 两个 Fragment 之间借助 ViewModel + LiveData 进行通信 ;

Activity 代码

package kim.hsl.livedatademoimport android.os.Bundle
import androidx.appcompat.app.AppCompatActivityclass MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)}
}

布局文件

在 Activity 中设置了两个 Fragment , 它们之间借助 ViewModel + LiveData 进行通信 ;

<?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"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><androidx.constraintlayout.widget.Guidelineandroid:id="@+id/guideline"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal"app:layout_constraintGuide_percent="0.5" /><androidx.fragment.app.FragmentContainerViewandroid:id="@+id/fragmentContainerView1"android:name="kim.hsl.livedatademo.Fragment1"android:layout_width="0dp"android:layout_height="0dp"app:layout_constraintBottom_toTopOf="@+id/guideline"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /><androidx.fragment.app.FragmentContainerViewandroid:id="@+id/fragmentContainerView2"android:name="kim.hsl.livedatademo.Fragment2"android:layout_width="0dp"android:layout_height="0dp"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="@+id/guideline" /></androidx.constraintlayout.widget.ConstraintLayout>

3、Fragment 代码


在该 Activity 组件中 , 维护了两个 Fragment , 两个 Fragment 之间借助 ViewModel + LiveData 进行通信 ;

第一个 Fragment 代码

先将 ViewModel 中的 LiveData 数据中的 进度值设置给 SeekBar ,

目的是为了在屏幕旋转时 , 可随时恢复数据 ;

在 SeekBar 的拖动数据中 , 修改 ViewModel 中的 LiveData 数据 ,

当数据修改时 , 对应的 Fragment2 中的 TextView 会刷新显示新的数据 ;

package kim.hsl.livedatademoimport android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.SeekBar
import android.widget.SeekBar.OnSeekBarChangeListener
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProviderclass Fragment1: Fragment() {override fun onCreateView(inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?): View? {// 设置布局val root: View = inflater.inflate(R.layout.fragment1, container, false)// 获取拖动条var seekBar: SeekBar = root.findViewById(R.id.seekBar)// 获取 ViewModelvar viewModel: MyViewModel = ViewModelProvider(requireActivity(),ViewModelProvider.AndroidViewModelFactory(requireActivity().application)).get(MyViewModel::class.java)seekBar.progress = viewModel.progress.value!!// 设置进度条拖动事件seekBar.setOnSeekBarChangeListener(object : OnSeekBarChangeListener{override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {viewModel.progress.value = progress}override fun onStartTrackingTouch(seekBar: SeekBar) {}override fun onStopTrackingTouch(seekBar: SeekBar) {}})return root}
}

第一个 Fragment 布局文件

Fragment1 中维护了一个 SeekBar 拖动条组件 ;

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><SeekBarandroid:id="@+id/seekBar"android:layout_width="0dp"android:layout_height="wrap_content"android:max="100"android:min="0"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /></androidx.constraintlayout.widget.ConstraintLayout>

第二个 Fragment 代码

在 Fragment2 中 , 只放了一个 TextView 组件 , 该组件显示的是 ViewModel 中的 LiveData 数据 , 当该 LiveData 数据发生改变时 , 对应 TextView 显示也随之更新 ;

package kim.hsl.livedatademoimport android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProviderclass Fragment2: Fragment() {override fun onCreateView(inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?): View? {// 设置布局val root: View = inflater.inflate(R.layout.fragment2, container, false)// 获取文本组件val textView: TextView = root.findViewById(R.id.textView)// 获取 ViewModelvar viewModel: MyViewModel = ViewModelProvider(requireActivity(),ViewModelProvider.AndroidViewModelFactory(requireActivity().application)).get(MyViewModel::class.java)// 设置文本显示内容textView.setText("${viewModel.progress.value}")// 设置 LiveData 监听viewModel.progress.observe(requireActivity(), object : androidx.lifecycle.Observer<Int> {override fun onChanged(t: Int) {textView.setText("${viewModel.progress.value}")}})return root}
}

第二个 Fragment 布局文件

Fragment2 中维护了 TextView 组件 ;

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><TextViewandroid:id="@+id/textView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="0"android:textSize="50sp"android:textColor="@color/black"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /></androidx.constraintlayout.widget.ConstraintLayout>

4、运行效果展示


拖动 Fragment1 中的进度条 , 将进度条的进度 在 Fragment2 中的 TextView 中显示 , 并且横竖屏切换时 , 数据没有丢失 ;

请添加图片描述


博客代码 :

  • CSDN 下载 : https://download.csdn.net/download/han1202012/87567750

http://chatgpt.dhexx.cn/article/PNRi0tDd.shtml

相关文章

LiveData详细分析

目录介绍 01.LiveData是什么东西02.使用LiveData的优势03.使用LiveData的步骤04.简单使用LiveData05.observe()和observerForever()06.LiveData原理介绍07.observe订阅源码分析08.setValue发送源码分析09.observeForever源码10.LiveData源码总结 00.使用LiveData实现bus事件总…

LiveData+Room

文章目录 LiveData1.LiveData的作用2.LiveData的特点3.LiveData与ViewModel(无参数)的结合4.LiveData与ViewModel(有参数)的结合5.map()和switchMap()5.0 map()和switchMap()的作用5.1map()5.11没带ViewModel版5.12带ViewModel版 5.2switchMap() Room1.Room的定义2.Room的三个组…

Android架构组件(二)——LiveData

Android架构组件&#xff08;二&#xff09;——LiveData 上一篇文章讲到了Android架构组件之一Lifecycle组件&#xff08;Android 架构组件&#xff08;一&#xff09;——Lifecycle-Aware Components&#xff0c;现在我们再来看看另一个成员LiveData。 定义 简单地说&#xf…

Android LiveData 使用详解

说在前面 本次推出 Android Architecture Components 系列文章&#xff0c;目前写好了四篇&#xff0c;主要是关于 lifecycle&#xff0c;livedata 的使用和源码分析&#xff0c;其余的 Navigation&#xff0c; Paging library&#xff0c;Room&#xff0c;WorkMannager 等春节…

由浅入深,详解 LiveData 的那些事

引言 关于LiveData,在2022尾声的今天&#xff0c;从事 Android 开发的小伙伴一定不会陌生。相应的&#xff0c;关于 LiveData 解析与使用的文章更是数不胜数&#xff0c;其中不乏优秀的创作者&#xff0c;在众多的文章以及前辈面前&#xff0c;本篇也不敢妄谈能写的多么深入,易…

LiveData的原理和使用

LiveData Livedata是什么&#xff1f;它的作用是什么&#xff1f;我们能用它来干什么&#xff1f; 首先&#xff0c;LiveData是一种可观察的数据存储类。这句话可以看成两个部分&#xff0c;一个是可观察的类&#xff0c;另一个是数据存储的类。 LiveData 是可以被观察的&am…

python电子书合集

Python电子书合集 小编最早接触的编程语言是C&#xff0c;决心走上编程之路的是JavaScript&#xff0c;后来入职靠的Java&#xff0c;后来发现还有一门短小精悍的语言叫——Python。 本来以为是一门新语言&#xff0c;结果才发现是自己out了&#xff0c;没想到这门语言比小编还…

《Python Cookbook》(中文第三版):电子书

《Python Cookbook&#xff08;第3版&#xff09;中文版》介绍了Python应用在各个领域中的一些使用技巧和方法&#xff0c;其主题涵盖了数据结构和算法&#xff0c;字符串和文本&#xff0c;数字、日期和时间&#xff0c;迭代器和生成器&#xff0c;文件和I/O&#xff0c;数据编…

python编程入门电子书-《Python编程 从入门到实践》高清电子书免费下载

今天给大家分享一本书 获取方式 公众号后台回复 Python基础 获取百度网盘下载链接 书籍简介 本书旨在让你成为优秀的程序员&#xff0c;具体地说&#xff0c;是优秀的Python程序员。通过阅读本书&#xff0c;你将迅速掌握编程概念&#xff0c;打下坚实的基础&#xff0c;并…

【小沐学Python】Python实现在线电子书制作(MkDocs + readthedocs + github + Markdown)

文章目录 1、简介2、安装3、创建新项目4、添加页面5、编辑导航页6、设置主题7、更改图标图标8、构建网站9、部署9.1 准备github项目9.2 注册登录Read the Docs9.3 导入github项目到 Read the Docs 10、Markdown语法10.1 横线10.2 标题10.3 段落10.4 文字高亮10.5 换行10.6 斜体…

超全的Python完全版电子书——从基础到爬虫、分析等高级应用,限时下载

python3.11即将于下半年发布&#xff0c;新的版本速度提升2倍&#xff0c;以弥补与其他编程语言在速度上的缺陷。可以预见Python语言在未来的应用范围会越来越广。 python学习方向建议&#xff1a; 如果你是本科及以下学历&#xff0c;建议你学习以下两个方向 1、爬虫。简单的…

【小沐学Python】Python实现在线电子书制作(Sphinx + readthedocs + github + Markdown)

文章目录 1、简介2、安装3、创建测试工程4、项目文件结构5、编译为本地文件6、编译为http服务7、更改样式主题8、支持markdown9、修改文档显示结构10、项目托管到github11、部署到ReadtheDocs结语 1、简介 Sphinx 是一个 文档生成器 &#xff0c;您也可以把它看成一种工具&…

python编程入门电子书-Python3零基础教材电子书合集

Python3零基础教材电子书合集&#xff0c;传送门&#xff1a;https://www.52pojie.cn/thread-676318-1-1.html 一、《Python编程从入门到实践》 链接&#xff1a;https://pan.baidu.com/s/1o9wJq0y 密码&#xff1a;12od 这书楼主现在也在看&#xff0c;讲的很细&#xff0c;…

学习Python必看的经典书籍(附电子书)

哈喽&#xff0c;我是牙儿 今天给大家推荐几本经典的Python书籍 一起来看看都有哪些吧~ 1 《Python学习手册&#xff08;第4版&#xff09;》 这本书全面、深入地介绍了 Python 语言&#xff0c;不管你是编程新手还是 Python 初学者&#xff0c;它将帮助你快速实现使用 Pyt…

超全的Python完全版电子书.pdf !从基础到爬虫、分析等高级应用,限时下载

python3.11即将于下半年发布&#xff0c;新的版本速度提升2倍&#xff0c;以弥补与其他编程语言在速度上的缺陷。可以预见Python语言在未来的应用范围会越来越广。 python学习方向建议&#xff1a; 如果你是本科及以下学历&#xff0c;建议你学习以下两个方向 1、爬虫。简单…

python入门经典电子书-推荐6本学习Python的免费电子书

便宜并不是没好货&#xff0c;这里的一些书籍已经被很多大学作为课本来使用&#xff0c;比如麻省理工的计算机科学与编程入门课程&#xff0c;加利福尼亚大学的编程思想课程都用到了下面的某(几)本书籍。 简明 简明 Python 教程是Swaroop C.H. 教授为Python初学者写的一本书。…

Python 开源电子书资源

转载自公众号&#xff1a;Mocun6 昨天给大伙儿送了书&#xff0c;留言区的篇幅占了整篇文章的一半&#xff0c;看来大家都想好&#xff08;把&#xff09;好&#xff08;我&#xff09;学&#xff08;掏&#xff09;习&#xff08;空&#xff09;。今天不送纸质书了&#xff0c…

100多本python书,免费电子版下载

推荐&#xff1a; 1、Coffee Break Python Slicing: 24 Workouts to Master Slicing in Python, Once and for All 切片&#xff08;Slicing&#xff09;是 Python 里非常有用的一个功能&#xff0c;属于 Python 开发人员最基本的技能之一。 如果你是初学者而且想了解 Slicin…

学习 Python 必看的书单(附电子书链接)

本文为你分享入门Python的必读书单。 学 Python 看什么书&#xff1f; 这是刚接触 Python 的朋友最疑惑的问题。 今天就结合自己入门时的学习历程和大家来聊一聊如何入门 Python&#xff0c;为了更有说服性一些&#xff0c;这里我把入门时看过的一些大佬推荐的书单进行了汇总…

python入门电子版-Python3零基础教材电子书合集

Python3零基础教材电子书合集,传送门:https://www.52pojie.cn/thread-676318-1-1.html 一、《Python编程从入门到实践》 链接:https://pan.baidu.com/s/1o9wJq0y 密码:12od 这书楼主现在也在看,讲的很细,建议大家零基础的从这书开始最好。个人觉得比《简明python教程》…