Android data binding is a way to connect UI layout to the underlying data model
Android data binding
How to use @Bindable
data binder
At the end of this tutorial, you will create an app like this
Setup Android data binding
As told before, this feature is still in beta version, so as the first thing let's set the right dependencies in the top level build.gradle:dependencies {
classpath "com.android.tools.build:gradle:1.3.0"
classpath "com.android.databinding:dataBinder:1.+"
}
by the way, make sure you downloaded gradle 2.4. Now the dependencies are ready and it is time to modify build.gradle in the app:
apply plugin: 'com.android.databinding'
How to use Android data binding
Now that the environment is ready, it is possible to code our Android app. As example, we will create a simple weather app that shows the temperature and other information, in this case to show to data the app will use the data binding.As the first thing, we create the layout, that will be very simple but it will contains some important things we should notice:
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="data" type="survivingwithandroid.com.androiddatabinding.model.Data" />
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" >
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="@color/primary"
android:elevation="4dp"
app:theme="@style/ThemeOverlay.AppCompat.Dark"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
android:layout_below="@id/toolbar"
android:text="@{data.city}"
android:textSize="18dp"
android:id="@+id/weather_icon"/>
<ImageView
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_centerInParent="true"
android:src="@{data.icon}"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="@{data.descr}"
android:layout_marginTop="10dp"
android:layout_below="@id/weather_icon"/>
<GridLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_alignParentBottom="true"
android:layout_marginBottom="15dp"
android:rowCount="1"
android:columnCount="4"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true">
<TextView android:id="@+id/temp"
android:layout_width="60dp"
android:layout_height="60dp"
android:text="@{data.temp}"
android:layout_row="0"
android:layout_column="0"
android:layout_gravity="center"
/>
<TextView android:id="@+id/press"
android:layout_width="60dp"
android:layout_height="60dp"
android:text="@{data.pressure}"
android:layout_row="0"
android:layout_column="1"
android:layout_gravity="center"
/>
<TextView android:id="@+id/hum"
android:layout_width="60dp"
android:layout_height="60dp"
android:text="@{data.humidity}"
android:layout_row="0"
android:layout_column="2"
android:layout_gravity="center"
/>
<TextView android:id="@+id/wind"
android:layout_width="60dp"
android:layout_height="60dp"
android:text="@{data.wind}"
android:layout_row="0"
android:layout_column="3"
android:layout_gravity="center"
/>
</GridLayout>
</RelativeLayout>
</layout>
As root of the app UI layout there is the layout, and then the variable we want to use in our layout are declared (line 3-5). It is important to declare these variables because they will be used in the binding process. At line 4, it is stated that the variable data is the type of survivingwithandroid.com.androiddatabinding.model.Data that contains the data we want to show. In other world this class is a POJO that is bound the UI. In the TextView widgets, the value of each field of the POJO class is bound to the corresponding android:text so the value is shown automatically.
Binding variable to the object
Now the layout is ready and it is possible to bind the class field to the UI widget. In onCreate method we get the reference to the current layout of the Activity in a different way compared to the usual way :@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
binding.setData(data);
....
}
where data is defined as:
private Data data = new Data(); //survivingwithandroid.com.androiddatabinding.model.Data;
Notice that at line 5 we set the activity layout and then we resolve the variable used in the layout. If we run the app in this way, we notice that the UI data is updated only once at the beginning, when the underlaying class field, bound to the UI, changes the UI does not reflect the change. This happen because it is necessary create a listener between the UI and the data field.
The first step is that the our POJO Data class extends BaseObservable:
public class Data extends BaseObservable {
....
}
Now it is necessary to bind the single class field to the UI, for example for temperature field:
public class Data extends BaseObservable {The
..
@Bindable
public String getTemp() {
return temp;
}
public void setTemp(String temp) {
this.temp = temp;
notifyPropertyChanged(BR.temp);
}
..
}
@Bindable
annotation is used to make a reference between the UI and the field and the notifyPropertyChanged
informs the listener that the underlaying filed is changed and it is necessary to update the view. Running an example, using the Android data binding the result is: Conclusion
As we have noticed Android data binding is a very interesting and powerful feature and it can simplify a lot app building. Anyway it is still in beta version and there are some small problems: for example even if i tried to update the ImageView using the same way and setting the resource id it did not work. Is it my mistake?!!Source code available @github
0 comments:
Post a Comment