澳门新葡萄京娱乐场 1

澳门新葡萄京娱乐场Android数据绑定组件RoboBinding使用详解

本文由码农网 –
小峰原创,转发请看清文末的转发要求,接待参加大家的付费投稿布置!

当前项目中因为Controller和View,Model未有完成解耦,变成Activity既要担任处理业务逻辑,又要承当UI彰显,数据绑定,所以导致Activity里代码过多,逻辑不掌握,对代码的可读性,可维护性不是很好,所以利用局地分段形式,能够尤其实用的对业务逻辑层,UI展现层,数据层进行拆分,聚焦分层形式有:使用的最多的是MVC和MVP。在那之中MVC现身与上世纪70时代,在八十多年的工程实践中,MVC丰富表明了它的中标,同偶尔间在长期的岁月底国对外演出集团变出了过多变种,个中也囊括MVP.MVC和MVP最大的间隔在与调整层对于整个框架的调整力上。而MVVM能够算是MVP的进级版,个中的VM是ViewModel的缩写,ViewModel能够领略成是View的数据模型和Presenter的合体,ViewModel和View之间的相互影响通过Data
Binding实现,而Data
Binding能够兑现双向的并行,那就使得视图和调整层之间的耦合程度特别下滑,关心点抽离更为深透,同期缓解了Activity的压力,三者之间的反差如下:

本文原创,转发请注明地址:
如何从布局品级去搭建多少个应用程式,怎么样让他应对日益改换的分界面与业务逻辑?
几天前为大家陈述生龙活虎种在Android上落到实处MVP方式的不二法门。也是自己从新类型中总计出来的生机勃勃种新的布局模式,我们能够查看自身的TheMVP项目:

RoboBinding简介

罗布oBinding是生机勃勃款基于Android的多少绑定组件,它能够扶持你编写可读性强、轻易测量试验甚至质量优良的Android
UI应用。罗布oBinding有以下几本性状:

  • 为了简练框架,罗布oBinding移除了大批量不须求的代码,例如addXXListener(State of Qatar,findViewById(卡塔尔等。
  • 可以将难以测验的Android代码调换为常常的JUnit测量检验。
  • 提供对象类型Cursor来替换
    – 关系项目Cursor,因为大家早就习于旧贯于操作对象 。
  • 能够比较轻便的为其它自定义组件,第三方组件或Android
    widget编写属性绑定完毕,简化代码,使项目易于维护。

上面我们通过二个小例子来读书罗布oBinding的应用方法。

澳门新葡萄京娱乐场 1MVVM.png

缘何须要MVP

关于怎么样是MVP,以致MVC、MVP、MVVM有啥界别,那类难点网络早原来就有不少的上书,你可以活动检索或探视文末的仿效小说,这里就只讲讲怎么必要MVP。
在Android开采中,Activity实际不是一个正经的MVC方式中的Controller,它的首要义务是加载应用的布局和开头化顾客分界面,并收受并处理来自客商的操作须要,进而作出响应。然而,随着分界面及其逻辑的复杂度不断升高,Activity类的天职不断追加,招致非常轻巧变得高大而重叠。
越小的类,bug越不轻便并发,越轻便调试,更易于测量检验,我相信那点大家是都趋势的。在MVP形式下,View和Model是截然分开未有其他直接涉及的(举例你在View层中全然无需导Model的包,也不应有去关联它们State of Qatar。
选拔MVP方式能够更平价的扶持Activity(或Fragment卡塔尔(قطر‎任务分开,减小类体量,使项目布局进一步明显。

罗布oBinding使用办法

布局代码:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:bind="http://robobinding.org/android">
    <TextView
        bind:text="{hello}" />
        ...
    <Button
        android:text="Say Hello"
        bind:onClick="sayHello"/>
</LinearLayout>

presentation models:

@org.robobinding.annotation.PresentationModel
public class PresentationModel implements HasPresentationModelChangeSupport {
    private String name;
    public String getHello() {
        return name + ": hello Android MVVM(Presentation Model)!";
    }
    ...
    public void sayHello() {
        firePropertyChange("hello");
    }
}

Activity代码

Activities将运用架构和表现层数据绑定在联合,MainActivity.java的代码如下:

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        PresentationModel presentationModel = new PresentationModel();
        View rootView = Binders.inflateAndBindWithoutPreInitializingViews(this, R.layout.activity_main, presentationModel);
        setContentView(rootView);
    }
}

愈来愈多关于罗布oBinding的行使,可以访谈其在Github上的主页。

Android平台上有一点比较好的MVVM框架,此中用的超级多的是罗布oBinding,罗布obinding犹如下特点:

现有的MVP方案

GitHub上有三个开源项目AndroidMVP,其考虑是通过将Activity或Fragment看做View,并单独行使has…a…关系蕴含一个Presenter类的办法完毕的,那是生机勃勃种有效的本事方案。

为了简洁明了框架,罗布oBinding移除了汪洋不供给的代码,比方addXXListener(卡塔尔国,findViewById(卡塔尔等。能够将难以测量检验的Android代码调换为成千上万的JUnit测量试验。提供对象类型Cursor来替换

AndroidMVP使用示例

完整Demo请查看这里
先是必要定义二个View层接口,让View完毕类Activity(Fragment卡塔尔达成;
说不上需求定义八个Presenter达成接口,让Presenter完结类完结;
在View完毕类Activity(Fragment卡塔尔中带有Presenter对象,并在Presenter创设的时候传一个View对象;
在Presenter中经过协会时传出的视图层对象操作View

public interface LoginView {
    public void showProgress();
    public void hideProgress();
    public void setUsernameError();
    public void setPasswordError();
}

public class A extends Activity implements LoginView, OnClickListener {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // ...
        // 省略初始化控件
        // ...
        presenter = new LoginPresenterImpl(this);
    }
    //...省略众多接口方法
}

public class LoginPresenterImpl implements LoginPresenter, OnLoginFinishedListener {
    private LoginView loginView;

    public LoginPresenterImpl(LoginView loginView) {
        this.loginView = loginView;
    }

    @Override public void validateCredentials(String username, String password) {
        loginView.showProgress();
        //做逻辑操作
    }
}
  • 关系项目Cursor,因为大家早已习感觉常于操作对象
    。能够十分轻巧的为别的自定义组件,第三方组件或Android
    widget编写属性绑定完成,简化代码,使项目易于维护。

AndroidMVP存在的标题

只是在用的时候会现出有的标题:
1.
诸如当使用步向后台且内部存储器不足的时候,系统是会回收这些Activity的。平常大家都精晓要用OnSaveInstanceState()去保存处境,用OnRestoreInstanceState()去复苏意况。
但是在我们的MVP中,View层是不应有去直接操作Model的,这样做不创立,相同的时候也增大了M与V的耦合。
2.
分界面复用难点。经常大家在应用程式最早版本中是无计可施预料到今后会有哪些改观的,比如大家最先使用一个Fragment去作为界面包车型客车显示,后来在本子更改中窥见那么些Fragment更加粗大,而Fragment的生命周期又太过复杂产生多数麻烦知晓的BUG,大家要求把这一个分界面放到一个Activity中落到实处。那时就麻烦了,要把Fragment转成Activity,那可不光是改良类名的题目,更加的多的是第一次全国代表大会堆生命周期须要去修正。举个例子参谋小说第22中学的译者就赶过过这么的标题。
3.
Activity自身正是Android中的多少个Context。无论怎么去封装,都难避防止将事业逻辑代码写入到内部。

** 罗布obiding 轻易利用示例:**View层(对应android xml文件)

缓慢解决现成方案的标题

既然如此知道了那几个主题素材,大家的消除办法自然是毫无将Activity作为View层而去单独满含Presenter类进来。反过来,大家将Activity(Fragment卡塔尔国作为Presenter层的代码,包罗一个View层的类来。如若您同一时候是一名IOS开辟者,你一定会很熟练,那不就是ViewController和应用程式Delegate吗。
使用Activity作为Presenter的长处就在于,能够原封不动的利用Activity本人的生命周期去管理项目逻辑,而无需强加给另一个饱含类,以致纪念额外自定义的生命周期。
而与此同时作为单身的View层,大家的视图能够未有丝毫改动的传递给Presenter(不管是Activity恐怕Fragment卡塔尔国,而无需改任何代码。对于三个开销公司,完全能够将View层的事物交给壹人编写,而将事情达成交给另壹个人编写。而随着逻辑变化对View的改造,只要求经过Presenter层的包括二个代理对象————ViewDelegate来操作相应的改换方法就够了。

<LinearLayout xmlns:andro xmlns:bind="http://robobinding.org/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="org.robobinding.androidmvvm.MainActivity" tools:ignore="MissingPrefix"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" bind:text="{hello}"/> //单向绑定,修改Model属性时,会自动反映到视图中(需要实体中提供相应的getHello(),setHello。 <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Name:"/> <EditText android:layout_width="fill_parent" android:layout_height="wrap_content" bind:text="${name}"/> //双向绑定,修改model属性时,会自动反映到视图中;反过来,修改视图内容,也会自动更改Model的相关属性。 </LinearLayout> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Say Hello" bind:onClick="sayHello"/></LinearLayout>

TheMVP原理介绍

与金钱观androidMVP不相同(原因上文已经说了卡塔尔,TheMVP使用Activity作为Presenter层来管理代码逻辑,通过让Activity包括叁个ViewDelegate对象来直接操作View层对外提供的方式,进而产生完全解耦视图层。如下图:
澳门新葡萄京娱乐场 2

** Model层:PresentationModel() **

TheMVP代码表明

要将Activity作为Presenter来写,须要让View变得可复用,必须解决的多少个标题正是setContentView(State of Qatar怎么样调用,因为它是Activity(Fragment有像样卡塔尔国的方法。
我们须要把视图分离出来独立完成。能够定义贰个接口,来限制View层必需完毕的章程(那几个接口定义,也便是View层的代办对象卡塔尔(قطر‎,举例:

public interface IDelegate {
    void create(LayoutInflater i, ViewGroup v, Bundle b);
    View getRootView();
}

率先通过inflater一个搭架子,将这一个构造调换来View,再用getRootView(卡塔尔方法把这一个View再次回到给Presenter层,让setContentView(view卡塔尔国去调用,那样就兑现了rootView的独自。
之所以,在Presenter层,大家的兑现应有是:

protected void onCreate(Bundle savedInstanceState) {
    //获取到视图层对象
    IDelegate viewDelegate = xxx;
    //让视图层初始化(如果是Fragment,就需要传递onCreateView方法中的三个参数)
    viewDelegate.create(getLayoutInflater(), null, savedInstanceState);
    //拿到初始化以后的rootview,并设置content
    setContentView(viewDelegate.getRootView());
}
public class PresentationModel implements HasPresentationModelChangeSupport { private PresentationModelChangeSupport changeSupport; private String name; public PresentationModel() { changeSupport = new PresentationModelChangeSupport; } public String getHello() { return name + ": hello Android MVVM(Presentation Model)!"; } public String getName() { return name; } public void setName(String name) { this.name = name; Log.d("model", "setName(),name: " + name); } public void sayHello(){ changeSupport.firePropertyChange; } @Override public PresentationModelChangeSupport getPresentationModelChangeSupport() { return changeSupport; }}

结合DataBinding

三个好的结构一定是对扩充开放,对校订关闭的,那是软件设计方式的开闭原则。
万生龙活虎您后边有打探过谷歌的DataBinding,你势必通晓ViewModel的定义。DataBinding
驱除了 Android UI
编制程序中的贰个痛点,正是要给叁个控件设置剧情,必须首先获得到控件的靶子,并调用set方法(比如setText(卡塔尔卡塔尔(قطر‎,传二个数额进去。
DataBinding允许你利用那样的代码为控件设置剧情。

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

中间user.lastName表示在项目中的数据类的user对象的lastName属性。

**Controller层: **

DataBinding存在的难题

可是选用 Data Binding 之后,xml的布局文件就不再仅仅地体现 UI
成分,还亟需定义 UI 元素用到的变量。所以,它的根节点不再是三个
ViewGroup,而是成为了 layout ,何况新添了二个节点 data

<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable name="user" type="com.xxx.User" />
    </data>
    <!--原先的根节点(Root Element)-->
    <LinearLayout>
    ....
    </LinearLayout>
</layout>

接下来还非得在 onCreate() 方法中,用 DatabindingUtil.setContentView()
来替换掉 setContentView(),然后成立叁个 user 对象,通过
binding.setUser(user) 与 variable 实行绑定。

protected void onCreate(Bundle savedInstanceState) {
    ActivityBasicBinding binding = DataBindingUtil.setContentView(
            this, R.layout.activity_basic);
    User user = new User();
    binding.setUser(user);
}

就算简化了试图与数据绑定的代码,但同期也就义了构造文件的可复用性。举例大家平时会境遇的,二个Fragment与另贰个Fragment,在构造上完全意气风发致,而单单是数额差异,此时我们平日会用代码去调整在分歧的分界面突显差异的数额。然而,若是将数据写死在xml中,就错失了结构的复用性。
所以,我们可以尝试将视图与数据模型绑定的逻辑抽取,单独创立三个类来使用代码调控,那样生机勃勃旦产生雷同的界面复用,只必要重写视图与数量绑定的逻辑就够了,别的的代码照旧不变。

public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); PresentationModel presentationModel = new PresentationModel(); ViewBinder viewBinder = createViewBinder(); View rootView = viewBinder.inflateAndBind(R.layout.activity_main, presentationModel);//将model和view进行绑定 setContentView; } private ViewBinder createViewBinder() { BinderFactory reusableBinderFactory = new BinderFactoryBuilder; return reusableBinderFactory.createViewBinder; }}

为Presenter添加ViewModel的功能

概念二个ViewModel层的接口,当中富含八个泛型分别为View层的代理和Model层的代理:

public interface DataBinder<T extends IDelegate, D extends IModel> {
    /**
     * 将数据与View绑定,这样当数据改变的时候,框架就知道这个数据是和哪个View绑定在一起的,就可以自动改变ui
     * 当数据改变的时候,会回调本方法。
     *
     * @param viewDelegate 视图层代理
     * @param data         数据模型对象
     */
    void viewBindModel(T viewDelegate, D data);
}

为咱们事前写好的Presenter增加扩充,使它亦可帮忙DataBinder。个中使用getDataBinder(卡塔尔(قطر‎方法,拿到开荒中现实的某部分界面包车型客车ViewModel层的扩大,然后大家只须要在数据变动的时候,手动调用notifyModelChanged(卡塔尔方法,就可以使ViewModel中定义的绑定逻辑生效:

public abstract class DataBindActivity<T extends IDelegate> extends
        ActivityPresenter<T> {
    protected DataBinder binder;

    public abstract DataBinder getDataBinder();

    public <D extends IModel> void notifyModelChanged(D data) {
        binder.viewBindModel(viewDelegate, data);
    }
}

从代码能够看看,罗布obinding移除了如addXXListener(卡塔尔,findViewById(卡塔尔国等代码,有一些儿肖似Annotation框架,简练了Activity结构,使得代码更便于阅读,维护,选拔了源代码生成的方法来代表java反射,所以不会有反射额外的性情费用。

双向绑定

同期选取以代码调控的逻辑,能够轻易实现视图改造多少,数据变动视图的双向绑定。那是专门的学业的ViewModel所一定会有所而前天的Beta版
DataBinding 不能成功的效用。
刚刚的DataBinder接口已经贯彻的是 Model->View
的单向绑定,那么大家只必要为其丰裕一个 View-> Model
的方法,来让实际分界面包车型大巴ViewModel层达成类来清除之中的逻辑就可以。

public interface DataBinder<T extends IDelegate, D extends IModel> {
    void viewBindModel(T viewDelegate, D data);

    /**
     * 将数据与View绑定,这样当view内容改变的时候,框架就知道这个View是和哪个数据绑定在一起的,就可以自动改变数据
     * 当ui改变的时候,会回调本方法。
     *
     * @param viewDelegate 视图层代理
     * @param data         数据模型对象
     */
    void modelBindView(T viewDelegate, D data);
}

唯恐你会有疑问,既然是MVP情势的档案的次序,还又加ViewModel层,岂不是非驴非马?这里须要验证的是大家的构造近来照例是MVP方式的,你能够看作是在Presenter中,大家极度增添了贰个措施,然后大家只在这里个艺术中写
setText(卡塔尔、setImageResource(卡塔尔 那类对控件设值的秘技。
此刻,大家的体系协会如下图:
澳门新葡萄京娱乐场 3

android官方匡助的databinding框架使用应用法则:

让MVP变得好用

  • android studio 1.3及以上版本
  • gradle 2.2及以上版本
  • android plugin for gradle 1.3.0及以上版本

利用泛型解耦

当今我们是兑现了View与Presenter的解耦,在onCreate中富含了一个接口对象来落到实处大家一定的某些亟须方法。不过又引入了难题:一些一定措施没办法引用了。譬喻有些分界面包车型客车设值、控件的修正显示逻辑对Presenter层的接口,接口对象必需强转成具体子类手艺调用。
解决办法:可以由此泛型来肃清直接引用具体对象的题目。譬如大家得以在子类定义现在分明叁个Presenter中所引用的Delegate的实际品种。例如:

public abstract class ActivityPresenter<T extends IDelegate> extends Activity {
    protected T viewDelegate;

    protected void onCreate(Bundle savedInstanceState) {
        viewDelegate = getDelegateClass().newInstance();
    }

    protected abstract Class<T> getDelegateClass();
}

这么大家在ActivityPresenter的世袭类中就可以通过动态设置getDelegateClass(卡塔尔的再次回到值来明确Delegate的现实性品种了。

使用手续:

证明伊始化控件

不满的是不可能使用编译时注脚绑定控件,举个例子Butterknife;可是你照样能够使用运维时注脚,比如afinal。可是也不推荐使用运转时表明,终归通过反射去初阶化控件会很费时间。
自然,化解办法也是一些:便是透过定义findViewById(卡塔尔(قطر‎泛型类类型再次回到值,那样大家就不用写那又臭又长的函数名加强转了。

public <T extends View> T bindView(int id) {
    T view = (T) mViews.get(id);
    if (view == null) {
        view = (T) rootView.findViewById(id);
        mViews.put(id, view);
    }
    return view;
}

public <T extends View> T get(int id) {
    return (T) bindView(id);
}
  1. 在品种顶层build.gradle中加多以下重视:

设置监听

与此同一时候你也得以三次对五个控件设置监听事件,举例那样同不经常常间对button1,button2,button3安装监听器listener

viewDelegate.setOnClickListener(listener, R.id.button1, R.id.button2, R.id.button3);

它的里边贯彻也很简短,便是使用了变参函数

public void setOnClickListener(OnClickListener l, int... ids) {
        if (ids == null) {
            return;
        }
        for (int id : ids) {
            get(id).setOnClickListener(l);
        }
    }

行使变长数组营造View集结

鉴于Presenter在应用访谈View的时候并非直接调用,而是经过代理对象直接调用,假诺大家在落成View层代码的时候有太多的控件必要被引述,只怕就非得定义一大堆控件申明,会促成回忆担负。
那个时候明显通过id去记念更便于一些。我们得以运用SparseArray它是由七个数组来代表Map操作的类(如若你照旧不通晓他是干嘛的,可以大概的真是HashMap卡塔尔(قطر‎。

组合地点的全方位例证,可以为IDelegate接口定义三个抽象类,将全数的工具方法都合併进来

public abstract class AppDelegate implements IDelegate {
    protected final SparseArray<View> mViews = new SparseArray<View>();

    protected View rootView;

    public abstract int getRootLayoutId();

    @Override
    public void create(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        int rootLayoutId = getRootLayoutId();
        rootView = inflater.inflate(rootLayoutId, container, false);
    }

    @Override
    public View getRootView() {
        return rootView;
    }

    public <T extends View> T bindView(int id) {
        T view = (T) mViews.get(id);
        if (view == null) {
            view = (T) rootView.findViewById(id);
            mViews.put(id, view);
        }
        return view;
    }

    public <T extends View> T get(int id) {
        return (T) bindView(id);
    }

    public void setOnClickListener(View.OnClickListener listener, int... ids) {
        if (ids == null) {
            return;
        }
        for (int id : ids) {
            get(id).setOnClickListener(listener);
        }
    }
}
dependencies { classpath "com.android.databinding:dataBinder:1.0-rc1"}

简单Demo

  • 全体的德姆o源码已经交付在了连串中,你能够在这里查看,运维名字为demo的module。
    这里仅取两个简约的演示。首先是View层的贯彻

public class SimpleDelegate extends AppDelegate {
    @Override
    public int getRootLayoutId() {
        return R.layout.delegate_simple;
    }

    @Override
    public void initWidget() {
        super.initWidget();
        TextView textView = get(R.id.text);
        textView.setText("在视图代理层创建布局");
    }

    public void setText(String text) {
        //get(id)等同于bindview(id),从上文就可以看到了,get方法调用了bindview方法
        TextView textView = get(R.id.text);
        textView.setText(text);
    }
}

跟着是Presenter层的得以达成

/**
 * 在这里做业务逻辑操作,通过viewDelegate操作View层控件
 */
public class SimpleActivity extends ActivityPresenter<SimpleDelegate> implements OnClickListener {

    @Override
    protected Class<SimpleDelegate> getDelegateClass() {
        return SimpleDelegate.class;
    }

    /**
     * 在这里写绑定事件监听相关方法
     */
    @Override
    protected void bindEvenListener() {
        super.bindEvenListener();
        viewDelegate.get(R.id.button1).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button1:
                viewDelegate.setText("你点击了button");
                break;
        }
    }
}
  1. 在供给接受databinding的moudle中增添

参照小说

《MVC, MVP,
MVVM比较以致界别》作者Justrun
《android完结MVP的新思路》译者FTExplore

至于小编

kymjs张涛,Android 高工。
博客:
GitHub:

apply plugin: 'com.android.databinding'

** 注意:**在品种编写翻译进程中,会现身诸如以下错误:错误生机勃勃:

Error:Application and test application id cannot be the same: both are 'com.fengjr.mobile' for qihuDebugAndroidTest

这里供给test的application id和花色id无法平等,需将test
的id(即testApplicationId
“com.fengjr.mobile”匡正为”com.fengjr.mobile.test”卡塔尔

示例1:

view 文件 activity_main.xml:<?xml version="1.0" encoding="utf-8"?><layout xmlns:andro> <data> <variable name="stu" type="com.fengjr.mobile.databind.Student" /> //指明该view文件要绑定的数据模型 </data> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{stu.name}"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{stu.addr}"/> </LinearLayout></layout>

** Model文件:**

package com.fengjr.mobile.databind;/** * Created by gaoge on 15/9/22. */public class Student { private final String name; private final String addr; public Student(String name, String addr) { this.name = name; this.addr = addr; } public String getName() { return name; } public String getAddr() {return this.addr; }}

** 绑定过程:TestDataBindingActivity **

public class TestDataBindingAct extends Activity{@Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); ActivityMainBinding binding=DataBindingUtil.setContentView(this,R.layout.activity_main); binding.setStu(new Student("姓名", "地址")); //将Model和view(xml文件进行绑定) }}

在mobile module 的build.gradle文件中扬言 apply
“com.android.databinding”后,android编写翻译系统会自动依照xml文件名称”activity_main”生成八个ActivityMainBinding的class
文件(生成文书的命名格式和xml生龙活虎风流罗曼蒂克对应State of Qatar可是项目中这段日子利用到google
annotation注释框架,且apt的本子是1.4,会和databinding编写翻译进度冲突,产生databinding无法自动生成ActivityBinding文件,需求在mobile
module的build.gradle文件中,将classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
改为classpath 'com.neenbedankt.gradle.plugins:android-apt:1.7'附apt和databinding冲突小说:

改造Model后自动更新UI,能够透过二种格局完结:

  1. 让Model实体世袭自BaseObservable,并且对相应的天性的get(卡塔尔国方法扩展@Bindable讲解,在set(卡塔尔方法中加进notifyPropertyChanged()属性,示例:

public class Student extends BaseObservable {private String name; public Student() {}public Student(String name) {this.name = name; }@Bindable public String getName() {return name; }public void setName(String name) {this.name = name; notifyPropertyChanged; }}
  1. 对此Model属性,使用google
    设计的扶助监听的数据类型ObservableFields(满含ObservableField ,ObservableBoolean ,ObservableByte ,ObservableChar ,ObservableShort ,ObservableInt ,ObservableLong,ObservableArrayMap,ObservableArrayList)

public class People { public ObservableField<String> name = new ObservableField<>(); public ObservableInt age = new ObservableInt(); public ObservableBoolean isMan = new ObservableBoolean(); } 

发表评论

电子邮件地址不会被公开。 必填项已用*标注