DataBindingチュートリアル第1回 – 基礎編

DataBinding

Data Bindingとは、Google IO 2015で発表された技術で、モデルオブジェクトとレイアウトを結びつける仕組みです。(Bindingとは”結びつける”という意味です) Data Bindingを使うと 「Javaのコード側でViewに文字列を設定する」という従来のスタイルが、 「レイアウト側がモデルを受け取って中身をViewに展開する」 というコーディングスタイルに代わります。

私がData Bindingを使い始めて感じたメリットには以下のようなものがあります。

実際はもっとたくさんのメリットがあると思いますが、まず同じメリットをみなさんにも体験してもらいたいと思いますので、簡単なチュートリアルから始めたいと思います。

(今回使うサンプルコードはこちらからダウンロードできます。)

セットアップ

appモジュールのbuild.gradleファイルに以下のようにdataBinding{enabled=true}を足します。

android {
    ....
    dataBinding {
        enabled = true
    }
}

レイアウトの変更

このサンプルでは、ユーザーの名前をTextViewに出力するだけのアプリを作って見ますので、本来であれば下のようなレイアウトを定義します。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="User Name"
        android:id="@+id/username"/>
</LinearLayout>

Data Bindingを使うためにはここからレイアウトの構造を変化させます。 まず今までのレイアウトを<layout>タグで囲みます。 次に先頭に新たに<data>というタグを足します。 ここで<data>タグの中にuserというメンバーを定義します。 見慣れない書き方ですがJavaのコードでUserクラスのメンバー変数”user”を宣言するのと同じです。

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable
            name="user"
            type="com.goldrushcomputing.databindingbasicsamples.model.User"/>

    </data>

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{user.name}"/>
    </LinearLayout>
</layout>

ここまでの作業で、Viewの中からuserというメンバーのデータにアクセスできるようになります。 TextViewの中でユーザーの名前をtextに設定するためにandroid:text="@{user.name}"のような表記を書きます。 これで、userの中のname変数に入っている文字列をTextViewのTextとして表示することができます。 type="com.goldrushcomputing.databindingbasicsamples.model.User"のところは、モデルクラスのフルパスを指定しないと行けないところを注意しましょう。

データオブジェクトの用意

上のレイアウトで定義したUserクラスは下のようにPOJOで定義します。

public class User {
    String name;

    public User(String name){
        this.name = name;        
    }

    public User(String name, String url){
        this.name = name;
    }
}

MainActivity

これで、レイアウトとモデルの準備ができました。最後にMainActivityを見ていきます。

public class MainActivity extends AppCompatActivity {



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

        ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        User user = new User("Benjamin");
        binding.setUser(user);
    }
}

Data Bindingを使うにはthis.setContentView(R.layout.activity_main);の代わりにDataBindingUtilsetContentViewを使います。 するとActivityMainBindingというクラスのオブジェクトが取得できます。 先ほどレイアウトファイル(activity_main.xml)を<layout>タグの中に入れると自動的にこのレアアウトファイル名からBindingクラスが作られます。 クラス名は、

  1. 先頭を大文字にする: activity -> Activity
  2. アンダースコアの後の文字を大文字にする: _main -> _Main
  3. アンダースコアを取り払う:_Main -> Main
  4. 最後に’Binding’という文字列をつける: ActivityMain -> ActivityMainBinding

つまり

activity_main -> Activity_main -> Activity_Main -> ActivityMain -> ActivityMainBinding

という風にルールが適用されてBindingクラスができます。 このBindingオブジェクトはレイアウトファイルそのものをオブジェクト化したものだと考えてください。 先ほど、ここに<data>というタグの領域を作り、その中にuserという変数を定義しました。

ここに、bindingオブジェクトはレイアウトファイルそのもの、ということで実際のユーザーデータを下のように代入できます。

User user = new User("Benjamin");
binding.setUser(user);

bindingオブジェクトにuserをセットしているので、下のようにViewのタグ内でオブジェクトから取ってきたデータをそのまま表示できるようになります。

<TextView android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{user.name}"/>

Data Bindingの素晴らしいところはモデルをアップデートするとViewに反映されるところです。 このケースでは、userというオブジェクトをbindingに設定すると自動的にTextViewのレンダリングが起き、最新のuserの名前が表示されます(これは次回詳しく説明します。)

ここまでできたらアプリケーションを起動して見てください。 実際には下のようなエラーが起きてしまいます。

Error:(7, 65) エラー: パッケージcom.goldrushcomputing.databindingbasicsamples.databindingは存在しません

これは私がData Bindingを初めて使って見たときにぶつかった壁でした。エラーの意味がわからず解決するのに1時間以上用してしまいました。 このエラーの原因は、レイアウト側からuserオブジェクトのname変数がみえれないことです。 変数をpublicにするか、

public String name;

下のようにアクセッサーをつけて再びビルドするとこのエラーは消えます。

public String getName(){
        return name;
}

ここは地味にハマるポイントなので押さえておくと覚えておいてください。

実行結果

実行すると以下のようにユーザー名の表示ができました。

スクリーンショット

これはもっとも単純なData Bindingの例です。 ただ、Data Bindingを導入するときは、gradleも、レイアウトファイルも、Activityファイルも従来のものに変更を加える必要があるのでこのようなシンプルなもので一度成功をしてから次のステップに進んだ方が良いと思い このようなシンプルなサンプルにしました。 次回以降Data Bindingの応用例を説明していきたいと思います。

チュートリアルの内容を自分のプロジェクトに反映させる時にわからないことや問題にぶつかった時のために、Fourhandsではオンラインのメンタリングサービスを提供しています。
ビデオチャットやスクリーン共有をつかて実際にコードをメンターに見てもらいながら問題の解決や、考え方のアドバイスがもらえるサービスですので、是非活用して見てください。 fourhands.com

NEXT

DataBindingチュートリアル第2回 – アクションのバインディング