Android:ViewModel
什么是 ViewModel
ViewModel 旨在以注重生命周期的方式存储和管理界面相关数据。ViewModel 让数据可在发生屏幕旋转等配置更改后继续留存。
上面一段话是截取自官方文档对 ViewModel 的定义。ViewModel 是管理、存储数据的,并且屏幕发生旋转等行为之后,数据依旧保留。
ViewModel 的生命周期
学习 ViewModel 也必须要了解它到底能存活多久?下图可知,ViewModel 会从 Activity 创建之初,直到这个 Activity 被销毁为止。

ViewModel 使用场景
使用过 Vue 框架的人肯定有 VueX(Pinia)——状态管理的使用经验,组件与组件之间可以层层往下传递数据,而有时候子组件往上传递数据也有些麻烦,倒不如使用状态管理,也就是说,把这些共用的数据放在一个“地方”,让所有组件都可以访问到的一个容器。
其实,ViewModel 也可以这样来理解。一定要清楚,一个 Activity 就是一个页面,页面与页面之间不可能通过 ViewModel 来共享数据,使用场景比如:日期选择器(Fragment)选择完之后,日期数据要返回到 Activity 页面上,这个时候就可以借助于 ViewModel 来做。ViewModel 相当于 Activity 与 Fragment 之间的通信桥梁。
创建 ViewModel 类
实现一个继承 ViewModel 的子类:TimePickerViewModel。里面只来存储日期选择器选择之后保存的日期数据,类型为 MutableLiveData,其泛型是 String。在获取这个 dateValue 之前,要做一个非空判断。设置日期数据必须要调用 MutableLiveData 提供的setValue,否则不起效果。
public class TimePickerViewModel extends ViewModel {
private MutableLiveData<String> dateValue;
public LiveData<String> getDateValue() {
if (dateValue == null) {
dateValue = new MutableLiveData<>();
}
return dateValue;
}
public void setDateValue(String dateValue) {
this.dateValue.setValue(dateValue);
}
}
UI 界面
<TextView
android:id="@+id/time_picker_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="未选择日期" />
<TextView
android:id="@+id/time_picker_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="选择日期" />
点击选择日期文本之后,触发点击事件,打开日期选择器。下面是点击文本之后,日期选择器的代码:
public class TimePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener {
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
final Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH);
int day = c.get(Calendar.DAY_OF_MONTH);
return new DatePickerDialog(getActivity(), this, year, month + 1, day);
}
@Override
public void onDateSet(DatePicker datePicker, int i, int i1, int i2) {
TimePickerViewModel vm = new ViewModelProvider(requireActivity()).get(TimePickerViewModel.class);
vm.setDateValue(i + "-" + i1 + "-" + i2);
}
}
当选择日期成功之后,触发onDateSet,该函数中调用 ViewModelProvider 以修改 TimePickerViewModel 的字段。ViewModelProvider 需要获取 Activity 的实例,可以通过requireActivity()或者getActivity()来获取。
MainActivity
MainActivity 实现 OnClickListener 接口,这样做的好处就是添加多个事件监听都不需要 new OnClickListener 接口,直接给 setOnClickListener() 函数提供 this:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.time_picker_btn).setOnClickListener(this);
}
@Override
public void onClick(View view) {
// 1. 实例化 TimePickerFragment
TimePickerFragment timePicker = new TimePickerFragment();
// 2. 显示日期选择器
timePicker.show(getSupportFragmentManager(), "datePicker");
// 3. 获取 TextView,展示的数据放在这里
TextView textview = findViewById(R.id.time_picker_text);
// 4. 观察 ViewModel 数据变化以更新 UI
TimePickerViewModel timePickerVM = new ViewModelProvider(this).get(TimePickerViewModel.class);
// 5. 观察数据变化
timePickerVM.getDateValue().observe(this, e -> {
// 6. 数据变化,把新的日期展示到 TextView 中
textview.setText(timePickerVM.getDateValue().getValue());
});
}
}
- 实例化 TimePickerFragment,构造日期选择器;
- 获取 TimePickerViewModel 对象,并观察数据是否发生变化;
- 如果数据发生变化,就把最新的日期显示到 TextView 上。

GitHub 仓库地址:Chap02-ViewModel
Android:ViewModel的更多相关文章
- Android:让WebView支持<input type=”file”…>元素
最近在做一个活动页面:用户上传一张图片进行缩放.旋转后点击下一步填写内容后生成图片! 做好后经过各种测试是没有问题的,基本没有什么明显BUG,流程都能走通,但是嵌入到APP后,问题就来了! 在IOS上 ...
- android:ToolBar详解
android:ToolBar详解(手把手教程) 泡在网上的日子 发表于 2014-11-18 12:49 第 124857 次阅读 ToolBar 42 来源 http://blog.mosil.b ...
- Android:学习AIDL,这一篇文章就够了(下)
前言 上一篇博文介绍了关于AIDL是什么,为什么我们需要AIDL,AIDL的语法以及如何使用AIDL等方面的知识,这一篇博文将顺着上一篇的思路往下走,接着介绍关于AIDL的一些更加深入的知识.强烈建议 ...
- cocos2d-x for android:SimpleGame分析
cocos2d-x for android:SimpleGame分析 作为cocos2d-x的标配DEMO,SimpleGame可算是给入门学cocos2d-x的俺们这些新手门学习的对象了,那么来分析 ...
- Android:布局实例之模仿微信Tab
微信Tab预览效果: 思路: 1.用TabHost+RadioGroup搭建基本布局,以RadioGroup代替TabWidget 2.设置按钮和文字的的样式和selector 3.创建相应的Acti ...
- Android:什么是Holo?【Translated By KillerLegend】
Android:什么是Holo? Martin Brinkmann on May 6, 2013 in Google Android 3 [Translated By KillerLegend] 当你 ...
- Android:AlertDialog对话框
1.简单的ALertDialog: Dialog alertDialog = new AlertDialog.Builder(this) .setTitle("标题") .setM ...
- Android:数据存储之SQLite
Android在运行时集成了SQLite , 所以每个Android应用程序都可以使用SQLite数据库. 我们通过SQLiteDatabase这个类的对象操作SQLite数据库,而且不需要身份验证. ...
- Android:设计之屏幕适配
据统计目前市场Android手机的分辨率有是10余种,分辨率如此广泛使得我们在处理分辨率适应方便遇到不少难题,本文就此难点记录设计与实际布局中的解决技巧. 以320x480为蓝本设计布局 因为Andr ...
- Android:PopupWindow简单弹窗改进版
Android:PopupWindow简单弹窗 继续上一节的内容,改进一下,目标是点击菜单后把菜单收缩回去并且切换内容,我使用的是PopupWindow+RadioGroup public class ...
随机推荐
- 【JUC】信号量Semaphore详解
欢迎关注专栏[JAVA并发] 欢迎关注个人公众号-- JAVA旭阳 前言 大家应该都用过synchronized 关键字加锁,用来保证某个时刻只允许一个线程运行.那么如果控制某个时刻允许指定数量的线程 ...
- 记一次 .NET 某工控软件 内存泄露分析
一:背景 1.讲故事 上个月 .NET调试训练营 里的一位老朋友给我发了一个 8G 的dump文件,说他的程序内存泄露了,一时也没找出来是哪里的问题,让我帮忙看下到底是怎么回事,毕竟有了一些调试功底也 ...
- Doris安装部署
下载安装 Doris运行在Linux环境中,推荐 CentOS 7.x 或者 Ubuntu 16.04 以上版本,同时你需要安装 Java 运行环境(JDK最低版本要求是8) 1.下载安装包 下载地址 ...
- 天坑,这样一个lambda随机取数据也有Bug
前几天,一位网友跟我说他编写的一段很简单的代码遇到了奇怪的Bug,他要达到的效果是从一个List中随机取出来一条数据,代码如下: 1 var random = new Random(); 2 var ...
- 为什么Git远程仓库中要配置公钥?
最近在使用阿里云效平台代码管理,首次使用新建仓库,使用SSH时需要配置公钥.之前也在GitHub.Gitee上配置过,每次都能正常使用,也没有思考过为什么要配置公钥.这次记录一下其中的原理. 本地和远 ...
- 下载Font Awesome框架
目录 一:下载Font Awesome框架 二:如何使用font awesome 1.使用图标等样式,点击复制标签即可,需要嵌套在i标签内 2.点击图标,复制标签,然后粘贴使用即可. 3.动态图片等 ...
- Jmeter 逻辑控制器之吞吐量控制器(Throughput Controller)
吞吐量控制器(Throughput Controller)用来控制其下元件的执行次数,并无控制吞吐量的功能,想要控制吞吐量可以用Constant Throughput Timer,吞吐量控制器有两种模 ...
- 【深入浅出 Yarn 架构与实现】4-3 RM 管理 NodeManager
本篇继续对 RM 中管理 NodeManager 的部分进行深入的讲解.主要有三个部分:检查 NM 是否存活:管理 NM 的黑白名单:响应 NM RPC 请求. 一.简介 在 RM 的主从结构中,最主 ...
- 百度智能云 API调用PythonSDK
百度智能云 API调用PythonSDK 这是一个用于百度云部分开放AI功能的Python库.主要为ORC功能,可以对各种图像文件进行文字识别,包括车牌.手写文字.通用文字.人脸发现.人脸比对和人流量 ...
- Hive详解(01) - 概念
Hive详解(01) - 概念 hive简介 Hive:由Facebook开源用于解决海量结构化日志的数据统计工具,是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提供类S ...