在Android应用程序中使用数据绑定

2022-11-25  本文已影响0人  BlueSocks

本教程介绍数据绑定在Android应用程序中的用法,数据绑定允许将用户界面与应用程序模型和逻辑同步。

1.在Android应用中使用数据绑定

1.1.Android数据绑定介绍

Android提供了使用数据绑定编写声明性布局的支持。这将最小化应用程序逻辑中连接到用户界面元素所需的代码。

使用数据绑定需要更改布局文件。这样的布局文件以layout根标记后跟数据元素和view根元素。数据元素描述可用于绑定的数据看法元素包含根层次结构,类似于未用于数据绑定的布局文件。对布局中数据元素或表达式的引用使用@{}或@={} ,

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
   <data>
       <variable name="temp" type="com.vogella.android.databinding.TemperatureData"/> 
   </data>
   <LinearLayout 
       android:orientation="vertical"
       android:layout_width="match_parent"
       android:layout_height="match_parent">
       <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@{temp.location}"/>
       <TextView
        android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="@{temp.celsius}"/>
   </LinearLayout>
</layout>

数据中的用户变量描述了可在此布局中使用的属性。
普通视图层次结构
Android数据绑定生成Binding基于此布局初始化。此类保存来自布局属性的所有绑定,即定义的变量到相应的视图。它还为布局中的数据元素提供生成的setter。生成的类的名称基于布局文件的名称。此名称将转换为Pascal case和Binding添加后缀。例如,如果布局文件被调用activity_main.xml,则调用generate类 活动。您可以通过此类或DataBindingUtil class

TemperatureData temperatureData = // your data is created here
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
binding.setTemp(temperatureData); // generated setter based on the data in the layout file

你可以使用inflate方法。这对于在片段中使用数据绑定非常有用,ListView或RecyclerView .

ActivityMainBinding binding = ActivityMainBinding.inflate(getLayoutInflater(), container, attachToContainer);
// get the root view
View view = binding.getRoot();
// do more stuff
TemperatureData temperatureData = // your data is created here
binding.setTemp(temperatureData); // generated setter based on the data in the layout file

还可以为RecyclerView、ViewPager或其他未设置Activity内容的事物进行布局。

1.2.在Android中启用应用程序绑定

要在Android应用程序中启用数据绑定,请将以下代码片段添加到app/build中。梯度文件。

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

1.3.通过侦听器绑定和方法引用进行事件的数据绑定

事件可以直接绑定到处理程序方法,类似于android:onClick可以分配给活动中的方法。事件属性名由侦听器方法的名称控制,但有一些例外。例如, View.OnLongClickListener有一个method onLongClick(),因此此事件的属性为android : onLongClick .

为了将一个事件分配给它的处理程序,使用一个普通的绑定表达式,其值为要调用的方法名。绑定表达式可以为视图分配单击侦听器。

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>
        <variable
            name="presenter"
            type="com.vogella.android.databinding.MainActivityPresenter"/>
    </data>


    <Button
            android:text="Start second activity"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="@{() -> presenter.showList()}"
            />

</layout>

您还可以通过android:onClick="@{handlers::onClickFriend}"/>。如果方法需要参数,也可以将数据对象传递给它们。例如:

android:onClick="@{(theView) -> presenter.onSaveClick(theView, task)}"

1.4.进口

也可以导入类以在数据绑定表达式中使用它们。

<data>
    <import type="com.example.MyStringUtils"/>
    <variable name="user" type="com.example.User"/>
</data>

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

1.5.使用数据模型的更改更新用户界面

任何普通的旧Java对象(POJO)都可以用于数据绑定。但是,如果数据模型中的更新也应更新用户界面,则对象必须能够通知数据更改。有三种不同的数据更改通知机制:observable objects;observable fields;*observable collections

Android提供BaseObservable可以扩展的类。数据类负责在属性更改时通知。这是通过分配@可装订注释getter和setter中的notifying。

package com.vogella.android.databinding;


import android.databinding.BaseObservable;
import android.databinding.Bindable;

import java.util.Observable;

public class TemperatureData extends BaseObservable {
    private String celsius;

    public TemperatureData(String celsius) {
        this.celsius = celsius;
    }

    @Bindable                            
    public String getCelsius() {
        return celsius;
    }

    public void setCelsius(String celsius) {
        this.celsius = celsius;
        notifyPropertyChanged(BR.celsius);         
    }
}

定义相关的getter
通知所有侦听器,BR.cellsius是生成的类
每次更新时都会调用此侦听器,并更新相应的视图。这样可以确保模型中的更新也更新UI。

或者,为了创建一个可观察的类,还可以使用ObservableField以及属性的子类

private class TemperatureData {
   public final ObservableField<String> celsius = new ObservableField<>();
   public final ObservableField<String> location =  new ObservableField<>();
}

要访问代码中的此类字段,请使用set和get方法

temp.location.set("Hamburg");
String celsius  = temp.celsius.get();

1.6.使用BindingAdapter的自定义转换器

有时您必须执行复杂的数据转换。为此,您可以通过静态@BindingAdapter方法。此方法可以放置在代码中的任何位置,并且可以覆盖字段到数据模型的默认转换。

例如,假设要将数据模型的字段分配给图像视图。

  <ImageView
            android:id="@+id/icon"
            android:layout_width="40dp"
            android:layout_height="fill_parent"
            android:layout_alignParentBottom="true"
            android:layout_alignParentTop="true"
            android:layout_marginRight="6dip"
            android:contentDescription="TODO"
            android:src="@{obj.url}"
            />

您可以在上注册此属性ImageView使用以下方法。此方法使用滑翔下载图像

@BindingAdapter("android:src")
    public static void setImageUrl(ImageView view, String url) {
        Glide.with(view.getContext()).load(url).into(view);
    }

2.练习:在Android应用程序中使用数据绑定

在本练习中,您将学习如何使用数据绑定在用户界面小部件之间进行交互。

2.1.激活数据绑定的使用

打开您的应用程序/内部版本.gradle文件并激活数据绑定的使用。

apply plugin: 'com.android.application'

android {

    dataBinding {
        enabled = true
    }

    .... [REST AS BEFORE...]

2.2.为视图交互创建类
创建以下类

package com.vogella.android.databinding;


import android.databinding.BaseObservable;
import android.databinding.Bindable;

public class TemperatureData extends BaseObservable {
    private String location;
    private String celsius;

    public TemperatureData(String location, String celsius) {
        this.location = location;
        this.celsius = celsius;
    }

    @Bindable
    public String getCelsius() {
        return celsius;
    }

    @Bindable
    public String getLocation() {
        return location;
    }

    public  void setLocation(String location){
        this.location = location;
        notifyPropertyChanged(BR.location);
    }

    public void setCelsius(String celsius) {
        this.celsius = celsius;
        notifyPropertyChanged(BR.celsius);
    }

}

package com.vogella.android.databinding;


public interface MainActivityContract {
    public interface Presenter {
        void onShowData(TemperatureData temperatureData);
    }

    public interface View {
        void showData(TemperatureData temperatureData);
    }

}
package com.vogella.android.databinding;

import android.content.Context;

public class MainActivityPresenter implements MainActivityContract.Presenter {
    private MainActivityContract.View view;
    private Context ctx;

    public MainActivityPresenter(MainActivityContract.View view, Context ctx) {
        this.view = view;
        this.ctx = ctx;
    }

    @Override
    public void onShowData(TemperatureData temperatureData) {
        view.showData(temperatureData);
    }

}

2.3.调整布局文件和活动以使用数据绑定

将布局更改为以下内容。

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>
        <variable
            name="temp"
            type="com.vogella.android.databinding.TemperatureData" />
        <variable
            name="presenter"
            type="com.vogella.android.databinding.MainActivityPresenter"/>
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        >
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@={temp.location}"
            />
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@={temp.celsius}"
            />

        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="@={temp.celsius}" />

        <Button
            android:text="Show data model"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="@{() -> presenter.onShowData(temp)}"
            android:id="@+id/button" />

    </LinearLayout>
</layout>

调整活动代码以使用生成的数据绑定类。

package com.vogella.android.databinding;

import android.app.Activity;
import android.content.Intent;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.widget.Toast;

import com.vogella.android.databinding.databinding.ActivityMainBinding;

public class MainActivity extends Activity implements MainActivityContract.View {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        MainActivityPresenter mainActivityPresenter = new MainActivityPresenter(this, getApplicationContext());
        TemperatureData temperatureData = new TemperatureData("Hamburg", "10");
        binding.setTemp(temperatureData);
        binding.setPresenter(mainActivityPresenter);
    }

    @Override
    public void showData(TemperatureData temperatureData) {
        String celsius = temperatureData.getCelsius();
        Toast.makeText(this, celsius, Toast.LENGTH_SHORT).show();
    }

}

来自:https://www.vogella.com/tutorials/AndroidDatabinding/article.html

上一篇下一篇

猜你喜欢

热点阅读