この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
データバインディングライブラリが公開
Google I/O 2015 で Android M が発表され、Chrome Tabs や 指紋認証、Google Pay、アクセス許可などさまざまな新機能が発表されました。楽しみですね!
- Google I/O:Android M(5.x)のプレビュー公開―指紋スキャナー、Google Pay、アクセス許可、バッテリー改善など新機能多数 | TechCrunch Japan
- Android M Developer Preview | Android Developers
今回はその中でも面白そうな新機能「データバインディング」を使ってみました。データバインディングはその名の通りデータをバインドしてくれる機能で、クラスのオブジェクトの状態の変更に応じて、XML に書いた View のプロパティを変更してくれます。
Android Studio 1.3 Developer Preview のインストール
まずは Android Studio 1.3 の Developer Preview をインストールしましょう。以下の Web ページ通りに行います。
日本語で書くとざっくり次のとおりです。
- Android Studio 1.2.2 をダウンロードする
- Settings を開き Appearance & Behavior > System Settings > Updates を開く
- チャンネルを Canary Chanel に変更する
- アップデートのチェックを行い、1.3 Developer Preview をインストールする
DataBinding ライブラリをインポートする
次に DataBinding ライブラリを Android アプリプロジェクトにインポートしましょう。まずプロジェクト直下の build.gradle を以下のようにします。公式ページ通りやったら動かなかったので、Gradle のバージョン指定に注意です。
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.3.0-beta1'
classpath "com.android.databinding:dataBinder:1.0-rc0"
}
}
allprojects {
repositories {
jcenter()
}
}
次にアプリの Module のほうの build.gradle を以下のようにします。ここでの注意点は compileOptions です。これも無いと動きませんでした。
apply plugin: 'com.android.application'
apply plugin: 'com.android.databinding'
android {
compileSdkVersion 'android-MNC'
buildToolsVersion "23.0.0 rc1"
defaultConfig {
applicationId "YOUR_PROJECT_NAME"
minSdkVersion 'MNC'
targetSdkVersion 'MNC'
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
}
Sync して終わりです。
XML を書く
次にいよいよ実装です。ウィザードで作成された直後のプロジェクトで作成される activity_main.xml を以下のようにします。
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="user" type="jp.classmethod.sample.User"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:text="@{user.firstName}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/button"
android:text="ばいんど!"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</layout>
ここで新しい書き方の登場です!いままでは XML のルートは View でしたが、それより大きな枠でもう1つ layout という階層が増えました。その中に data を入れ、variable にバインド対象のメンバーとクラスを指定しています。
なお、私の環境では XML での記述で新しい Attribute の解析エラーが出たので、Lint を無効化しました。
バインド対象のクラスを作成する
次に、バインド対象のクラスを作成しましょう。今回はサンプル通りに User クラスを作成しました。
package jp.classmethod.sample;
import android.databinding.BaseObservable;
import android.databinding.Bindable;
public class User extends BaseObservable {
private String firstName;
private String lastName;
public User(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
@Bindable
public String getFirstName() {
return this.firstName;
}
@Bindable
public String getLastName() {
return this.lastName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
notifyPropertyChanged(BR.firstName);
}
}
バインド可能なクラスを作成するには BaseObservable を継承します。そしてゲッターに @Bindable アノテーションを付けます。すると同パッケージに BR クラスが自動で作成されるので、今度はセッターで notifyPropertyChanged メソッドを呼び出し、どのプロパティが変化したか通知します。
次に MainActivity.java を次のように実装します。
package jp.classmethod.sample;
import android.app.Activity;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import jp.classmethod.sample.databinding.ActivityMainBinding;
public class MainActivity extends Activity implements View.OnClickListener {
private User mUser;
private ActivityMainBinding mBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
this.mUser = new User("Test", "User");
this.mBinding.setUser(this.mUser);
findViewById(R.id.button).setOnClickListener(this);
}
@Override
public void onClick(View v) {
this.mUser.setFirstName("Hoge");
}
}
ここでのポイントは大きく2点。1点目は ActivityMainBinding のクラスが <パッケージ名>.databinding の中に自動生成される点です。ここは恐らくコードヒントが出てこないので自分で書きましょう。2点目が DataBindingUtil を使って ActivityMainBinding クラスを生成するところです。第2引数で渡したレイアウト XML の Binding クラスが生成されます。レイアウト XML には data の中の variable の name を user としているため setUser() が自動生成されています。
ここまで実装してお気づきの人も居るかと思いますが、ちょいちょいエラーになります。
しかし、最大の注意点はエラーが表示されていてもコンパイルが成功するという点です! Developer Preview だからだと思いますが、エラーが表示されていても気にせずにビルドを実行してみてください。
以上で完成です!動かしてみると、ボタンを押したタイミングでテキストが更新されると思います。
まとめ
簡単ですが、データバインディングの事始めでした。エラーが出てしまうところは Developer Preview だからでしょうか、、
他にもデータバインディングに関する沢山の機能が追加されているので、今後も試していきたいと思います!