Android MVVM框架搭建(一)ViewModel + LiveData + DataBinding

public String pwd;

账号和密码这当然是最基本的两个数据了,下面我们修改一下activity_main.xml中的布局,代码如下:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout 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”

android:gravity=“center”

android:orientation=“vertical”

android:padding=“32dp”

tools:context=“.MainActivity”>

<com.google.android.material.textfield.TextInputLayout

android:layout_width=“match_parent”

android:layout_height=“wrap_content”>

<com.google.android.material.textfield.TextInputEditText

android:id=“@+id/et_account”

android:layout_width=“match_parent”

android:layout_height=“wrap_content”

android:background=“@color/white”

android:hint=“账号” />

</com.google.android.material.textfield.TextInputLayout>

<com.google.android.material.textfield.TextInputLayout

android:layout_width=“match_parent”

android:layout_height=“wrap_content”

android:layout_marginTop=“12dp”>

<com.google.android.material.textfield.TextInputEditText

android:id=“@+id/et_pwd”

android:layout_width=“match_parent”

android:layout_height=“wrap_content”

android:background=“@color/white”

android:hint=“密码”

android:inputType=“textPassword” />

</com.google.android.material.textfield.TextInputLayout>

<com.google.android.material.button.MaterialButton

android:id=“@+id/btn_login”

android:layout_width=“match_parent”

android:layout_height=“48dp”

android:layout_margin=“24dp”

android:insetTop=“0dp”

android:insetBottom=“0dp”

android:text=“登 录”

app:cornerRadius=“12dp” />

③ 实现登录

下面回到MainActivity中,增加代码如下图所示:

在这里插入图片描述

乍一看好像没啥不同的,无非就是给mainViewModel中的两个变量赋了值。不过这里有一个数据持久化的内容在里面,怎么证明呢?看一下下面这个GIF图

在这里插入图片描述

这个图可能有一些黑屏的地方,因为我在给自己的手机做横竖屏切换的时候,手机录屏好像有一点问题,不过没事。因为这个结果是对的,那就是数据持久化,因为我们知道手机在切换屏幕的时候Activity是会重新创建的,因此如果我们的数据是放在Activity中,那么切换屏幕之后就会重置,输入框也不会有值,但是通过ViewModel去保存输入框的值就不同了,虽然你的Activity在切换屏幕的时候销毁并且重新创建了,但是我的MainModel依然稳定,所以我才能在横屏的时候也登陆,这样不会造成数据丢失。

二、LiveData使用


LiveData是用来做什么的?数据变化感知,也就是说如果我一个页面中对一个TextView进行多次赋值的话,可以通过LiveData来操作,只需要在值改变的时候进行设置就好了,可以简化页面上的代码。下面举一个实际的例子来说明。依然是之前那个登录页面,不过需要修改一下MainViewModel中的变量,如下:

① 可修改数据

public MutableLiveData account = new MutableLiveData<>();

public MutableLiveData pwd = new MutableLiveData<>();

请注意这里使用的是MutableLiveData,表示值的内容开变动,而LiveData是不可变的。<>中的是泛型,你可以直接将一个对象放进去,当对象的内容有改动时,通知改变就可以了,现在这么写是为了方便理解。下面进入MainActivity中,首先我们改变一下布局activity_main.xml在按钮的下面再加如下代码

<TextView

android:id=“@+id/tv_account”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”/>

<TextView

android:id=“@+id/tv_pwd”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”/>

② 数据观察

然后回到MainActivity中,修改代码如下图所示:

在这里插入图片描述

上面的图中从上往下有四处标注,我们从下面的两处标注来看,首先在给MainViewModel中的account赋值时,采用了MutableLiveData的setValue()的方式,还有一种方式是postValue(),这里要注意一点setValue()只能在主线程中调用,postValue()可以在任何线程中调用。pwd也是一样的,然后在最后一处标注的地方,对MainViewModel中的account和pwd进行数据观察,当这两个值有改变时通知页面最新的值,这里用了lambda表达式进行了一次简化,实际的代码是这样的。

在这里插入图片描述

下面我们运行一下:

在这里插入图片描述

三、DataBinding使用


Android的DataBinding在已经内置了,因此只需要在app模块的build.gradle中开启就可以使用了。DataBinding,顾名思义就是数据绑定,可以看到现在的三个组件都与数据有关系,ViewModel数据持有,LiveData数据观察、DataBinding数据绑定。

① 单向绑定

而DataBinding的绑定有两种方式:单向数据绑定和双向数据绑定。举个例子:比如我手机上收到一个通知,我需要显示通知的文字内容在页面上,这就是单向绑定,而我页面上的文字内容改变也重新发一个通知出去,这就是双向绑定。可以理解为A和B进行交互。A发消息,B要做出反应。B发消息,A也要相应改变。最常用的就是当我Model中的数据改变时,改变页面上的值。这个是单向绑定。下面我们可以新建一个用户User对象,代码如下:

public class User extends BaseObservable {

private String account;

private String pwd;

public String getAccount() {

return account;

}

public void setAccount(String account) {

this.account = account;

notifyChange();//通知改变 所有参数改变

}

public String getPwd() {

return pwd;

}

public void setPwd(String pwd) {

this.pwd = pwd;

}

public User(String account, String pwd) {

this.account = account;

this.pwd = pwd;

}

}

这里我继承了BaseObservable,注意它在androidx.databinding包下。然后我们的数据是需要显示在页面上的,而之前是通过Activity获取xml中的控件,然后显示数据在控件上,而现在有了DataBinding,可以直接和xml的中数据进行绑定,这看起来和JS比较像。下面我们对activity_main.xml进行改变。改变后代码如下:

<?xml version="1.0" encoding="utf-8"?>

<layout 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”>

<variable

name=“user”

type=“com.llw.mvvm.User” />

<LinearLayout

android:layout_width=“match_parent”

android:layout_height=“match_parent”

android:gravity=“center”

android:orientation=“vertical”

android:padding=“32dp”

tools:context=“.MainActivity”>

<com.google.android.material.textfield.TextInputLayout

android:layout_width=“match_parent”

android:layout_height=“wrap_content”>

<com.google.android.material.textfield.TextInputEditText

android:id=“@+id/et_account”

android:layout_width=“match_parent”

android:layout_height=“wrap_content”

android:background=“@color/white”

android:hint=“账号” />

</com.google.android.material.textfield.TextInputLayout>

<com.google.android.material.textfield.TextInputLayout

android:layout_width=“match_parent”

android:layout_height=“wrap_content”

android:layout_marginTop=“12dp”>

<com.google.android.material.textfield.TextInputEditText

android:id=“@+id/et_pwd”

android:layout_width=“match_parent”

android:layout_height=“wrap_content”

android:background=“@color/white”

android:hint=“密码”

android:inputType=“textPassword” />

</com.google.android.material.textfield.TextInputLayout>

<com.google.android.material.button.MaterialButton

android:id=“@+id/btn_login”

android:layout_width=“match_parent”

android:layout_height=“48dp”

android:layout_margin=“24dp”

android:insetTop=“0dp”

android:insetBottom=“0dp”

android:text=“登 录”

app:cornerRadius=“12dp” />

<TextView

android:id=“@+id/tv_account”

android:text=“@{user.account}”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”/>

<TextView

android:id=“@+id/tv_pwd”

android:text=“@{user.pwd}”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”/>

这里我在最外层加了一个layout标签,然后将原来的布局放在layout里面,再增加一个数据源,也就是user对象,然后再底部的两个tv_account和tv_pwd两个TextView中的text属性中绑定了user对象中的属性值。当然这样还没有完成,最后一步是在MainActivity中去进行绑定的。

进入MainActivity。在onCreate方法中,先将其他的代码注释掉。

在这里插入图片描述

然后修改待明日如下图所示

在这里插入图片描述

这里要注意一点,DataBindingUtil.setContentView返回的是一个ViewDataBinding对象,这个对象的生成取决于你的Activity,例如MainActivity,就会生成ActivityMainBinding。然后再通过生成的ActivityMainBinding去设置要显示在xml中控件的值。因此你会看到我完全没有去findViewById,然后控件再去设置这个setText。还有一点就是当你使用了DataBinding之后就不需要去手动findViewById了,通过编译时技术会生成驼峰命名的对象,如上图的btnLogin、etAccount、etPwd。上图的代码就是通过更改数据然后通知到xml做更改,初始化的修改时admin、123456。然后再通过输入框去修改。我将会输入study、666,然后点击登录按钮,也会将输入框的数据显示在TextView上,这样是否会省去很多不必要的繁琐工作呢?下面运行一下:

在这里插入图片描述

② 双向绑定

双向绑定是建立在单向绑定的基础上,实际的开发中用到双向绑定的地方并没有单向绑定多,双向绑定举一个例子,在输入框输入数据时候直接将数据源中的数据进行改变,这里会用到ViewModel和LiveData。下面进行双向绑定的使用,修改一下MainViewModel,代码如下:

public class MainViewModel extends ViewModel {

public MutableLiveData user;

public MutableLiveData getUser(){

if(user == null){

user = new MutableLiveData<>();

}

return user;

}

}

下面修改User类,这里面做了一些改变

public class User extends BaseObservable {

public String account;

public String pwd;

@Bindable

public String getAccount() {

return account;

}

public void setAccount(String account) {

this.account = account;

notifyPropertyChanged(BR.account);//只通知改变的参数

}

@Bindable

public String getPwd() {

return pwd;

}

public void setPwd(String pwd) {

this.pwd = pwd;

notifyPropertyChanged(BR.pwd);//只通知改变的参数

}

public User(String account, String pwd) {

this.account = account;

this.pwd = pwd;

}

}

不同于notifyChange()改变某一个参数,某一个对象都会通知,现在notifyPropertyChanged()就具有针对性,只通知对应属性改变。之前在activity_main.xml中的data标签中是使用的User,现在我们改成ViewModel,顺便把布局调整一下,代码如下:

<?xml version="1.0" encoding="utf-8"?>

<layout 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”>

<variable

name=“viewModel”

type=“com.llw.mvvm.viewmodels.MainViewModel” />

<LinearLayout

android:layout_width=“match_parent”

android:layout_height=“match_parent”

android:gravity=“center”

android:orientation=“vertical”

android:padding=“32dp”

tools:context=“.MainActivity”>
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

最后

我见过很多技术leader在面试的时候,遇到处于迷茫期的大龄程序员,比面试官年龄都大。这些人有一些共同特征:可能工作了5、6年,还是每天重复给业务部门写代码,工作内容的重复性比较高,没有什么技术含量的工作。问到这些人的职业规划时,他们也没有太多想法。

其实30岁到40岁是一个人职业发展的黄金阶段,一定要在业务范围内的扩张,技术广度和深度提升上有自己的计划,才有助于在职业发展上有持续的发展路径,而不至于停滞不前。

不断奔跑,你就知道学习的意义所在!

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!

,基本涵盖了95%以上Android开发知识点,真正体系化!**

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

最后

我见过很多技术leader在面试的时候,遇到处于迷茫期的大龄程序员,比面试官年龄都大。这些人有一些共同特征:可能工作了5、6年,还是每天重复给业务部门写代码,工作内容的重复性比较高,没有什么技术含量的工作。问到这些人的职业规划时,他们也没有太多想法。

其实30岁到40岁是一个人职业发展的黄金阶段,一定要在业务范围内的扩张,技术广度和深度提升上有自己的计划,才有助于在职业发展上有持续的发展路径,而不至于停滞不前。

不断奔跑,你就知道学习的意义所在!

[外链图片转存中…(img-rr5uQVqq-1711754061076)]

[外链图片转存中…(img-PpU7ARfT-1711754061076)]

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
  • 8
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值