ViewModel的基本使用

目录

  • 一、基本使用
  • 二、ViewModel + DataBinding + LiveData结合使用
    • 1. java版本
    • 2. kotlin版本

一、基本使用

MyViewModel.kt

package com.example.myviewmodelimport androidx.lifecycle.ViewModelclass MyViewModel : ViewModel() {// 数据放这 进行横竖屏切换不会丢失var number : Int = 0
}

MainActivity.kt

package com.example.myviewmodelimport androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.lifecycle.ViewModelProvider
// Kotlin的绑定机制
import kotlinx.android.synthetic.main.activity_main.*class MainActivity : AppCompatActivity() {// 数据放这 进行横竖屏切换会丢失// var number : Int = 0private lateinit var myViewModel: MyViewModeloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)// myViewModel = MyViewModel()  // 不能之间实例化,因为这样写系统就不可控了// 旧版本的写法(扩展性不强)// ViewModelProviders.of(this).get(MyViewModel::class.java)// this == ViewModelStoreOwner接口myViewModel = ViewModelProvider(this, ViewModelProvider.NewInstanceFactory()).get(MyViewModel::class.java)  // 通过反射来加载Java的class// Kotlin的绑定机制tv_number.text = "${myViewModel.number}"bt.setOnClickListener {tv_number.text = "${++myViewModel.number}"}}
}

  数据存放在ViewModelStore类中,该类有一个Map存储<String, ViewModel>,value为ViewModel,该ViewModel存放相关的具体数据,横竖屏切换保证ViewModelStore是同一个对象。

二、ViewModel + DataBinding + LiveData结合使用

1. java版本

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- DataBinding区域 -->
<layout xmlns:android="http://schemas.android.com/apk/res/android"><data><variablename="vm"type="com.example.jetpack_kotlin.MainViewModel" /></data><!-- UI绘制区域 --><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical"android:background="@drawable/phone2_bg"><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="0dip"android:layout_weight="1" /><!-- 电话号码 --><TextViewandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:textSize="@dimen/activity_phone_tv"android:gravity="center"android:text="@{vm.phoneInfo}"android:textStyle="bold" /><!-- 表格布局 --><TableLayoutandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_marginBottom="16dip"><!-- 第一列 --><TableRowandroid:layout_width="fill_parent"android:layout_height="wrap_content"><Buttonandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_weight="1"android:text="@string/phone1"android:onClick="@{()->vm.appendNumber(String.valueOf(1))}"android:textSize="@dimen/activity_phone_bt"android:background="@drawable/phone_selector_number" /><Buttonandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_weight="1"android:text="@string/phone2"android:onClick="@{()->vm.appendNumber(String.valueOf(2))}"android:textSize="@dimen/activity_phone_bt"android:background="@drawable/phone_selector_number" /><Buttonandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_weight="1"android:text="@string/phone3"android:onClick="@{()->vm.appendNumber(String.valueOf(3))}"android:textSize="@dimen/activity_phone_bt"android:background="@drawable/phone_selector_number" /></TableRow><!-- 第二列 --><TableRowandroid:layout_width="fill_parent"android:layout_height="wrap_content"><Buttonandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_weight="1"android:text="@string/phone4"android:onClick="@{()->vm.appendNumber(String.valueOf(4))}"android:textSize="@dimen/activity_phone_bt"android:background="@drawable/phone_selector_number" /><Buttonandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_weight="1"android:text="@string/phone5"android:onClick="@{()->vm.appendNumber(String.valueOf(5))}"android:textSize="@dimen/activity_phone_bt"android:background="@drawable/phone_selector_number" /><Buttonandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_weight="1"android:text="@string/phone6"android:onClick="@{()->vm.appendNumber(String.valueOf(6))}"android:textSize="@dimen/activity_phone_bt"android:background="@drawable/phone_selector_number" /></TableRow><!-- 第3列 --><TableRowandroid:layout_width="fill_parent"android:layout_height="wrap_content"><Buttonandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_weight="1"android:text="@string/phone7"android:onClick="@{()->vm.appendNumber(String.valueOf(7))}"android:textSize="@dimen/activity_phone_bt"android:background="@drawable/phone_selector_number" /><Buttonandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_weight="1"android:text="@string/phone8"android:onClick="@{()->vm.appendNumber(String.valueOf(8))}"android:textSize="@dimen/activity_phone_bt"android:background="@drawable/phone_selector_number" /><Buttonandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_weight="1"android:text="@string/phone9"android:onClick="@{()->vm.appendNumber(String.valueOf(9))}"android:textSize="@dimen/activity_phone_bt"android:background="@drawable/phone_selector_number" /></TableRow><!-- 第4列 --><TableRowandroid:layout_width="fill_parent"android:layout_height="wrap_content"><Buttonandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_weight="1"android:text="@string/phonexin"android:onClick="@{()->vm.appendNumber(@string/phonexin)}"android:textSize="@dimen/activity_phone_bt"android:background="@drawable/phone_selector_number" /><Buttonandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_weight="1"android:text="@string/phone0"android:onClick="@{()->vm.appendNumber(String.valueOf(0))}"android:textSize="@dimen/activity_phone_bt"android:background="@drawable/phone_selector_number" /><Buttonandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_weight="1"android:text="@string/phonejin"android:onClick="@{()->vm.appendNumber(@string/phonejin)}"android:textSize="@dimen/activity_phone_bt"android:background="@drawable/phone_selector_number" /></TableRow><!-- 第5列 --><TableRowandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_marginTop="6dip"><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_weight="1"android:orientation="vertical"><!-- 清空 --><Buttonandroid:layout_width="40dp"android:layout_height="40dp"android:textSize="@dimen/activity_phone_bt"android:background="@drawable/phone_selector_min"android:layout_gravity="center"android:onClick="@{()->vm.clear()}"android:layout_margin="6dip" /></LinearLayout><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_weight="1"android:orientation="vertical"><!-- 拨打 --><ImageViewandroid:layout_width="46dip"android:layout_height="46dip"android:src="@drawable/phone_selector_call"android:onClick="@{()->vm.callPhone()}"android:layout_gravity="center" /></LinearLayout><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_weight="1"android:orientation="vertical"><!-- 删除一个字符 --><Buttonandroid:layout_width="60dp"android:layout_height="wrap_content"android:textSize="@dimen/activity_phone_bt"android:background="@drawable/phone_selector_backspace"android:layout_gravity="center"android:onClick="@{()->vm.backspaceNumber()}"/></LinearLayout></TableRow></TableLayout></LinearLayout>
</layout>

MainViewModel.java

package com.example.jetpack_java2;import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.MutableLiveData;/*** AndroidViewModel 与 ViewModel的区别是 AndroidViewModel自带application环境*/
public class MainViewModel extends AndroidViewModel {// 传统方式的数据// private String phoneInfo = "";  // 目前无法实现感应功能// 实现感应功能 LiveData + DataBindingprivate MutableLiveData<String> phoneInfo;// 环境private Context mContext;public MainViewModel(@NonNull Application application) {super(application);mContext = application;}// 把数据暴露出去 给布局用public MutableLiveData<String> getPhoneInfo() {if (phoneInfo == null) {phoneInfo = new MutableLiveData<>();// 设置默认值phoneInfo.setValue("");}return phoneInfo;}/*** 输入* @param number*/public void appendNumber(String number) {phoneInfo.setValue(phoneInfo.getValue() + number);}/*** 删除*/public void backspaceNumber() {int length = phoneInfo.getValue().length();if (length > 0) {phoneInfo.setValue(phoneInfo.getValue().substring(0, length - 1));}}/*** 清空*/public void clear() {phoneInfo.setValue("");}/*** 拨打*/public void callPhone() {Intent intent = new Intent();intent.setAction(Intent.ACTION_CALL);intent.setData(Uri.parse("tel:" + phoneInfo.getValue()));// 非Activity启动拨号 或者是 非Activity启动任何的  startActivity都会崩溃intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);mContext.startActivity(intent);}
}

MainActivity.java

package com.example.jetpack_java2;import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import androidx.lifecycle.ViewModelProvider;
import androidx.lifecycle.ViewModelProviders;import android.os.Bundle;
import android.view.View;import com.example.jetpack_java2.databinding.ActivityMainBinding;public class MainActivity extends AppCompatActivity {private ActivityMainBinding dataBinding;   // DataBinding初始化private MainViewModel mainViewModel;       // MainViewModel初始化@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// setContentView(R.layout.activity_main);dataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);// 旧版本的写法// mainViewModel = ViewModelProviders.of(this).get(MainViewModel.class);// 下面是新版本的写法// 如果MainViewModel extends ViewModel// mainViewModel = new ViewModelProvider(this,//      new ViewModelProvider.NewInstanceFactory()).get(MainViewModel.class);// 如果MainViewModel extends AndroidViewModelmainViewModel = new ViewModelProvider(getViewModelStore(),new ViewModelProvider.AndroidViewModelFactory(getApplication())).get(MainViewModel.class);dataBinding.setVm(mainViewModel);dataBinding.setLifecycleOwner(this);  // DataBinding与LiveData建立感应}
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.jetpack_java2"><uses-permission android:name="android.permission.READ_CONTACTS"/><uses-permission android:name="android.permission.WRITE_CONTACTS"/><uses-permission android:name="android.permission.CALL_PHONE"/><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/AppTheme"><activity android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>

2. kotlin版本

MainViewModel.kt

package com.example.jetpack_kotlinimport android.app.Application
import android.content.Context
import android.content.Intent
import android.net.Uri
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveDataclass MainViewModel(application : Application) : AndroidViewModel(application) {// LiveData数据(有感应)val phoneInfo by lazy { MutableLiveData<String>() }init {phoneInfo.value = "" // 设置默认值}// 定义一个环境var mContext : Context = application/*** 输入*/fun appendNumber(number : String) {phoneInfo.value = phoneInfo.value + number}/*** 删除*/fun backspaceNumberr() {var length = phoneInfo.value?.length ?: 0if (length > 0) {phoneInfo.value = phoneInfo.value?.substring(0, length - 1)}}/*** 清空*/fun clear() {phoneInfo.value = ""}/*** 拨号*/fun callPhone() {var intent = Intent()intent.action = Intent.ACTION_CALLintent.data = Uri.parse("tel:" + phoneInfo.value)intent.flags = Intent.FLAG_ACTIVITY_NEW_TASKmContext.startActivity(intent)}
}

MainActivity.kt

package com.example.jetpack_kotlinimport androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider
import com.example.jetpack_kotlin.databinding.ActivityMainBindingclass MainActivity : AppCompatActivity() {var binding : ActivityMainBinding ?= nullvar viewModel : MainViewModel ?= nulloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// setContentView(R.layout.activity_main)binding = DataBindingUtil.setContentView(this, R.layout.activity_main)viewModel = ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory(application)).get(MainViewModel::class.java)binding?.vm = viewModel// DataBinding 与 LiveData 建立感应binding?.lifecycleOwner = this}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/58789.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android Looper Handler 机制浅析

最近想写个播放器demo&#xff0c;里面要用到 Looper Handler&#xff0c;看了很多资料都没能理解透彻&#xff0c;于是决定自己看看相关的源码&#xff0c;并在此记录心得体会&#xff0c;希望能够帮助到有需要的人。 本文会以 猜想 log验证 的方式来学习 Android Looper Ha…

低代码的探索之路

Gartner发布报告指出&#xff0c;2023年全球低代码开发平台市场规模将达到345亿美元&#xff0c;比2022年增长20%。 目前&#xff0c;国内外已经有许多低代码平台&#xff0c;包括OutSystems、Mendix、Appian、Microsoft Power App等。这些平台提供了丰富的功能和工具&#xff…

almaLinux 8 安装 xxdiff 5.1

almaLinux 安装 xxdiff XXdiff——比较和合并工具下载安装安装qt5 XXdiff——比较和合并工具 XXdiff是一款免费、强大的文件和目录比较及合并工具&#xff0c;可以在类似Unix的操作系统上运行&#xff0c;比如Linux、Solaris、HP/UX、IRIX和DEC Tru64。XXdiff的一大局限就是不…

【【萌新的STM32-22中断概念的简单补充】】

萌新的STM32学习22-中断概念的简单补充 我们需要注意的是这句话 从上面可以看出&#xff0c;STM32F1 供给 IO 口使用的中断线只有 16 个&#xff0c;但是 STM32F1 的 IO 口却远远不止 16 个&#xff0c;所以 STM32 把 GPIO 管脚 GPIOx.0~GPIOx.15(xA,B,C,D,E,F,G)分别对应中断…

Redis缓存穿透和雪崩

Redis缓存穿透和雪崩 Redis缓存的使用&#xff0c;极大的提升了应用程序的性能和效率&#xff0c;特别是数据查询方面。但同时&#xff0c;它也带来了一些问题。其中&#xff0c;最要害的问题&#xff0c;就是数据的一致性问题&#xff0c;从严格意义上讲&#xff0c;这个问题…

迁移学习:实现快速训练和泛化的新方法

文章目录 迁移学习的原理迁移学习的应用快速训练泛化能力提升 迁移学习的代码示例拓展应用与挑战结论 &#x1f389;欢迎来到AIGC人工智能专栏~迁移学习&#xff1a;实现快速训练和泛化的新方法 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博客主页&#xff1a;IT陈寒的博…

自定义list工具类 ListUtils.java

自定义list工具类 ListUtils.java 简介 自定义list工具类 api list中是否有完全相同的元素? 如果有 返回true, 如果没有返回false; checkRepeat(List list);list 转 String&#xff0c;list -> “1,2,3,4”&#xff1b; list2String(List list); 源码 import java.uti…

机器学习-神经网络(西瓜书)

神经网络 5.1 神经元模型 在生物神经网络中&#xff0c;神经元之间相互连接&#xff0c;当一个神经元受到的外界刺激足够大时&#xff0c;就会产生兴奋&#xff08;称为"激活"&#xff09;&#xff0c;并将剩余的"刺激"向相邻的神经元传导。 神经元模型…

微信开发之一键创建标签的技术实现

简要描述&#xff1a; 添加标签 请求URL&#xff1a; http://域名地址/addContactLabel 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-Type&#xff1a;application/jsonAuthorization&#xff1a;login接口返回 参数&#xff1a; 参数名必选类型说明…

paddle 1-高级

目录 为什么要精通深度学习的高级内容 高级内容包含哪些武器 1. 模型资源 2. 设计思想与二次研发 3. 工业部署 4. 飞桨全流程研发工具 5. 行业应用与项目案例 飞桨开源组件使用场景概览 框架和全流程工具 1. 模型训练组件 2. 模型部署组件 3. 其他全研发流程的辅助…

单变量图的类型与直方图绘图基础

文章目录 单变量图的类型1.直方图&#xff08;histogram plot&#xff09;2.密度图&#xff08;density plot&#xff09;3.Q-Q 图&#xff08;Quantile- Quantile plot&#xff0c;又称分位图&#xff09;4.P-P 图&#xff08;Probability-Probability plot&#xff09;5.经验…

基于 CentOS 7 构建 LVS-DR 群集。配置nginx负载均衡。

1、基于 CentOS 7 构建 LVS-DR 群集。 [root132 ~]# nmcli c show NAME UUID TYPE DEVICE ens33 c89f4a1a-d61b-4f24-a260-6232c8be18dc ethernet ens33 [root132 ~]# nmcli c m ens33 ipv4.addresses 192.168.231.200/24 [roo…

8 python的迭代器和生成器

概述 在上一节&#xff0c;我们介绍了Python的模块和包&#xff0c;包括&#xff1a;什么是模块、导入模块、自定义模块、__name__、什么是包、创建包、导入包等内容。在这一节中&#xff0c;我们将介绍Python的迭代器和生成器。在Python中&#xff0c;迭代器是一个非常重要的概…

windows下如何搭建属于自己的git服务器

前一阵子公司需要&#xff0c;领导让我给我们技术部搭建一个git服务器。以前看过教程&#xff0c;但自己没动手做过&#xff0c;开始按照网上的教程来&#xff0c;但搭建过程中发现还是不够详细&#xff0c;今天给大家一个比较详细的&#xff0c;希望对大家有帮助。 高能预警&a…

微软用 18 万行 Rust 重写了 Windows 内核

微软正在使用 Rust 编程语言重写其核心 Windows 库。 5 月 11 日——Azure 首席技术官 Mark Russinovich 表示&#xff0c;最新的 Windows 11 Insider Preview 版本是第一个包含内存安全编程语言 Rust 的版本。 “如果你参加了 Win11 Insider 环&#xff0c;你将在 Windows 内…

ES6之浅尝辄止1:class的用法

class是es6新增的一种语法糖&#xff0c;用于简化js中构造类的过程 1.es5中如何构造类&#xff1f; function Person(name,age){this.name name;this.age age; } Person.prototype.sayName function(){return this.name; } let p1 new Person(小明,22);2.es6中的class方式…

DC/DC开关电源学习笔记(二)开关电源的分类

&#xff08;二&#xff09;开关电源的分类 1.DC/DC类开关电源2.AC/DC变换器3.电路结构分类4.功率开关管分类5.电路拓扑分类 开关电源可分为 AC/DC和DC/DC两大类。 作为二次电源的DC/DC变换器现已实现模块化&#xff0c; 且设计技术及生产工艺在国内外均已成熟和标准化&#xf…

【微信小程序篇】- 多环境(版本)配置

最近自己在尝试使用AIGC写一个小程序&#xff0c;页面、样式、包括交互函数AIGC都能够帮我完成(不过这里有一点问题AIGC的上下文关联性还是有限制&#xff0c;会经常出现对于需求理解跑偏情况&#xff0c;需要不断的重复强调&#xff0c;并纠正错误&#xff0c;才能得到你想要的…

Python的pymysql模块与MySQL数据库的互动:基础与实例

Python的pymysql模块与MySQL数据库的互动&#xff1a;基础与实例 一、连接数据库二、创建游标三、执行SQL命令四、关闭连接 在Python的世界里&#xff0c;操作MySQL数据库最常用的库就是pymysql。 pymysql是一个灵活且易于使用的库&#xff0c;它允许我们以Python的方式操作MyS…

Bean 生命周期

Bean 生命周期 一、Bean 实例化的基本流程 Spring容器在进行初始化时&#xff0c;会将xml配置的的信息封装成一个BeanDefifinition对象&#xff0c;所有的BeanDefifinition存储到一个名为beanDefifinitionMap的Map集合中去&#xff0c;Spring框架在对该Map进行遍历&#xff0…