I have used data-binding for a while, even now it is not available for JDK 8 and API 24 now. I still find a way to use the data binding in a easier way. But when I use the following way to do the exact two-way data binding(In my mind, the two-way data binding is the thing like here(What is two way binding?), somethings strange is happened.
1. Two-way databinding(in xml)
android:text="@={testStr}"
This is not mentioned in the official documentation(https://developer.android.com/topic/libraries/data-binding/index.html, this page is usually updated, may be it is changed now). But it is available to bind the variable to the xml.
2. ObservableField for the attributes
Example from here (https://developer.android.com/topic/libraries/data-binding/index.html#observablefields)
private static class User {
public final ObservableField<String> firstName =
new ObservableField<>();
public final ObservableField<String> lastName =
new ObservableField<>();
public final ObservableInt age = new ObservableInt();
}
3. Extend the model class to the BaseObservable
private static class User extends BaseObservable {
private String firstName;
private String lastName;
@Bindable
public String getFirstName() {
return this.firstName;
}
@Bindable
public String getLastName() {
return this.lastName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
notifyPropertyChanged(BR.firstName);
}
public void setLastName(String lastName) {
this.lastName = lastName;
notifyPropertyChanged(BR.lastName);
}
}
The model class must be extended to the BaseObservable class, and also the getter method must be annotated with "@Bindable" and the setter method need to call the method notifyPropertyChange() with corresponding naming in the binding xml.
My question is, I would like to know the drawback and the advantages for three binding methods. Of course, I know the first one will be easier. But some moment I found in the documentation and in some website. And it disappeared in the next moment. The official documentation is changed without any clear announcement. I still wonder should I use the first method so I have to prepare to change the the method 2 or 3.
Student_XML2WAY.java
public class Student_XML2WAY {
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int pAge) {
age = pAge;
}
public String getName() {
return name;
}
public void setName(String pName) {
name = pName;
}
}
Student_ObserField.java
public class Student_ObserField {
private ObservableInt age;
private ObservableField<String> name;
public Student_ObserField() {
age = new ObservableInt();
name = new ObservableField<>();
}
public ObservableInt getAge() {
return age;
}
public ObservableField<String> getName() {
return name;
}
}
Student_Extend.java
public class Student_Extend extends BaseObservable{
private int age;
private String name;
@Bindable
public int getAge() {
return age;
}
public void setAge(int pAge) {
age = pAge;
notifyPropertyChanged(BR.student3);
}
@Bindable
public String getName() {
return name;
}
public void setName(String pName) {
name = pName;
notifyPropertyChanged(BR.student3);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="student1"
type="example.com.testerapplication.sp.bean.Student_XML2WAY"/>
<variable
name="student2"
type="example.com.testerapplication.sp.bean.Student_ObserField"/>
<variable
name="student3"
type="example.com.testerapplication.sp.bean.Student_Extend"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@={student1.name}"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{student2.name}"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{student3.name}"/>
<Button
android:id="@+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="update"/>
</LinearLayout>
</layout>
Activity class
public class MainActivity extends AppCompatActivity {
private Student_XML2WAY mStudent1;
private Student_ObserField mStudent2;
private Student_Extend mStudent3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = DataBindingUtil.inflate(LayoutInflater.from(this), R.layout.activity_main, null, false);
mStudent1 = new Student_XML2WAY();
mStudent1.setName("XML First");
mStudent2 = new Student_ObserField();
mStudent2.getName().set("ObserField Second");
mStudent3 = new Student_Extend();
mStudent3.setName("Extend Third");
binding.setStudent1(mStudent1);
binding.setStudent2(mStudent2);
binding.setStudent3(mStudent3);
setContentView(binding.getRoot());
binding.btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mStudent1.setName("Student1");
mStudent2.getName().set("Student2");
mStudent3.setName("Student3");
}
});
}
}