はじめに
最近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>
やったこととしては,
- レイアウトファイルのルートを
<layout>
に - Bindさせたいデータオブジェクトを
<data>
で宣言する. typeが型で,nameは変数名 - 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回目はここまで.