美文网首页
MVVM模式之databinding(一)

MVVM模式之databinding(一)

作者: 源来是你啊 | 来源:发表于2017-10-14 16:35 被阅读0次

1.介绍

dataBinding对android视图的数据绑定十分友好,并且支持视图与数据的双向绑定,大大简化了传统的mvc模式的数据绑定和代码量,降低代码耦合。
databinding性能优越,比传统的注解框架性能优越,甚至比findViewById性能更好,并且用法简单。

1.使用方法

1.1开启DataBinding支持
android {
    ...
    dataBinding{
        enabled = true;
    }
}
1.2定义ViewModel

ViewModel 就相当于一个bean,这里string类型就是绑定text文本,而绑定图片则需要用到@BindingAdapter("属性")注解一个静态函数。

package com.example.lihao.mvvm_test;

import android.databinding.BaseObservable;
import android.databinding.Bindable;
import android.databinding.BindingAdapter;
import android.databinding.ObservableField;
import android.os.StrictMode;
import android.widget.ImageView;

import com.squareup.picasso.Picasso;

/**
 * Created by lihao on 17-10-14.
 */

public class UserModel {

    private String url = "";

    private String title = "";

    private String des = "";


    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }


    public String getTitle() {
        return title;
    }


    public void setTitle(String title) {
        this.title = title;
    }


    public String getDes() {
        return des;
    }

    public void setDes(String des) {
        this.des = des;
    }

    //相当于自定义一个属性
    @BindingAdapter("imageSrc")
    public static void getImage(ImageView iv, String url){
        Picasso.with(iv.getContext()).load(url).placeholder(R.mipmap.ic_launcher).into(iv);
    }
  //点击事件处理
  public void onItemClick(View view){
        Toast.makeText(view.getContext(),getTitle(),Toast.LENGTH_SHORT).show();
    }
}
1.3定义view

这里的View指的是布局文件和databinding绑定数据

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

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

    <data>
        <variable
            name="userModel"
            type="com.example.lihao.mvvm_test.UserModel"/>

    </data>

    <LinearLayout
        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:orientation="horizontal"
        android:onClick="@{userModel.onItemClick}"
        tools:context="com.example.lihao.mvvm_test.MainActivity">

        <ImageView
            android:id="@+id/iv_pic"
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:scaleType="centerCrop"
            app:imageSrc="@{userModel.url}"/>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
            <TextView
                android:id="@+id/tv_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{userModel.title}"/>

            <TextView
                android:id="@+id/tv_des"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{userModel.des}"/>
        </LinearLayout>

    </LinearLayout>

</layout>

这里文本的绑定就用属性家@绑定,值得注意的是布局文件需要用layout包裹,并用<data>节点传递对应类型的数据,例如<variable>节点下,name是数据变量名,引用数据的,而type是ViewModel的全包名。绑定图片就用自定义属性并传入对应的链接即可。事件点击则和text文本注解引用类似。

1.4调用方法

在主函数的oncreate方法中加入一下代码

        UserModel userModel = new UserModel();//创建viewModel
        userModel.setUrl("http://www.baidu.com/img/bd_logo1.png");//设置数据
        userModel.setTitle("测试");
        userModel.setDes("这是dataBinding");

        ActivityMainBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_main);//绑定布局文件,这里替代了传统的setContentView

        binding.setUserModel(userModel);//视图绑定数据

布局文件被layout绑定以后,会生成一个对应的绑定布局类型,这里的ActivityMainBinding就是被layout包裹后生成的类型,如果报错,rebuild一下就好。

1.5效果图
2017-10-14 21-45-04屏幕截图.png

绑定ListView

如果以上没有让你感受到databinding的优点,那么以下对ListView绑定会让你觉得惊艳

ViewModel
package com.example.lihao.mvvm_test;

import android.databinding.BaseObservable;
import android.databinding.Bindable;
import android.databinding.BindingAdapter;
import android.databinding.ObservableField;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import com.squareup.picasso.Picasso;

/**
 * Created by lihao on 17-10-14.
 */

public class NewsModel extends BaseObservable {

    private final ObservableField<String> img = new ObservableField<>();
    private final ObservableField<String> keywords = new ObservableField<>();
    private final ObservableField<String> des = new ObservableField<>();

    public NewsModel(String img,String keyword,String des){
        this.img.set(img);
        this.keywords.set(keyword);
        this.des.set(des);

    }

    @BindingAdapter("img")
    public static void getImage(ImageView iv,String img){
        Picasso.with(iv.getContext()).load(img).into(iv);
    }

    //如果有动态改变数据的需在get方法加上@Bindable
    @Bindable
    public String getImg(){
        return this.img.get();
    }

    public void setImg(String img){
        this.img.set(img);
    }

    @Bindable
    public String getKeywords(){
        return this.keywords.get();
    }

    public void setKeywords(String keywords){
        this.keywords.set(keywords);

        notifyPropertyChanged(BR.keywords);//再次更新,与bdindable连用
    }

    @Bindable
    public String getDes(){
        return this.des.get();
    }

    public void setDes(String des){
        this.des.set(des);
    }

    public void onItemClick(View view){
        Toast.makeText(view.getContext(), "条目被点击", Toast.LENGTH_SHORT).show();
    }

    public void onTitleClick(View view){
        setKeywords("标题被点击");
    }
}
View
<?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">

    <data>
        <variable
            name="NewsModel"
            type="com.example.lihao.mvvm_test.NewsModel" />
    </data>

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="80dp">

        <ImageView
            android:id="@+id/tv_pic"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_gravity="center"
            android:scaleType="centerCrop"
            app:img="@{NewsModel.img}"/>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="80dp"
            android:orientation="vertical"
            android:onClick="@{NewsModel.onItemClick}"
            android:gravity="center">
            <TextView
                android:id="@+id/tv_keywords"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textStyle="bold"
                android:onClick="@{NewsModel.onTitleClick}"
                android:text="@{NewsModel.keywords}"/>

            <TextView
                android:id="@+id/tv_des"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dp"
                android:text="@{NewsModel.des}"/>
        </LinearLayout>

    </LinearLayout>

</layout>
效果图
2017-10-14 22-50-22屏幕截图.png

小结

由dataBinding的支持的双向数据绑定,简化了大部分数据操作,事件处理降低代码耦合,省去了诸多findViewById操作,简洁代码,提高性能。

善意提醒:databinding的使用虽然简单,但前外不可粗心,很容易出错,但不以找出错误,如一直出现databinding找不到,有两种可能,一种是没有rebuild,另一种是xml布局文件写错了。

相关文章

网友评论

      本文标题:MVVM模式之databinding(一)

      本文链接:https://www.haomeiwen.com/subject/idbxuxtx.html