なか日記

一度きりの人生、楽しく生きよう。

Android Bindingを使ってみた(3)

Android Bindingを使ってみた(2) - タイトルは未定の続きです。

前回ので準備ができましたので、いよいよActivityとViewModelを分離してみます。

ソース一式はこちら
https://github.com/nakaji/AndroidBindingSample

お知らせ

  • AndroidBindingSampleActivityのクラス名が無駄に長いので、BMIActivityに変更しました

BMIViewModelクラスの追加

PojoViewModelを実装したBMIViewModelクラスを作成します。
BMIActivity*1の中にあるPojoViewModelの実装部分やBMIのgetter、setterをBMIViewModelへ移動します。
また、このクラスではAndroid関係のクラスを直接参照しない様にしたいので、身長と体重を受け取るsetterを公開しておきます。

ソース
public class BMIViewModel implements PojoViewModel {

    private PojoViewModelHelper helper = new PojoViewModelHelper();
    private double bmi;
    private double height;
    private double weight;

    public PojoViewModelHelper getHelper() {
        return helper;
    }

    public void notifyPropertyChanged(String propertyName) {
        helper.notifyPropertyChanged(propertyName);
    }

    public void Calculate() {
        double bmi = weight / Math.pow(height / 100.0, 2);
        setBMI(bmi);
    };

    public void setBMI(double bmi) {
        this.bmi = bmi;
        notifyPropertyChanged("BMI");
    }

    public String getBMI() {
        return "Your BMI is " + String.valueOf(bmi);
    }

    public void setHeight(double height) {
        this.height = height;
    }

    public void setWeight(double weight) {
        this.weight = weight;
    }
}

BMIActivityの修正

Binder.setAndBindContentViewの変更

ViewにバインドするmodelがBMIActivityからBMIViewModelに変わりますので、PojoViewModelWrapper.createの引数をBMIViewModelのインスタンスに変更します。

身長と体重が変更されたことをmodelに通知

WPF等であれば双方向バインディングが行えますが、Android Bindingでは今のところModel→Viewの片方向しか対応されていないようです。
なので、テキストが変更された際にAndroidBindingSampleViewModelに変更された値を通知する様にします。

ソース
public class BMIActivity extends Activity {

    private EditText heightText;
    private EditText weightText;

    private BMIViewModel viewModel = new BMIViewModel();

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Binder.init(this.getApplication());
        Binder.setAndBindContentView(this, R.layout.main, PojoViewModelWrapper.create(viewModel));

        heightText = (EditText) findViewById(R.id.height);
        weightText = (EditText) findViewById(R.id.weight);

        heightText.addTextChangedListener(new TextWatcher() {
            @Override
            public void onTextChanged(CharSequence charsequence, int i, int j, int count) {
                if (count > 0) {
                    viewModel.setHeight(Double.valueOf(charsequence.toString()));
                } else {
                    viewModel.setHeight(0);
                }
            }

            @Override
            public void beforeTextChanged(CharSequence charsequence, int i, int j, int k) {
            }

            @Override
            public void afterTextChanged(Editable editable) {
            }
        });

        weightText.addTextChangedListener(new TextWatcher() {
            @Override
            public void onTextChanged(CharSequence charsequence, int i, int j, int count) {
                if (count > 0) {
                    viewModel.setWeight(Double.valueOf(charsequence.toString()));
                }
                else {
                    viewModel.setWeight(0);
                }
            }

            @Override
            public void beforeTextChanged(CharSequence charsequence, int i, int j, int k) {
            }

            @Override
            public void afterTextChanged(Editable editable) {
            }
        });
    }
}

で、結局

最初に紹介してた@さんとほとんど同じになりました。

うーん。落ちがありませんでした。

*1:旧:AndroidBindingSampleActivity