Posted at

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

More than 1 year has passed since last update.


はじめに

最近Androidで,Viewを取ってくるときによく使うfindViewByIdをぶっとばすために ButterKnifeを使うことを検討していた.

しかしButter Knife、今までありがとう。 Data Binding、これからよろしく。の記事を見たり,「DataBindingいいよ」という話を聞き,標準で使えるDataBindingを使ってみようと思ったので,連載形式で勉強していきたいと思う.


DataBindingとは?

まず,DataBindingについて整理していこう.

公式ドキュメントはここ.

https://developer.android.com/topic/libraries/data-binding/index.htm

DataBindingの言葉の意味はwikipediaによると,


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低コスト導入