Jetpack架构组件DataBinding

Jetpack架构组件DataBinding

    • 基本使用
      • datading 入门使用
      • 单向数据绑定视图
        • BaseObservable
        • ObservableField
        • ObservableCollection
      • 双向数据绑定
      • 事件绑定
      • RecycleView
        • Activty类
        • xml
        • MainViewModel类

基本使用

通常情况下Jetpack组件都是混合一起使用的,这里我们为了讲解,可能会单独使用。

前一篇中我们讲解了ViewModel,终于要介绍大Boos组件DataBinding。
DataBinding是Android上MVVM实现最强大的组件,是 MVVM 模式在 Android 上的一种实现,用于降低布局和逻辑的耦合性,使代码逻辑更加清晰。DataBinding 能够省去我们一直以来的 findViewById() 步骤,大量减少 Activity 内的代码,数据能够单向或双向绑定到 layout。

来看一下怎么使用

datading 入门使用

build.gradle中添加对Databinding的支持。

android {
    ...
    dataBinding {
        enabled = true
    }
}

打开布局文件,选中根布局,按住 Alt + 回车键,点击 “Convert to data binding layout”,就可以生成 DataBinding 需要的布局规则。

Jetpack架构组件DataBinding_第1张图片

单向数据绑定视图


<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <import type="cn.iwcode.androidjetpack.databind1.UserBean" />
        <variable
            name="userInfo"
            type="UserBean" />
    data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".databind1.DataBindActivity1">

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

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

layout 标签将原布局包裹了起来,data 标签用于声明要用到的变量以及变量类型。

每个绑定的布局都会生成一个绑定类,ViewDataBinding 的实例名是根据布局文件名来生成,将之改为首字母大写的驼峰命名法来命名,并省略布局文件名包含的下划线。控件的获取方式类似,但首字母小写。

也可以通过class自定义ViewDataBinding实例名

<data class="CustomBinding">

data>
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
//        setContentView(R.layout.activity_data_bind_1);

    ActivityDataBind1Binding viewDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_data_bind_1);

    UserBean userBean = new UserBean();
    userBean.name = "ygs";
    userBean.phoneNUmber = "18612345678";

    viewDataBinding.setUserInfo(userBean);
}

简单的Model绑定后,如果数据改变并不会让UI自动更新,而我们希望数据改变时,实时刷新UI。

实现数据变化自动驱动 UI 刷新的方式有三种:BaseObservable、ObservableField、ObservableCollection

BaseObservable

BaseObservable有 notifyChange() 和 notifyPropertyChanged() 两个方法刷新数据,

  • notifyChange 刷新所有的字段。
  • notifyPropertyChanged只刷新BR的静态字段,使用@Bindable注解可以生成BR的静态字段。
public class UserBean extends BaseObservable {

    //如果是 public 修饰符,则可以直接在成员变量上方加上 @Bindable 注解
    //如果是 private 修饰符,则在成员变量的 get 方法上添加 @Bindable 注解
    @Bindable
    public String name;

    public String phoneNUmber;

    public int age;

    //更新所有的字段
    public void setAll(String name, String phoneNUmber, int age) {
        this.name = name;
        this.phoneNUmber = phoneNUmber;
        this.age = age;
        notifyChange();
    }
    
    // 只更新name字段
    public void setName(String name) {
        this.name = name;
        notifyPropertyChanged(BR.name);
    }

    public void setPhoneNUmber(String phoneNUmber) {
        this.phoneNUmber = phoneNUmber;
    }
}

在调用setName方法是只更新name字段,而setAll会更新所有的字段。

ObservableField

手动去调用notifyPropertyChanged太麻烦,官方提供了ObservableField包装类。

ObservableField是对 BaseObservable 中字段的注解和刷新等操作的封装,官方原生提供了对基本数据类型的封装,例如 ObservableBoolean、ObservableByte、ObservableChar、ObservableShort、ObservableInt、ObservableLong、ObservableFloat、ObservableDouble 以及 ObservableParcelable ,也可通过 ObservableField 泛型来申明其他类型。

public class UserBean extends BaseObservable {

    public ObservableField<String> name;

    public ObservableField<String> phoneNUmber;

    public ObservableField<Integer> age;

    public void setAll(String name, String phoneNUmber,int age) {
        this.name.set(name);
        this.phoneNUmber.set(phoneNUmber);
        this.age.set(age);
    }

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

ObservableCollection

这个主要是提供对list和map的包装,如ObservableArrayMap,ObservableArrayList。

双向数据绑定

  • 单向绑定:数据改变时 同时视图刷新。
  • 双向绑定:数据改变时 同时视图刷新,视图改变时,也刷新数据

双向绑定给单向绑定就多了一个等号android:text="@={userInfo.phoneNUmber},很简单吧:


事件绑定

我们新建一个事件的类,写几个事件的回调方法:

public class EventViewModel extends ViewModel {

    public void onNameClick(UserBean user){
        Logger.i(user);
    }

    public void onNameClick(View view){
        Logger.i(view);
    }

    public void afterTextChanged(Editable s){
        Logger.i("afterTextChanged: "+s.toString());
    }
}

对应的xml




    
        
        

        
        
    

    

        

        

        

        

    

可以看见有3中写法

  • eventViewModel.onNameClick
  • eventViewModel::onNameClick
  • Lambda表达式 ()->eventViewModel.onNameClick(userInfo)

RecycleView

我们来看看databind与Recycleview的简单使用。

Activty类

ActivityDataBind5Binding viewDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_data_bind_5);

MainViewModel viewModel = ViewModelProviders.of(this).get(MainViewModel.class);

viewDataBinding.setViewModel(viewModel);

xml


<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:binding="http://schemas.android.com/apk/res-auto"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

        <import type="cn.iwcode.androidjetpack.databind5.MainViewModel" />

        <variable
            name="viewModel"
            type="MainViewModel" />
    data>

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

        <androidx.recyclerview.widget.RecyclerView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:adapter="@{viewModel.adapter}"
            android:layoutManage="@{viewModel.layoutManage}"/>
    LinearLayout>
layout>

MainViewModel类

public class MainViewModel extends ViewModel {

    private RecycleAdapter adapter ;

    private ObservableArrayList<UserBean> listData = new ObservableArrayList<>();

    private void loadData(){
        for (int i = 0;i < 20 ; i++){
            UserBean userBean = new UserBean();
            userBean.name = "ygs-"+i;
            userBean.phoneNUmber = "18612345678";
            userBean.headUrl = "https://avatars1.githubusercontent.com/u/5112053?s=460&v=4";
            userBean.des = "这是描述, 这是描述, 这是描述, 这是描述, 这是描述, 这是描述, 这是描述, 这是描述, 这是描述"+i;
            listData.add(userBean);
        }
    }

    public RecyclerView.LayoutManager layoutManage(){
        return new LinearLayoutManager(APP.mContext);
    }

    public RecycleAdapter adapter(){
        adapter = new RecycleAdapter(listData, APP.mContext);
        loadData();
        return adapter;
    }
}

后面就不贴代码了,有兴趣可以去看一下

你可能感兴趣的:(Android,移动开发,安卓)