Monday, February 11, 2019

My first exercise of using Data Binding + ObservableField

The Data Binding Library is a support library that allows you to bind UI components in your layouts to data sources in your app using a declarative format rather than programmatically. It's my first exercise of using Data Binding and ObservableField, in Java. Basically, it follow the steps in Android Developers document of Data Binding Library.


The TextViews myArchitecture, myRelease and myDensity are loaded in onCreate() once. The TextView myNumber is associated with ObservableField, and will be updated at run-time.

Prepare:

- To use the Data Binding Library in your app, you have to target devices running Android 4.0 (API level 14) or higher.

- It's recommended to use the latest Android Plugin for Gradle in your project. Currently it's 3.3.1.


Read this video how to:

- Make sure include Support Repository in the Android SDK manager.


-  Add the dataBinding element to your build.gradle file in the app module.

In Android Studio, select Project view, extend app view, select to edit build.gradle. Add the code:

    dataBinding {
        enabled = true
    }


- Enable the new data binding compiler.
Note: The new compiler in Android Plugin version 3.2 is enabled by default. (refer https://developer.android.com/topic/libraries/data-binding/start) So it's skipped here.

- layout:
layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>
        <variable name="user" type="com.blogspot.android_er.myandroidinfo.MainActivity.User"/>
    </data>

    <android.support.constraint.ConstraintLayout
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="My device info"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:textStyle="bold"/>
        <TextView
            android:id="@+id/mylink"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="android-er.blogspot.com"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/title" />
        <TextView
            android:id="@+id/myArchitecture"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text='@{user.bArchitecture, default="Architecture"}'
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/mylink"
            android:gravity="left"
            android:textSize="30dp"/>
        <TextView
            android:id="@+id/myRelease"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text='@{user.bRelease, default="Release"}'
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/myArchitecture"
            android:gravity="left"
            android:textSize="30dp"/>
        <TextView
            android:id="@+id/myDensity"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text='@{user.bDensity, default="Density"}'
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/myRelease"
            android:gravity="left"
            android:textSize="30dp"/>

        <TextView
            android:id="@+id/myNumber"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{user.bNum}"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/myDensity"
            android:gravity="left"
            android:textSize="50dp"
            android:textStyle="italic|bold"
            android:textColor="#0000FF"/>

    </android.support.constraint.ConstraintLayout>
</layout>

- Java code
MainActivity.java
package com.blogspot.android_er.myandroidinfo;

import android.databinding.DataBindingUtil;
import android.databinding.ObservableField;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;

import com.blogspot.android_er.myandroidinfo.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {

    public class User {
        public final String bArchitecture;
        public final String bRelease;
        public final String bDensity;
        public final ObservableField<String> bNum = new ObservableField<>();
        public User(String arch, String rel, String den) {
            this.bArchitecture = arch;
            this.bRelease = rel;
            this.bDensity = den;
        }
    }

    private class MyTask extends AsyncTask<Void, Void, Void> {

        @Override
        protected Void doInBackground(Void... voids) {

            for (int i = 0; i < 20; i++) {
                user.bNum.set(String.valueOf(i));
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return null;
        }
    }

    User user;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        String arch = System.getProperty("os.arch");
        String release = Build.VERSION.RELEASE;

        DisplayMetrics metrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metrics);
        int dpi = metrics.densityDpi;

        ActivityMainBinding binding =
                DataBindingUtil.setContentView(this, R.layout.activity_main);
        user = new User(arch, release, String.valueOf(dpi));
        binding.setUser(user);

        new MyTask().execute();

    }
}