Android DataBinding入門 ① ~導入・オブジェクト監視~

# はじめに
最近Androidで，Viewを取ってくるときによく使うfindViewByIdをぶっとばすために [ButterKnife](http://jakewharton.github.io/butterknife/)を使うことを検討していた．
しかし[Butter Knife、今までありがとう。 Data Binding、これからよろしく。](http://qiita.com/izumin5210/items/2784576d86ce6b9b51e6)の記事を見たり，「DataBindingいいよ」という話を聞き，標準で使えるDataBindingを使ってみようと思ったので，連載形式で勉強していきたいと思う．

# DataBindingとは？ 
まず，DataBindingについて整理していこう． 
公式ドキュメントはここ．
https://developer.android.com/topic/libraries/data-binding/index.htm

DataBindingの言葉の意味は[wikipedia](https://ja.wikipedia.org/wiki/%E3%83%87%E3%83%BC%E3%82%BF%E3%83%90%E3%82%A4%E3%83%B3%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0)によると，
> XMLなどのデータソースとアプリケーションやウェブページ（ウェブアプリケーション）のユーザインタフェースを静的または動的に結合する技術である。    
>   
> 分離されたデータソースとユーザインタフェースの間を橋渡しする役割を果たし、データが変更されるとそれに応じてユーザインタフェースが変更される一方向なデータバインディングと、  併せてユーザインタフェースの変更または操作に応じてデータが変更される双方向のデータバインディングがある。  

重要な点としては，**分離されたデータソースとUIの間の橋渡しをする役割**であること． 
これを最小限のコード量で実現できるのがDataBinding Libraryだと締めておく． 

# DataBindingを導入
Android StudioのプロジェクトでDataBindingを使えるようにするには，appディレクトリ以下のbuild.gradleにこれを追加するだけ！

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

※Android Studio 1.3以降がサポートしています．
[https://developer.android.com/topic/libraries/data-binding/index.html?hl=ja#studio_support]


# DataBinding
今回はサンプルとして，Hello worldを表示しているアプリを少しいじって，INABAボタンだけがあるだけのアプリを作成しました．
ここでは，INABAボタンにテキストをセットするところまでやります． 

まず，レイアウトファイルを編集します．
サンプルファイルを以下に示しておきます．

```
// 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.test.model.User"/>
    </data>

    <RelativeLayout xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="com.test.MainActivity">

        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{user.name}"/>
    </RelativeLayout>
</layout>
```

やったこととしては，
1. レイアウトファイルのルートを`<layout>`に
2. Bindさせたいデータオブジェクトを`<data>`で宣言する. typeが型で，nameは変数名
3. Bindさせたい場所に`@{}`構文でセット

Bindさせるデータオブジェクトは`User`として作りました． 

```
// User.java
public class User{
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
```


次に，ActivityでBindingオブジェクト取得してみましょう．

```
// MainActivity.java
public class MainActivity extends AppCompatActivity {
    private ActivityMainBinding mActivityMainBinding;
    private User mUser1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        mUser1 = new User();
        mUser1.setName("inaba");
        mActivityMainBinding.setUser(mUser1);
    }
}
```

` mActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);` でレイアウトとBindされたオブジェクトを得ることができる．
このオブジェクトのクラス名のルールとしては， レイアウトファイル名の`_`を抜いてパスカルケースで単語を連ね，末尾に`Binding`がつく. 
`mActivityMainBinding.setUser(mUser1);`で Bindingオブジェクトとレイアウトファイルの`<data>`タグ内で宣言されているデータオブジェクトと紐付ける．
ここでButtonのViewを取ってきたいときは，`findViewById` + キャストでなく，以下のようにしてとれる.

```
Button button = mActivityMainBinding.button;
``` 
(**これが一番うれしい点!!**)
ここまでで，ボタンにテキストをいれるとこまでできた．

# オブジェクト監視
次にINABAボタンを押したら，MATSUMOTOボタンに変化するようにしてみよう．
普通にやるとしたら，ButtonオブジェクトにClickListenerをセットして，setTextすることになると思う．
Data Bindingで実現するには，先程作ったUserオブジェクトの変化を監視できるようにし，Bindingオブジェクトに通知してあげる必要がある．

まず，Userクラスを監視できるようにするには`BaseObservable`を継承し，監視するフィールドのゲッターに`@Bindable`をつける．
変更をBindingオブジェクトに通知するため，`notifyPropertyChanged(BR.name);` を監視するフィールドのセッターで呼んであげる．これでOK． 

```
public class User extends BaseObservable{
    private String name;
    
    @Bindable
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
        notifyPropertyChanged(BR.name);
    }
```

監視の設定がおわったので，ボタンが押された時の動作を記述する．

```
// activity_main.xml
 <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{user.name}"
            android:onClick="@{activity.onNameClick}"/>
```
Buttonに` android:onClick="@{activity.onNameClick}"/>`のよう，`onClick`属性を追加し，`onNameClick`メソッドを定義しておく．

```
// MainActivity.java
    public void onNameClick(View view){
        Toast.makeText(this, "name click", Toast.LENGTH_SHORT).show();
        mUser1.setName("matsumoto");
    }
}
```

これで完成！ 
第1回目はここまで．

# 参考
[Android Data Binding低コスト導入](http://tech.pjin.jp/blog/2016/04/28/android-data-binding%E3%81%A7%E4%BD%8E%E3%82%B3%E3%82%B9%E3%83%88%E5%B0%8E%E5%85%A5)