Android MVP模式学习(二)----Data Binding结合

公司项目最近已经用MVP模式重新构造完成,重构后的项目直观明了,代码复用性高,易于调试维护。

之后主管让我去了解MVC,MVP ,MVVM,Data Binding相关的知识,于是便有了下面这篇博客。参考资料:

选择恐惧症的福音!教你认清MVC,MVP和MVVM

完全掌握Android Data Binding

这里很感谢这两篇文章的理论与技术支持,感谢这些大神。

OK,开始今天的主题。

关于MVP模式与MVVM模式孰是孰非,我想不是我一个初学者短短几句就能够说清楚的,我们也不用纠结于此。引用大神的话“真正的最佳实践都是人想出来的”。我们为何不结合一下MVP和MVVM的特点:MVP+Data Binding,依旧使用presenter去做和model层的通信,同时使用data binding去轻松的bind data。

Data Binding—-2015年的Google IO 大会上,Android 团队发布的一个 数据绑定框架。以后可以直接在 layout 布局 xml 文件中绑定数据,无需再通过findViewById或者注解框架去设置数据。

具体看看MVP+Data Binding在项目中的应用:

点击button,请求加载网络数据,两秒过后,将模拟的数据显示在textView中。

1.准备工作

新建一个 Project,确保 Android 的 Gradle 插件版本不低于 1.5.0-alpha1:

classpath ‘com.android.tools.build:gradle:1.5.0‘

然后修改对应模块(Module)的 build.gradle:

dataBinding {
    enabled true
}

2.数据对象

这里的数据对象有两种情况,一种是普通的数据对象,一种是绑定的数据对象,能够自动更新数据。

先看第一种:

/**
 * Created by tangyangkai on 16/4/27.
 */
public class User{
    private String firstName;
    private String lastName;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
}

一个简单的User,两个属性以及它的 getter 和 setter。

3.布局文件

<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>

        <variable
            name="user"
            type="com.example.tangyangkai.myapplication.User"></variable>
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="getWebMsg"
            android:text="模拟请求网络数据" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="姓氏:" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{user.firstName}" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="名字:" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{user.lastName}" />
    </LinearLayout>
</layout>

(1.)data节点:使用 Data Binding 之后,xml 的布局文件就不再用于单纯地展示 UI 元素,还需要定义 UI 元素用到的变量。所以,它的根节点不再是一个 ViewGroup,而是变成了 layout,并且新增了一个节点 data。data 节点的作用就像一个桥梁, 把数据(Model)与 UI(View) 进行绑定,搭建了 View 和 Model 之间的通路。

(2.)申明variable:

<data>
<variable
      name="user"
      type="com.example.tangyangkai.myapplication.User">            </variable>
</data>

在 xml 布局文件的 data 节点中声明一个 variable,这个变量会为 UI 元素提供数据(例如 TextView 的 android:text),然后在 Java 代码中把『后台』获取的数据与这个 variable 进行绑定。其中 type 属性就是我们在 Java 文件中定义的 User 类。

(3.)使用variable:

            <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{user.firstName}" />

数据与 Variable 绑定之后,xml 的 UI 元素就可以直接使用了。

4.Activity实现

public class FiveActivity extends AppCompatActivity implements StringView {

    private StringPresenter mStringPresenter;
    ActivityFiveBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mStringPresenter = new StringPresenter(this);
        binding = DataBindingUtil.setContentView(
                this, R.layout.activity_five);

    }

    //请求网络数据
    public void getWebMsg(View view) {
        mStringPresenter.SetUrl();
    }

    @Override
    public void ShowString(String firstName, String lastName) {
        User user = new User();
        user.setFirstName(firstName);
        user.setLastName(lastName);
        binding.setUser(user);

    }
}

(1.)ActivityFiveBinding是框架自动生成的, 其中的set 方法也是根据 variable 名称而生成的。

(2.)修改 FiveActivity 的 onCreate 方法,用 DatabindingUtil.setContentView() 来替换掉 setContentView()

(3.)创建一个 User 对象,将从网络获取的数据通过set方法传递给User,通过 binding.setUser(user) 与 variable 进行绑定。

至此,使用第一种数据对象的data binding流程已经过了一遍,其实核心就是申明variable,绑定variable,使用variable。第二种数据对象也一样,只不过是绑定variable时候有些不一样。

5.第二种数据类型

/**
 * Created by tangyangkai on 16/4/27.
 */
public class User extends BaseObservable{
    private String firstName;
    private String lastName;

    @Bindable
    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
        notifyPropertyChanged(BR.firstName);
    }

    @Bindable
    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
        notifyPropertyChanged(BR.lastName);
    }
}

(1.)要实现 数据对象的绑定,Android 原生提供了已经封装好的一个类 - -BaseObservable,并且实现了监听器的注册机制,我们只需要继承 BaseObservable。

(2.)BR 是编译阶段生成的一个类,功能与 R.java 类似,用 @Bindable 标记过 getter 方法会在 BR 中自动生成一个 entry。

(3.)当数据发生变化时会调用 notifyPropertyChanged(BR.firstName) 方法,通知系统 BR.firstName 这个 entry 的数据已经发生变化,再去更新 UI。

public class FiveActivity extends AppCompatActivity implements StringView {

    private StringPresenter mStringPresenter;
    User user = new User();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mStringPresenter = new StringPresenter(this);
        ActivityFiveBinding binding = DataBindingUtil.setContentView(
                this, R.layout.activity_five);
        binding.setUser(user);

    }

    //请求网络数据
    public void getWebMsg(View view) {
        mStringPresenter.SetUrl();
    }

    @Override
    public void ShowString(String firstName, String lastName) {
        user.setFirstName(firstName);
        user.setLastName(lastName);
    }
}

与第一种数据对象不同的是,variable的数据绑定会在初始化的时候就完成。获取网络数据成功以后,只要直接传递给user即可,数据以及UI的更新会在内部进行。

6.MVP的代码

Presenter层

/**
 * Created by tangyangkai on 16/4/11.
 * Presenter作为中间层,持有View和Model的引用,对model层的数据进行处理,控制View层的展示
 */
public class StringPresenter implements StringModel.getMsgListener {
    private StringView stringview;
    private StringModel stringmodel;

    public StringPresenter(StringView stringview) {
        this.stringview = stringview;
        stringmodel = new StringModel();
    }

    //对view层提供请求数据方法
    public void SetUrl() {
        stringmodel.getWebMsg(this);
    }

    //将model层返回的数据传递给view
    @Override
    public void getMsgSuccess(String firstName, String lastName) {
        stringview.ShowString(firstName, lastName);
    }
}

Model层


/**
 * Created by tangyangkai on 16/4/11.
 * 模拟请求数据,具体实战根据返回结果处理
 */
public class StringModel {

    public interface getMsgListener {
        void getMsgSuccess(String firstName, String lastName);
    }

    public void getWebMsg(getMsgListener listener) {
        //模拟网络数据请求
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        listener.getMsgSuccess("tang", "yangkai");
    }

}

之前一篇博客关于MVP的使用说的很清楚,这里就不详细解释了。

Android MVP模式学习(一)—-认知与使用

关于Data Binding的高级用法以及注意事项,开始那两篇文章介绍的很详细,大家可以细细品尝。

关于这些模式与框架,仁者见仁,智者见智,其实都是为了尽量降低程序的耦合性和提高代码的复用性。以上是记录自己最近学习这些框架模式的一些心得,有不当之处欢迎大家指出,一起进步。

公司开新项目了,准备投入新的战斗O(∩_∩)O~

时间: 2024-08-05 04:53:05

Android MVP模式学习(二)----Data Binding结合的相关文章

Android Afinal框架学习(二) FinalActivity 一个IOC框架

框架地址:https://github.com/yangfuhai/afinal 对应的源码: net.tsz.afinal.annotation.view.* FinalActivity FinalActivity是一个基础类,结合注解实现了,依赖注入(view的资源id,常用的监听器), 利用set方式注入 完全注解方式就可以进行UI绑定和事件绑定,无需findViewById和set event Listener 这个过程:initInjectedView>findViewById.set

作为过来人,对于Android MVP模式的一些详解

前言 闲来无事在家偶然翻到了之前整理的文档和面试要做到准备路线,虽然内容有点多,但是技多不压身,多多益善 本部分内容是关于Android进阶的一些知识总结,涉及到的知识点比较杂,不过都 是面试中几乎常问的知识点,也是加分的点. 关于这部分内容,可能需要有一些具体的项目实践.在面试的过程中,结合具体自 身实践经历,才能更加深入透彻的描绘出来 相关内容后续GitHub更新,想冲击金三银四的小伙伴可以找找看看,欢迎star(顺手留下GitHub链接,需要获取相关面试等内容的可以自己去找)https:/

Xamarin.Android MVP模式

一.简介 随着UI创建技术的功能日益增强,UI层也履行着越来越多的职责.为了更好地细分视图(View)与模型(Model)的功能,让View专注于处理数 据的可视化以及与用户的交互,同时让Model只关系数据的处理,基于MVC概念的MVP(Model-View-Presenter)模式应运而生. 在MVP模式里通常包含4个要素: View:负责绘制UI元素.与用户进行交互(在Android中体现为Activity); View interface:需要View实现的接口,View通过View i

android MVP模式简单介绍

原文 http://zhengxiaopeng.com/2015/02/06/Android%E4%B8%AD%E7%9A%84MVP/ 前言 MVP作为一种MVC的演化版本在Android开发中受到了越来越多的关注,但在项目开发中选择一种这样的软件设计模式需保持慎重心态,一旦确定 使用MVP作为你App的开发模式那么你就最好坚持做下去,如果在使用MVP模式开发过程中发现问题而且坑越来越大,这时你想用MVC等来重新设计的话基 本上就等于推倒重来了.要知道在Android上MVP在现在为止并没有统

android MVP模式简介

MVP架构略解: M--Model,业务层(主要负责具体功能实现) V--View,视图层(用作显示) P--Presenter,连接层(搭建Model层和View层通信桥梁) MVP模式下,Model层和View层是完全隔离(解偶)的,两者的通信都是通过Presenter层作为桥梁来进行通信的,所以,Presenter层中一定含有Model层和View层具体实例(由这可以看出,当界面改变时,只需更改Presenter层中的View实例即可;同理,当数据加载方式改变时,只需更改Presenter

android MVP模式思考

在软件开发设计中,有多种软件设计模式,如web开发中经典的MVC, 将后台分为三层:Model层,View层和Controller层,其中,Model主要是数据处理,如数据库,文件,或网络数据等:View层是视图层,主要是指前端或后端用于直接展现给用户的页面,Controller层则是负责业务逻辑处理,即将Model中读取的数据显示到View层,同时又将View层触发的操作事件经过业务处理后将数据保存到Model层中. 在android中,可能很多开发者使用的还是mvc模式,比如,在代码中可以发

关于Android MVP模式的思考

最近经常看到各种介绍MVP模式的博客的,之前写过不少的Android应用,在做那些应用的时候,都是要求快速完成,所以从开始设计到写代码就一直考虑着重用.以前写的项目基本都是不断重构项目,将项目代码变得更加精简,提高代码之间的复用性.但是代码并没有特别地注重按照MVC模式或者是MVP模式来,更多的是直接考虑模块化,重用,精简.所以看了MVP模式后,决定去总结一下自己代码中的问题并优化,算是对自己之前写的代码的回顾. MVP框架 MVP框架是目前在Android流行起来的框架,它非常适合用于Andr

Android MVP模式简单介绍:以一个登陆流程为例

老的项目用的MVC的模式,最近完成了全部重构成MVP模式的工作,虽然比较麻烦,好处是代码逻辑更加清楚.简洁,流程更加清晰,对于后续版本迭代维护都挺方便.对于一些想要学习MVP模式的同学来讲,百度搜出来的好多都没法直接转化为项目里可以直接用的东西,所以这里正好拿出自己项目里已经用了的,你们可以直接用到自己的项目里.当然,不可能把所有项目代码在这里放出来,所以就拿登陆的流程出来,这个比较合适也比较常用. 1.先看下包结构: model:放一些bean类,以及网络处理类RetrofitManager,

Android MVP模式的初识

  MVP是什么?或许在之前更多的人知道的是MVC这个模式(Model View Controller),然而MVP与MVC最不同的一点是M与V是不直接 关联的也是就Model与View不存在直接关系,这两者之间间隔着的是Presenter层.个人感觉这是一种很棒的设计,让代码能够实现充分的解耦. 那么我们还是没有讲到MVP是什么~~~不要急,我会用最简单的方式来叙述,这样好理解~ M(Model):为UI层提供数据,或者是保存UI层的数据: V(View) :单纯的数据展示,响应用户的操作并且