Androidのバインディングを試す


いまさらながら試してみる。
詳細はこちらを参照。
データバインディングライブラリ

バインディングを有効にする

build.gradleにバインディングの設定を追加する。

build.gradle
apply plugin: 'com.android.application'
android {
    compileSdkVersion 25
    buildToolsVersion "23.0.3"

    //■■■ここ追加■■■
    dataBinding {
        enabled = true
    }

    defaultConfig {
        applicationId "example.com.myapplication"
        minSdkVersion 19
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:25.1.0'
}

アプリ側のあれこれ

レイアウト、アクティビティの修正と、バインディングされるViewModelを作る。

レイアウト

レイアウトファイルにTextViewとボタン2つ追加する。

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable name="data" type="example.com.myapplication.MainActivityViewModel" />
    </data>

    <RelativeLayout xmlns:tools="http://schemas.android.com/tools"
        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="example.com.myapplication.MainActivity">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{data.text}"
            android:id="@+id/textView" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="01"
            android:id="@+id/button"
            android:layout_below="@+id/textView"
            android:onClick="@{data.onButtonClick01}"
            android:layout_alignParentStart="true" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="02"
            android:id="@+id/button2"
            android:layout_below="@+id/button"
            android:onClick="@{data.onButtonClick02}"
            android:layout_alignParentStart="true" />
    </RelativeLayout>
</layout>

アクティビティ

ViewModelのインスタンスを生成してバインドする。

MainActivity.java
public class MainActivity extends AppCompatActivity {

    private MainActivityViewModel viewModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        viewModel = new MainActivityViewModel();
        ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);

        binding.setData(viewModel);
    }
}

ViewModel

げったーには@Bindableを付与し、せったーはnotifyPropertyChangedを実行する。
イベントのバインディングはメソッドでもリスナーでもおk

MainActivityViewModel.java
public class MainActivityViewModel extends BaseObservable {
    private String text;
    public View.OnClickListener onButtonClick02;

    @Bindable
    public String getText() {
        return text;
    }
    public void setText(String value) {
        this.text = value;
        notifyPropertyChanged(example.com.myapplication.BR.text);
    }

    public void onButtonClick01(View view) {
        setText("ふがふが");
    }

    public MainActivityViewModel() {
        text = "ほげほげ";
        onButtonClick02 = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                setText("もふもふ");
            }
        };
    }
}

実行

起動後

01をクリック

02をクリック