什么是 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());
});
}
}
  1. 实例化 TimePickerFragment,构造日期选择器;
  2. 获取 TimePickerViewModel 对象,并观察数据是否发生变化;
  3. 如果数据发生变化,就把最新的日期显示到 TextView 上。

GitHub 仓库地址:Chap02-ViewModel

Android:ViewModel的更多相关文章

  1. Android:让WebView支持<input type=”file”…>元素

    最近在做一个活动页面:用户上传一张图片进行缩放.旋转后点击下一步填写内容后生成图片! 做好后经过各种测试是没有问题的,基本没有什么明显BUG,流程都能走通,但是嵌入到APP后,问题就来了! 在IOS上 ...

  2. android:ToolBar详解

    android:ToolBar详解(手把手教程) 泡在网上的日子 发表于 2014-11-18 12:49 第 124857 次阅读 ToolBar 42 来源 http://blog.mosil.b ...

  3. Android:学习AIDL,这一篇文章就够了(下)

    前言 上一篇博文介绍了关于AIDL是什么,为什么我们需要AIDL,AIDL的语法以及如何使用AIDL等方面的知识,这一篇博文将顺着上一篇的思路往下走,接着介绍关于AIDL的一些更加深入的知识.强烈建议 ...

  4. cocos2d-x for android:SimpleGame分析

    cocos2d-x for android:SimpleGame分析 作为cocos2d-x的标配DEMO,SimpleGame可算是给入门学cocos2d-x的俺们这些新手门学习的对象了,那么来分析 ...

  5. Android:布局实例之模仿微信Tab

    微信Tab预览效果: 思路: 1.用TabHost+RadioGroup搭建基本布局,以RadioGroup代替TabWidget 2.设置按钮和文字的的样式和selector 3.创建相应的Acti ...

  6. Android:什么是Holo?【Translated By KillerLegend】

    Android:什么是Holo? Martin Brinkmann on May 6, 2013 in Google Android 3 [Translated By KillerLegend] 当你 ...

  7. Android:AlertDialog对话框

    1.简单的ALertDialog: Dialog alertDialog = new AlertDialog.Builder(this) .setTitle("标题") .setM ...

  8. Android:数据存储之SQLite

    Android在运行时集成了SQLite , 所以每个Android应用程序都可以使用SQLite数据库. 我们通过SQLiteDatabase这个类的对象操作SQLite数据库,而且不需要身份验证. ...

  9. Android:设计之屏幕适配

    据统计目前市场Android手机的分辨率有是10余种,分辨率如此广泛使得我们在处理分辨率适应方便遇到不少难题,本文就此难点记录设计与实际布局中的解决技巧. 以320x480为蓝本设计布局 因为Andr ...

  10. Android:PopupWindow简单弹窗改进版

    Android:PopupWindow简单弹窗 继续上一节的内容,改进一下,目标是点击菜单后把菜单收缩回去并且切换内容,我使用的是PopupWindow+RadioGroup public class ...

随机推荐

  1. 2.6:Python数据存取-文件、文件夹及目录、数据库

    一.Python文件读写 1.文件的打开模式 <class '_io.TextIOWrapper'>和<class '_io.BufferedReader'>.python使用 ...

  2. 【Shell案例】【打印指定行用sed、for循环、head和tail配合使用】4、输出第5行的内容

    描述写一个 bash脚本以输出一个文本文件 nowcoder.txt 中第5行的内容. 示例:假设 nowcoder.txt 内容如下:welcometonowcoderthisisshellcode ...

  3. Spring 6 源码编译和高效阅读源码技巧分享

    一. 前言 Spring Boot 3 RELEASE版本于 2022年11月24日 正式发布,相信已经有不少同学开始准备新版本的学习了,不过目前还不建议在实际项目中做升级,毕竟还有很多框架和中间件没 ...

  4. ExcelToObject.NPOI 两行代码导出Excel报表、读取Excel数据

    简介 作为一个dotnet开发者,经常面对业务系统中大量报表导入导出,经常写了一堆的重复代码.最近发现一个操作excel的神器:ExcelToObject.NPOI,两行代码就能导出一个报表,两行代码 ...

  5. openresty package path

    openresty lua_package_path 是整个openresty最基础的功能,不理解 path就无法做项目,更无法写框架. 先看下文档lua_package_path https://g ...

  6. 搭建漏洞环境及实战——在Linux系统中安装LANMP

    LANMP是Linux下Apache.Nginx.mysql和php的应用环境 演示的是WDLinux 命令:wget http://dl.wdlinux.cn/files/lamp_v3.tar.g ...

  7. a标签跳新链接,如果链接为空则不跳转

    a标签跳新链接,如果链接为空则不跳转 <el-carousel-item v-for="item in slideList" :key="item.id" ...

  8. Linux基础第一章 概述

    第一章 概述 1.1 前言 本章讨论系统的概念,从硬件.操作系统角度更加深刻的理解计算机系统,并快速浏览Linux系统提供的服务. 1.2 系统组成     1.3 操作系统和应用程序 操作系统这个词 ...

  9. [深度学习]DEEP LEARNING(深度学习)学习笔记整理

    转载于博客http://blog.csdn.net/zouxy09 一.概述 Artificial Intelligence,也就是人工智能,就像长生不老和星际漫游一样,是人类最美好的梦想之中的一个. ...

  10. 突如其来的&amp;quot;中断异常&amp;quot;,我(Java)该如何处理?

    # **一.何为异常?** ## 1.生活中的实例 生活中存在许多不正常: 上班路上自行车掉链子 上厕所手机掉马桶 下班回家钥匙丢失 ....... 2.程序中的实例 我们的代码中也许存在许多纰漏,导 ...