Data Bindingを使ってみる その2
前回に引き続き、Data Bindingについて書いていきます。
今回は、ボタンを押すことで性別が変化するようにしてみます。
まずはData Bindingを使っていない場合、以下のようになると思います。
public class MainActivityNoBinding extends AppCompatActivity { private TextView tv_name; private TextView tv_gender; private Button changeGender; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main_no_binding); tv_name = (TextView)findViewById(R.id.txt_name); tv_gender = (TextView)findViewById(R.id.txt_gender); tv_name.setText("ハンタくん"); tv_gender.setText("MAN"); changeGender = (Button)findViewById(R.id.btn_change_gender); changeGender.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { tv_gender.setText("WOMAN"); } }); } }
次に、Data Bindingを使っていきます。 Activityとactivity_main.xmlの実装はそれぞれ以下のようになります。
[MainActivity.java]
public class MainActivity extends AppCompatActivity { private Hanter hanter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ActivityMainBinding binder = DataBindingUtil.setContentView(this, R.layout.activity_main); hanter = new Hanter("ハンタくん", "MAN"); binder.setHanter(hanter); binder.btnChangeGender.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { hanter.setGender("WOMAN"); } }); } }
[activity_main.xml]
<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <data> <variable name="hanter" type="monhaan.example.com.monhaan.Hanter"/> </data> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> (略) <Button android:id="@+id/btn_change_gender" android:text="change gender" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/lbl_gender"/> </RelativeLayout> </layout>
activity_main.xmlには'btn_change_gender'というIDでButtonを一つ追加しただけです。 そしてMainActivity.javaの13行目で、btn_change_genderボタンにOnClickListenerをセットしています。 このように、ViewのIDをキャメル記法にした名前のメソッドを通じて、findViewByIdをしなくてもViewコンポーネントにアクセスできます。
16行目で、genderプロパティに"WOMAN"を指定して性別を変更しようとしていますが、HanterクラスのprivateなgenderプロパティにはまだSetterがないため、以下のようにHanterクラスを修正しておきます。
public class Hanter extends BaseObservable{ private String name; private String gender; public Hanter(String name, String gender){ this.name = name; this.gender = gender; } public String getName() { return this.name; } @Bindable public String getGender() { return this.gender; } public void setGender(String gender) { this.gender = gender; notifyPropertyChanged(monhaan.example.com.monhaan.BR.gender); } }
前回からの修正点としては、 まず1行目、ObservableクラスをimplementsしたBaseObservableクラスを継承しています。こうすることで、Hanterクラスが持ついずれかのプロパティの値に変化があった時に呼ばれるリスナーがセットされます。 21行目で、プロパティの変化を伝えるBaseObservable#notifyPropertyChangedメソッドを呼ぶことで、実際にgenderプロパティの値が変化したことをバインダーに伝え、リスナーが呼ばれるようにしています。 なお、BRクラスはgenderプロパティのGetterに@Bindableアノテーションを付与することで自動生成されるクラスです。 これで性別が'MAN'から'WOMAN'に変更されるはずです。
ちなみに、activity_main.xmlにOnClickListenerのセットを記述したい場合は以下のように実装することも可能です。 [activity_main.xml その2]
<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <data> <variable name="activity" type="monhaan.example.com.monhaan.MainActivity"/> <variable name="hanter" type="monhaan.example.com.monhaan.Hanter"/> </data> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> (略) <Button android:id="@+id/btn_change_gender" android:text="change gender" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/lbl_gender" app:onClickListener="@{activity.changeGenderListener}"/> </RelativeLayout> </layout>
4行目でMainActivityクラスのオブジェクト'activity'を定義し、 20行目でButtonのonClickListenerにchangeGenderListenerをセットしています。
changeGenderListenerは、MainActivity内で以下のように定義しています。 [MainActivity.java]
public View.OnClickListener changeGenderListener = new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this, "clicked", Toast.LENGTH_SHORT).show(); hanter.setGender("woman"); } };
さて、今日はこれぐらいにしておきます。
サンプルコードはこちら↓