什么是 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. CyclicBarrier循环屏障源码解析(基于jdk11)

    目录 CyclicBarrier循环屏障源码解析(基于jdk11) 1.1 CyclicBarrier概述 1.2 CyclicBarrier原理 1.2.1 基本结构(jdk11) 1.2.2 aw ...

  2. 什么是NineData?突然就火了

    NineData 是集成了 SQL 开发.数据复制.数据备份.数据对比多个模块的云服务,支持混合云(自建库+云数据库的业务架构)和多云(多个不同云厂商数据库组成的业务架构)架构下的企业数据管理,大幅降 ...

  3. 云数据库FinOps实战复盘

    历时三个多月的HBase成本优化项目按照预期交付了,HBase云数据库月度成本下降了32.5%,超出预期达成目标. 我们对本次HBase成本优化项目进行深度复盘,并进一步尝试总结云数据库的FinOps ...

  4. Python全栈工程师之从网页搭建入门到Flask全栈项目实战(5) - Flask中的ORM使用

    1.理解ORM ORM是MTV模型里面的Model模型 ORM(Object Relational Mapping),对象关系映射 举例:学生选课 学生和课程这两个实体,一个学生可以选择多门课程,一个 ...

  5. 自研分布式高性能RPC框架及服务注册中心实践笔记【原创】【开源】

    痛点 1. bsf底层依赖springcloud,影响bsf更新springboot新版本和整体最新技术版本升级. 2. eureka已经闭源,且框架设计较重,同时引入eureka会自行引入较多spr ...

  6. 第二章 --------------------XAML基础

    1.XAML是什么? XAML是扩展标记语言,是为了方便设计人员设计UI界面.具体关于XAML语法的讲解参考其他相关书籍.  XAML每一个标签以<>开头,以</>结尾,作为标 ...

  7. [编程基础] Python命令行解析库argparse学习笔记

    Python argparse教程展示了如何使用argparse模块解析Python中的命令行参数. 文章目录 1 使用说明 1.1 Python argparse可选参数 1.2 Python ar ...

  8. MongoDB - 分片简介

    简介 什么是分片 高数据量和高吞吐量的数据库应用会对单机的性能造成较大压力,大的查询会将单机的 CPU 耗尽,大的数据量对单机的存储压力较大,最终会耗尽系统的内存压力转移到磁盘 IO 上. 为了解决这 ...

  9. [C#]C++/CLI中interior_ptr和pin_ptr的区别

    interior_ptr 当垃圾回收器移动对象时,Interior pointer能随之移动,并始终指向该对象. 但是如果把这个指针返回给外部函数,那么当垃圾回收时(垃圾回收期间会压缩对象,),对象地 ...

  10. Hugging Face 2023 实习生招募计划

    Hugging Face 2023 实习生招募计划 想参与到 <王婆卖瓜>「最酷的 AI 社区」</王婆卖瓜>,共同构建未来吗?今天,我们为大家分享 Hugging Face ...