Databinding框架简介

以前项目一直用MVC(Model View Controller)架构,最近又改为(Model View View Model),引用了Google力推的Databinding框架,可以堪称黑科技。减少了findViewId麻烦的实例化,优化了臃肿的controller层。XML布局与数据互绑,减少了很多逻辑与代码量,大大节约了开发周期。

本文主要介绍一些Databinding的常用方法,Google Databinding原地址Developer

最新的AS已经集成了databinding框架,只需在gradle配置文件中添加一下代码:

dataBinding {
    enabled = true
}

数据绑定

先看下常用用法,新建一个实体bean:

public class Student {
    private String name;
    private String age;

    public Student() {
    }

    public Student(String name, String age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
}
xml布局如下,@{}绑定数据源:

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

    <data>

        <variable
            name="bean"
            type="com.wms.databinding.Student" />
    </data>

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

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

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{bean.age}" />
    </LinearLayout>
</layout>
<variable
    name="bean"
    type="com.wms.databinding.Student" />

这句用来声明在布局中用的变量类型及变量名,然后配置参数:

ActivityMainBinding binding;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    binding= DataBindingUtil.setContentView(this,R.layout.activity_main);

    binding.setBean(new Student("张三","23"));
}

运行之后如上,你也可以通过inflate引入布局

binding = ActivityMainBinding.inflate(getLayoutInflater());

绑定viewgroup:

ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false);
ListItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false);
Databinding绑定点击事件:

一、无参的点击事件:

添加事件响应类:

public class Presenter{
    public void onShow(View view){
        Toast.makeText(MainActivity.this,"show",Toast.LENGTH_LONG).show();
    }
}

XML中配置绑定:

<variable
    name="presenter"
    type="com.wms.databinding.MainActivity.Presenter"/>
<Button
    android:onClick="@{presenter.onShow}"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

在onCreate中绑定事件:

binding.setPresenter(new Presenter());

二、带参的点击事件:

1.添加事件相应类:

public void onShow2() {
    Toast.makeText(MainActivity.this, "show2", Toast.LENGTH_LONG).show();
}
XML:

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="@{()->presenter.onShow2()}"
    android:text="show2" />
2.传递View写法:

public void onShow3(View view) {
    Toast.makeText(MainActivity.this, "show3", Toast.LENGTH_LONG).show();
    view.setVisibility(View.GONE);
}

XML:

<variable
    name="view"
    type="android.view.View" />
<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="@{(view)->presenter.onShow3(view)}"
    android:text="show3" />
3. 多参传递:

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick='@{()->presenter.onShow4(bean,"show4")}'
    android:text="show4" />
public void onShow4(final Student student,String msg) {
    Toast.makeText(MainActivity.this, student.getName()+"--"+msg, Toast.LENGTH_LONG).show();
}
方法引用:

通过binding可以在xml中引用jdk,sdk中的方法也可以引用自定义方法

XML先引入工具类:

<import type="com.wms.databinding.Util" />
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@{Util.getItem(bean)}" />
工具类:

public class Util {

    public static String getItem(Student item) {
        return item.getName() + "--" + item.getAge();
    }

}
常用表达式:

直接从官方copy过来了:

  • Mathematical + - / * %
  • String concatenation +
  • Logical && ||
  • Binary & | ^
  • Unary + - ! ~
  • Shift >> >>> <<
  • Comparison == > < >= <=
  • instanceof
  • Grouping ()
  • Literals - character, String, numeric, null
  • Cast
  • Method calls
  • Field access
  • Array access []
  • Ternary operator ?:

android:visibility="@{bean.name==null?View.GONE:View.VISIBLE}"
android:text="@{bean.name??bean.age}"
android:text="@{String.valueOf(bean.age+1)}"

BindingAdapter:

bingding框架添加了bindingAdapter注释,在XML中配置属性,然后Binding运行时会找到adapter下所属方法并运行,但是声明的方法必须为静态方法,所以在方法中引用的参数要么通过adapter去传递要么是static。BindingAdapter最常用的就是异步加载图片:
下面是相关代码:
@BindingAdapter("imgUrl")
public static void loadImg(ImageView view,String url) {
    Glide.with(view.getContext()).load(url).into(view);
}
XML中使用"app:attr"格式去配置参数:
<ImageView
    android:id="@+id/img"
    android:layout_width="200dp"
    android:layout_height="200dp"
    app:imgUrl='@{"http://img3.duitang.com/uploads/item/201509/24/20150924192932_ceu4a.thumb.700_0.jpeg"}'/>

提示:在用binding框架做数据绑定时xml中不要使用中文,如果引用中文可写在res/string中
android:text="@{bean.name+@string/chinese}"
在绑定数据时,需要加入为空判断,防止在控件初始化时没有赋值而导致空指针异常。


相关Demo已上次至git 源码在这

发布了10 篇原创文章 · 获赞 0 · 访问量 1万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览