I am using Data Binding in a development project, and I will write an article about what I learned.
This time, I learned how to use DataBinding to monitor changes in the properties of data class objects and reflect them in the View display.
The text display of ① and ② is dynamically switched back and forth each time the "Change" button is pressed. "Doraemon" ⇄ "Nobita"
① |
---|
② |
---|
build.gradle(:app)
activity_main.xml
-- Character.java
(model class)
-- EventHandlers.java
(interface)MainActivity.java
Added dataBinding {enabled = true}
to build.gradle (: app)
build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 30
buildToolsVersion "30.0.2"
defaultConfig {
applicationId "com.android.databindingjava"
minSdkVersion 24
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
//Add description
dataBinding {
enabled = true
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
Character.java
//Inherit BaseObservable
public class Character extends BaseObservable {
private String name;
public Character(String name) {
this.name = name;
}
//to getName@Constant BR for monitoring by giving Bindable.name is generated
@Bindable
public String getName() {
return name;
}
//notifyPropertyChanged in setName(BR.name)By granting
//BR from the layout side.getName corresponding to name()Is called (getName is called from the layout side when setName is done)
public void setName(String name) {
this.name = name;
notifyPropertyChanged(BR.name);
}
}
To reflect the changes in the view
--Inheriting BaseObservable
--Add @Bindable
to getName
and generate BR.name
which is a constant for monitoring.
--Write notifyPropertyChanged (BR.name);
in setName
By doing this, getName
will be called from the layout side when setName
is executed, and when the value of name
is changed, the change will be reflected in the view.
EventHandlers.java
public interface EventHandlers {
//Since we want to correspond to the click event, the argument is View.Make it the same as onClick of OnClickListener (View view)
void onChangeClick(View view);
}
Define the event handler to be set in the layout as an interface
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<!--By setting the route to layout, it will be recognized as a layout corresponding to Data Binding.-->
<!-- activity_main.xml =>ActivityMainBinding In this way, a Binding class corresponding to the xml file name is automatically created.-->
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!--Binding object-->
<data>
<!--Named character by this description(Any)Is associated with the User class object-->
<variable name="character" type="com.android.databindingjava.Character" />
<!--Named eventHandlers by this description(Any)The handler (interface) is set with-->
<variable name="eventHandlers" type="com.android.databindingjava.EventHandlers" />
</data>
<!-- Views-->
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/text_view_user_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:text="@{character.name}" />
<Button
android:id="@+id/button_change"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30dp"
android:text="change"
android:onClick="@{eventHandlers.onChangeClick}"
app:layout_constraintBottom_toTopOf="@id/text_view_user_name"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
<variable name = "character" type = "com.android.databindingjava.Character" />
defines a Character class object with the name character in the layout file and uses the object in the layout file. become able to.
@ {character.name}
With this description, you can access the name property of the Character class, and android: text = "@ {character.name}"
sets the value of the property to text.
@ {}
are allowed to be null, and even if it is null, NullPointerException will not occur.<variable name = "eventHandlers" type = "com.android.databindingjava.EventHandlers" />
defines the EventHandlers interface in the layout file with the name eventHandlers, and you can access the interface in the layout file. Will be.
@ {eventHandlers.onChangeClick}
With this description, you can access onChangeClick of the EventHandlers interface, and when you click by writing android: onClick = "@ {eventHandlers.onChangeClick}"
in the Button element OnChangeClick will be called.
(* It is also necessary to describe in MainActivity.java described later)
MainActivity.java
//Implement EventHandlers (interface)
public class MainActivity extends AppCompatActivity implements EventHandlers {
private Character chara = new Character("Doraemon");
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// activity_main.Create a binding instance of the class corresponding to xml
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
// activity_main.Set chara to character in xml
binding.setCharacter(chara);
// activity_main.Set MainActivity in eventHandlers of xml
binding.setEventHandlers(this);
}
// button_Click event processing of change (interface)
@Override
public void onChangeClick(View view) {
//Change the character string to be set depending on the character string of chara name
if (chara.getName().equals("Doraemon")) {
chara.setName("Nobita");
} else {
chara.setName("Doraemon");
}
}
}
By creating a layout file with the root set to <layout>
, the Binding class corresponding to the xml file name is automatically created.
In this case, activity_main.xml => ActivityMainBinding (.java)
The following processing is performed in onCreate
--Create an instance with ActivityMainBinding binding = DataBindingUtil.setContentView (this, R.layout.activity_main);
--binding.setCharacter (chara);
to set chara to character in the layout file
--Set MainActivity to eventHandlers in the layout file with binding.setEventHandlers (this);
Then, the interface onChangeClick is implemented, and the process of changing the data according to the TextView string value without a method is written.
This article of mine is a mess of reference to this article. It was really easy to understand! Thank you very much!
Android Databinding ~ Super Introduction ~
This time it's a simple app, but the actual project is large and it's difficult to read the code. I will continue learning further.
We would appreciate it if you could comment on any mistakes or suggestions.
Recommended Posts