読者です 読者をやめる 読者になる 読者になる

techium

このブログは何かに追われないと頑張れない人たちが週一更新をノルマに技術情報を発信するブログです。もし何か調査して欲しい内容がありましたら、@kobashinG or @muchiki0226 までいただけますと気が向いたら調査するかもしれません。

Data Bindingを使ってみる その1

DroidKaigiの土産話に感化された私は、今更ながらData-Bindingを使ってみました。
まずは公式を見ながら基本的なところからやってみます。

【環境】
Android Studio 2.0 beta 6

1.準備
まずはData Bindingを利用するため、appモジュールにあるbuild.gradleに設定を追記します。

[build.gradle]

android {
    (略)
    dataBinding{
        enabled = true
    }
}

Android Studio 1.3 Developer Previewの頃はdependenciesに追記したりプラグインの記述が必要だったりしたようですが、
Android Studio 2.0現在はこれだけでオッケーです。

dataBindingのenabledオプションはAndroid Plugin DSLの1.5から追加されていますので、Android Plugin for Gradle の1.5.0以降を利用します。

buildscript {
    (略)
    dependencies {
        //classpath 'com.android.tools.build:gradle:2.0.0-beta6'
        classpath 'com.android.tools.build:gradle:1.5.0'
    }
}

2. TextViewに文字列をバインドしてみる
次に、実際にData Bindingを使ってみます。
まずはData Bindingを使用していない以下のようなレイアウトを用意しました。

[activity_main.xml]

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

        (・・・略・・・)

    <TextView
        android:id="@+id/lbl_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="名前:"
        android:layout_below="@id/txt_hello">
    </TextView>
    <TextView
        android:id="@+id/txt_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/txt_hello"
        android:layout_toRightOf="@id/lbl_name"/>

    <TextView
        android:id="@+id/lbl_gender"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="性別:"
        android:layout_below="@id/lbl_name">
    </TextView>
    <TextView
        android:id="@+id/txt_gender"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/lbl_name"
        android:layout_toRightOf="@id/lbl_gender"/>

</RelativeLayout>

[MainActivity.java]

public class MainActivity extends AppCompatActivity {

    private TextView tv_name;
    private TextView tv_gender;

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

        tv_name = (TextView)findViewById(R.id.txt_name);
        tv_gender = (TextView)findViewById(R.id.txt_gender);
        tv_name.setText("ハンタくん");
        tv_gender.setText("MAN");
    }
}

これを、まずは以下のようにData Bindingに対応してみます。
[activity_main.xml 改]

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <data>
        <variable name="hanter" type="monhaan.example.com.monhaan.Hanter"/>
    </data>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        (・・・略・・・)

        <TextView
            android:id="@+id/lbl_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/txt_hello"
            android:text="名前:">
        </TextView>
        <TextView
            android:id="@+id/txt_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/txt_hello"
            android:layout_toRightOf="@id/lbl_name"
            android:text="@{hanter.name}"/>

        <TextView
            android:id="@+id/lbl_gender"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/lbl_name"
            android:text="性別:">
        </TextView>
        <TextView
            android:id="@+id/txt_gender"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/lbl_name"
            android:layout_toRightOf="@id/lbl_gender"
            android:text="@{hanter.gender}" />
    </RelativeLayout>
</layout>

Data Bindingを利用するレイアウトファイルは、layoutタグをrootとする必要があります。
layoutタグの中にDataタグを用意し、さらにその中に'hanter'プロパティをvariableタグで定義します。
この'hanter'は、typeに指定したHanterクラス(後述)のオブジェクトで、activity_main.xml内で利用することができるバインド変数となります。
26行目と41行目で、'hanter'が持つnameプロパティとgenderプロパティの値を、それぞれTextViewの文字列としてセットするようにします。

バインドする側のソースコードは以下のようにします。
[MainActivity.java 改]

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ActivityMainBinding binder = DataBindingUtil.setContentView(this, R.layout.activity_main); 
        Hanter hanter = new Hanter("ハンタくん", "man"); 
        binder.setHanter(hanter);  
    }
}

7行目で、レイアウトファイル(activity_main.xml)に変数をバインドするためのActivityMainBindingクラスのインスタンスを生成しています。
ActivityMainBindingクラスは"activity_main.xml 改"を作成すると自動生成されるクラスで、"activity_main.xml"のファイル名を基に、"Binding"をクラス名として付与した名称で生成されます。
8行目でHanterクラスのインスタンスを生成(ここでは"名前"と"性別"にそれぞれ"hantakun"と"MAN"を設定している)し、9行目でレイアウトファイルにバインドしています。
ActivityMainBinding#setHanterメソッドも自動生成されており、"activity_main.xml 改"の4行目でname属性に指定した"hanter"を基に、メソッド名が生成されています。

f:id:uentseit:20160310224018p:plain:w200
図.実行結果

ちなみに、Hanterクラスは以下のようになっています。
[Hanter.java]

public class Hanter {
    private String name;
    private String gender;

    public Hanter(String name, String gender){
        this.name = name;
        this.gender = gender;
    }

    public String getName() {
        return this.name;
    }

    public String getGender() {
        return this.gender;
    }
}

何の変哲もありませんが、次回以降でこちらにも手を入れていきます。
さて、長くなりそうなので、続きは次回。

サンプルコード
github.com