欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android DataBinding 数据绑定

程序员文章站 2022-04-20 08:53:11
...

Android DataBinding

Databinding作为支持MVVM模式的一种数据绑定框架,类似ButterKnife取代findViewById,它可以直接在 layout 布局 xml 文件中绑定数据,接下来就从三个方面进行分析并写一个监视View层的数据变化来理解DataBinding框架。

  • 什么是DataBinding 数据绑定 (what)
  • 为什么要用DataBinding (why)
  • 怎么去用DataBinding (how)

what

谷歌Android 团队发布了一个数据绑定框架(Data Binding Library),官方原生支持 MVVM 模型,取代findViewById直接在 layout 布局 xml 文件中绑定数据,自动建立layout文件的java对象。对于MVVM模型中直接在ViewModel层中与View层进行数据绑定,为开发者提供一个结构清晰、方便分工合作、代码解耦,正是由于它会自动建立layout文件的java对象,所以它在项目中会比较沉重,但是整体利大于弊,是很不错的框架。

why

说它的几个优点就可以感受到它的强大

  • 完全能替代findViewById,会自动建立layout文件的java对象
  • 完全代替R.id.xx,解决复杂layout布局中找不到id的的问题
  • 只需要在ViewModel层中进行数据操作,View层就可以自动更新UI
  • 支持对一个或多个数据进行监听,更好的完成UI逻辑
  • 分层清晰,UI层和逻辑层解耦度大,后期维护性强

它还有一些优点就不一一赘述,就这些就够我们先用的,接下来我们通过一个View层监视数据变化来了解使用它。

how

Step 1

Gradle中进行配置

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

Step 2

定义一个实体类

public class User {
    private String name;

    public User(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

Step 3

在xml里通过–layout–、–data–进行实体数据的绑定,例如将User进行数据的绑定,用户可随意设定“user”,需要在View层控件中声明:android:text=”@{user.name]”。

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <!--dataBinding-->
    <data>
        <variable name="user" type="com.xxx.databinding.myapplication.User"/>
    </data>

    <!--View-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        >
    <TextView
        android:text="@{user.name}"
        android:textSize="24sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    </LinearLayout>

</layout>

写到这里时将项目Build一下,这时就会自动在build/intermediates/classes/debug/com/xxx/databinding下生成ActivityMainBinding.class文件,就这样就绑定成功了。

例如
activity_main => ActivityMainBinding
fragment_main =>FragmentMainBinding

MainActivity.java

在MainActivity中进行绑定,并设置一个用户,通过setUser()进行View层交互。
(activity 场合)

public class MainActivity extends AppCompatActivity {

    private User mUser;
    private ActivityMainBinding binding;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mUser=new User("Java");

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

(fragment场合)

public class MainFragment extends Fragment {

    private  FragmentMainBinding binding;
    private User mUser;
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        binding= DataBindingUtil.inflate(inflater,R.layout.fragment_main,container,false);
        mUser=new User("Java");

        return binding.getRoot();
    }
}

这就是在不同场合使用Databinding的情况。列子中先定义一个死数据“Java”进行代码演示。此时程序运行View层显示“java”。

Step 4

添加一个功能来通过点击按钮来改变View层的数据变化,定义事件处理程序。onChangeClick的参数应该与View.OnClickListener中的onClick的参数相同。

public interface ChangeViewHandlers {
    void onChangeClick(View view);
}

通过像User这样的变量在 variable 中描述,这样在每个视图中就可以使用。

    <!--dataBinding-->
    <data>
        <variable name="user" type="com.dhc.databinding.myapplication.User"/>
        <variable name="handlers" type="com.dhc.databinding.myapplication.ChangeViewHandlers"/>
    </data>

绑定点击事件,添加一个Button来进行点击操作与接口方法相关联 android:onClick=”@{handlers.onChangeClick}”。
activity_main.xml

    <Button
            android:id="@+id/change_btn"
            android:text="Change"
            android:onClick="@{handlers.onChangeClick}"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
           />

android:onClick与View.OnClickListener中onClick属性相对应。同样,View.OnLongClickListener中的onLongClick与android:onLongClick相对应。

点击事件的实现。在MainActivity中实现了接口并接受事件。打印日志。

MainActivity.java

public class MainActivity extends AppCompatActivity implements ChangeViewHandlers {

    private User mUser;
    private ActivityMainBinding binding;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mUser=new User("Java");

        binding= DataBindingUtil.setContentView(this,R.layout.activity_main);
        binding.setUser(mUser);
        binding.setHandlers(this);
    }

    @Override
    public void onChangeClick(View view) {

        Log.d("Debug","Change User name");
    }

}

log:D/Debug: Change User name

动态变更数据,点击按钮来进行数据的变更。完成后”Android”会显示在Log中,但是在页面View层还没有进行显示,因此要进行更改视图,以便监视对象。

public class MainActivity extends AppCompatActivity implements ChangeViewHandlers {

    private User mUser;
    private ActivityMainBinding binding;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mUser=new User("Java");

        binding= DataBindingUtil.setContentView(this,R.layout.activity_main);
        binding.setUser(mUser);
        binding.setHandlers(this);
    }

    @Override
    public void onChangeClick(View view) {
        Log.d("Debug","Change User name");
        mUser.setName("Android");
        Log.d("Debug",mUser.getName());
    }
}

log:D/Debug: Change User name
D/Debug: Android

Step 5

继承BaseObservable

继承BaseObservable,并对getter和setter进行修改,在getName()添加@Bindable来监视常量BR.name。将BR.name赋给setName(),当setter发生调用后,进行通知改变。

public class User extends BaseObservable{
    private String name;

    public User(String name) {
        this.name = name;
    }
    @Bindable
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
        notifyPropertyChanged(BR.name);
    }
}

此时,点击后,View层就显示为“Android”。

*使用ObservableField

如果不想用继承,另外一种方法来变更,注意它的字段类型是ObservableField。

public class User {

    public ObservableField<String> name=new ObservableField<>();

    public User(String name) {
        this.name.set(name);
    }
}

此时,点击后,View层就显示为“Android”。

总结

以上就是使用DataBinding简单的进行数据的绑定,通过一个点击事件来绑定数据,我们不用考虑它怎么使用,事件也不用考虑怎么发生的。将结构进行分离,通过数据绑定来实现View层的数据变化。

相关标签: android databinding