This is the 25th day of my participation in the August Genwen Challenge.More challenges in August

Android DataBinding Literacy Part 1

A few days ago, I discussed with a friend about a small program, and found that it was also using the mode of bidirectional binding. I said, our big Android has bidirectional binding for a long time. This article documents the process of implementing data binding for those of you who are not familiar with data binding.

What is DataBinding

In simple terms, DataBinding is a support library for data and UI binding, as well as a tool on which to implement the MVVM pattern.

The library was born in 2015, and the popularity of MVVM made more people know about it. Later, it was found that many front-end frameworks also have data binding technology, such as the small program I saw written like this:

_this.setData({
  treeData:[item]
}) 

Copy the code
 <view list='{{treeData}}' />
Copy the code

This way of writing is very similar to the way of writing in Android, maybe these languages are similar to deep down.

Implement simple DataBinding

DataBinding is a tool on which the MVVM architecture depends; You can omit the findViewById operation.

2.1 open the DataBinding

We just need to enable it in build.gradle of module, sample code

Android {compileSdkVersion 28 buildToolsVersion "28.0.3"... // Enable dataBinding dataBinding{enabled true}}Copy the code

2.2 Creating an Object

There’s nothing to talk about. A regular object

public class Person {

    private int id;
    private String name;
    private String sex;

    public Person() {
    }

    public Person(int id, String name, String sex) {
        this.id = id;
        this.name = name;
        this.sex = sex;
    }
    
    // get set
}
Copy the code

2.3 Modifying the Layout File

Change the Layout file to conform to the rules for data binding.

<? The XML version = "1.0" encoding = "utf-8"? > <layout xmlns:android="http://schemas.android.com/apk/res/android"> <! <data class="MainBinding"> <variable name="person" type="com.demo.mvvmdemo. person" /> </data> <! <LinearLayout Android :layout_width="match_parent" Android :layout_height="match_parent" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{String.valueOf(person.id)}" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{person.name}" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{person.sex}" /> </LinearLayout> </layout>Copy the code

Focus is to increase the < data > this tag, the class is to specify the binding name, after the activity, immediately after see don’t understand. Android :text=”@{string.valueof (person.id)} corresponds to the id property of the object we created.

2.4 Creating an Activity

public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // setContentView(R.layout.activity_main); MainBinding mainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main); Person Person = new Person(1, ""," "); mainBinding.setPerson(person); }}Copy the code

Replace the original setContentView with the display in the appeal code. Is ActivityMainBinding.

SetPerson is binding objects.

At this point, a simple data binding is complete.

3. Change the UI instantly

The above code has implemented data binding, but every time we change data and want to update the page, we need to re-call setData(Object) to update the attempt, which is obviously not convenient.

How to implement binding once, update data at any time update attempt

This scenario starts with the observer mode to see how it works.

3.1 Unidirectional binding method 1. BaseObservable is inherited

  1. Let objects inheritBaseObservable
  2. Add to each get method@Bindable
  3. Add to each set methodNotifyPropertyChanged (BR. Corresponding property)

Code sample

public class Person extends BaseObservable { private int id; private String name; private String sex; public Person() { } public Person(int id, String name, String sex) { this.id = id; this.name = name; this.sex = sex; } @Bindable public int getId() { return id; } public void setId(int id) { this.id = id; notifyPropertyChanged(BR.id); } @Bindable public String getName() { return name; } public void setName(String name) { this.name = name; notifyPropertyChanged(BR.name); } @Bindable public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; notifyPropertyChanged(BR.sex); }}Copy the code

Activity

public class MainActivity extends AppCompatActivity { Person person; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // setContentView(R.layout.activity_main); final ActivityMainBinding mainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main); Person = new person (1, ""," "); mainBinding.setPerson(person); new Handler().postDelayed(new Runnable() { @Override public void run() { person.setId(2); Person. Elegantly-named setName (" li si "); Person. SetSex (" female "); }}, 2000); }}Copy the code

Delay two seconds to refresh the data, after two seconds, the updated object properties, you can see the interface also refreshed.

3.1 Unidirectional Binding 2. Define the ObserverField object

  1. Changed the attributes of the entity class.
  2. The method also changes when setting properties.
person.getId().set(2); Person. GetName (). The set (" li si "); Person. GetSex (). The set (" female ");Copy the code

Let’s just look at the code.

Entity class

public class Person { public ObservableField<Integer> id = new ObservableField<>(); public ObservableField<String> name = new ObservableField<>(); public ObservableField<String> sex = new ObservableField<>(); public ObservableField<Integer> getId() { return id; } public void setId(ObservableField<Integer> id) { this.id = id; } public ObservableField<String> getName() { return name; } public void setName(ObservableField<String> name) { this.name = name; } public ObservableField<String> getSex() { return sex; } public void setSex(ObservableField<String> sex) { this.sex = sex; }}Copy the code

Activity

public class MainActivity extends AppCompatActivity { Person person; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // setContentView(R.layout.activity_main); final ActivityMainBinding mainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main); person = new Person(); mainBinding.setPerson(person); new Handler().postDelayed(new Runnable() { @Override public void run() { person.getId().set(2); Person. GetName (). The set (" li si "); Person. GetSex (). The set (" female "); }}, 2000); }}Copy the code

As you can see, the end result is the same.