美文网首页
在Android应用程序中使用数据绑定

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

作者: BlueSocks | 来源:发表于2022-11-25 21:31 被阅读0次

    本教程介绍数据绑定在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

    相关文章

      网友评论

          本文标题:在Android应用程序中使用数据绑定

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