博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android MVVM开发——DataBinding基础
阅读量:7051 次
发布时间:2019-06-28

本文共 5246 字,大约阅读时间需要 17 分钟。

hot3.png

前言

        目前主流的开发框架不外乎MVC、MVP和MVVM三种,对于前两种模式,我还算稍有了解。可是提到MVVM,在真正自己动手用过前,我真是一点概念都没有。使用了之后,我就深深爱上了MVVM。使用这种开发模式,可以大量减少令人头疼的id命名,自然也省去了许多TextView、Button变量的定义以及相关的findViewById()语句,编写表单页面时效果尤佳。

        当然,最主要的还是Google在2015年时,已经为我们提供了DataBinding技术,我们可以非常方便地在Android Studio中使用这个框架进行MVVM模式的开发。官方的,好用的!

        学习过程中我主要参考了以下两篇文章:

        ①玩转Android之MVVM开发模式实战,炫酷的DataBinding!

            ;

        ②Android-MVVM架构-Data Binding的使用

            。

        虽然网上资料也不少,但是有的内容学习时没找到,所以觉得需要补充一下。更是为了方便日后回顾,于是我写了这么一篇日志。看下面的内容前,可以先看一下第二个地址中文章开头的介绍,以便于了解为什么要使用MVVM模式。

 

一、使用前的准备

        要在Android Studio中使用DataBinding,就需要先在gradle中进行一句简单的配置:

apply plugin: 'com.android.application'android {    ……    dataBinding {        enabled = true    }}dependencies {    ……}

        接着就可以开始了。

 

二、DataBinding在layout.xml中的使用

        先看一下一个简单的布局

……
……

        界面效果如下:

        

        可以看到,layout文件的根节点不再是一个View或者是一个ViewGroup,而是“layout”。在layout下又有一个<data>节点,在这个节点我们可以定义变量。下面的<ScrollView>就是以往我们使用的根节点啦,在<data>中定义的变量,可以在这里使用。变量类型可以像例子中那样写个import,也可以直接在variable下的type中定义完整路径。在花括号内,我们可以进行一些简单的计算。例如:

        在这里,固定字符应使用“`”符号来区分,而不是引号。还可以进行三目运算,如:

        “&gt;”是“>”的意思,因为在xml中使用一些符号需要使用转义符,所以是这样写的,具体转移前面的有转载过。这里使用View的两个变量,是需要在<data>中进行声明的。

    

        注意layout_width="match_parent"这种属性在layout节点也是可以写的,然后根ViewGroup中可以同时定义,都写上之后,该文件并不会报错,而在build时,与该文件关联的debug文件会报重复定义的错误。

 

三、DataBinding在.java文件中的使用

package example.chumi.demo.view.activity.mvvm;import android.databinding.DataBindingUtil;import android.support.v7.app.AppCompatActivity;import example.chumi.demo.R;import example.chumi.demo.model.User;public class MVVMTestActivity extends AppCompatActivity {    private User user;    private example.chumi.demo.databinding.ActivityMvvmtestBinding binding;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);//        setContentView(R.layout.activity_mvvmtest);        bindData();    }    private void bindData() {        binding = DataBindingUtil.setContentView(this, R.layout.activity_mvvmtest);        user = new User("Arcanite", "Magician", "奥金", 18);        binding.setUser(user);    }}

        这里也有一个与以往有很大不同的地方——不再使用setContentView(),而是使用了

DataBindingUtil.setContentView()

        通过这个方法我们可以获取到一个binding实例,使用这个实例可以对xml中定义的变量进行设置。binding的类型名由xml文件名决定,对比layout名和类名不难发现两者的关系。

        这里需要提一下在Fragment中binding实例的获取,如果该Fragment对应的layout文件中包含变量,那么可以使用下面这种方法来获取。

@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {    View view = inflater.inflate(R.layout.fragemnt, container, false);    binding = DataBindingUtil.bind(view);    initData();    initView(view);    return view;}

 

四、变量数据的同步更新

        当实体类继承BaseObservable,就可以让框架帮助我们对界面上展示的数据进行更新。在需要更新的变量的set方法中增加notifyPropertyChanged()方法,在对应的get方法上添加声明“@Bindable”。下面是示例代码:

package example.chumi.demo.model;import android.databinding.BaseObservable;import android.databinding.Bindable;public class User extends BaseObservable {    private String face;    private String firstName;    private String lastName;    private String displayName;    private int age;    public User(String firstName, String lastName, String displayName, int age) {        this.firstName = firstName;        this.lastName = lastName;        this.displayName = displayName;        this.age = age;    }    public void setFace(String face) {        this.face = face;        notifyPropertyChanged(example.chumi.demo.BR.face);    }    @Bindable    public String getFace() {        return face;    }    @Bindable    public String getFirstName() {        return firstName;    }    @Bindable    public String getLastName() {        return lastName;    }    @Bindable    public String getDisplayName() {        return displayName;    }    @Bindable    public int getAge() {        return age;    }    public void setFirstName(String firstName) {        this.firstName = firstName;        notifyPropertyChanged(example.chumi.demo.BR.firstName);    }    public void setLastName(String lastName) {        this.lastName = lastName;        notifyPropertyChanged(example.chumi.demo.BR.lastName);    }    public void setDisplayName(String displayName) {        this.displayName = displayName;        notifyPropertyChanged(example.chumi.demo.BR.displayName);    }    public void setAge(int age) {        this.age = age;        notifyPropertyChanged(example.chumi.demo.BR.age);    }}

        如果BR总是报错,可以尝试在变量全部声明完毕后build一次工程。

 

五、layout.xml的几点补充

①Includes

 name.xml 和 contact.xml都必须包含 <variable name="user" ../>

②事件的绑定

        在第一部分中,增加点击事件监听器clickListener。

    

        那么在ViewGroup部分,我们就可以直接使用这个监听器。

③自定义事件

        在实体类中声明如下方法:

/** * * 对应的xml属性声明 app:load_img="@{food.imgUrl}",使用时需要在layout的声明中增加 xmlns:app="http://schemas.android.com/apk/res-auto" * 前面写定义的名字,后面填参数 * * @param img 需要显示图片的控件,DataBinding会自动传 * @param imgUrl 图片地址,需要在layout文件中的控件属性声明中写好 */@BindingAdapter("load_img")public static void loadInternetImage(ImageView img, String imgUrl) {    Picasso.with(img.getContext()).load(imgUrl).into(img);}

        对应的layout文件可以在添加注释中的声明后,在第一个参数对应的控件中使用这个方法。

 

        有空时我会Demo程序上传到码云,届时将会贴上链接,希望大家多多指教。

 

转载于:https://my.oschina.net/arcanite/blog/809073

你可能感兴趣的文章
安装Java
查看>>
Ubuntu Linux输入法fcitx方块乱码解决设置
查看>>
node递归批量重命名指定文件夹下的文件
查看>>
python if not用法
查看>>
python-2
查看>>
选择器
查看>>
springMVC参数的获取区别
查看>>
SSH报错记录
查看>>
BZOJ4543/BZOJ3522 [POI2014]Hotel加强版(长链剖分)
查看>>
Python中文转为拼音
查看>>
advacing lnux program --4.1.5 Thread Attributes[copy]
查看>>
SQL SERVER大话存储结构(1)
查看>>
更改SQLServer实例默认字符集
查看>>
MVC设计模式
查看>>
NSBundle和XIB加载
查看>>
Mybatis——SSM
查看>>
java===java基础学习(8)---静态域与静态方法
查看>>
windows使用git clone速度慢,改善方法
查看>>
Eclipse Java开发环境配置 + memcached + maven
查看>>
[转]C++对象内存分配
查看>>