Hokuriku.NET vol.12
2013/8/3
大場 知悟 (@tworks)
はじめに
内容は個人に帰属します
所属する組織を代表するものではありません
http://blog.tworks.jp/wp-
content/uploads/2013/08/AndroidBindingSample.zip
大場知悟(おおばとものり)
@tworks
匿名文化のTwitterで本名を強いられてい
る人です
2012年9月11日 ~Hokuriku.NET vol.10~
こどもの運動会により、あえなくキャンセル
2013年4月13日 ~Hokuriku.NET X WCAF~
AM 5:20 徹夜で発表資料を作成
AM 5:33 淡路島付近で(M)6.3の地震
交通機関STOP
大場が北陸に近づこうとすると何かが起こる...?
本題
Androidアプリ開発のお話
本日は
ここ
プ
ロ
グ
ラ
ミ
ン
グ
デザイン・ユーザーインターフェース
簡単なAndroidアプリ
簡単なAndroidアプリ
(おまけ)
複雑なAndroidアプリ
Before Android-Binding
After Android-Binding
つくるもの
UI
テキスト表示欄
ボタン
ボタンをつつくとテキスト表示欄に「じん
ぐる」を表示
Before
Android-Binding
<RelativeLayout xmlns:android=
"http://schemas.android.com/apk/res/android">
<TextView
android:id="@id/hello_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=“Hello World!" />
</RelativeLayout>
activity_main.xml
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
MainActivity.java
<RelativeLayout xmlns:android=
"http://schemas.android.com/apk/res/android">
<TextView
android:id="@+id/hello_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="こんにちは" />
</RelativeLayout>
activity_main.xml
TextView textView =
(TextView)findViewById(R.id.hello_text);
textView.setText("じんぐる");
MainActivity.java
<Button
android:id="@+id/hello_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="こんにちは" />
activity_main.xml
Button button = (Button)findViewById(R.id.hello_button);
button.setOnClickListener(newOnClickListener() {
@Override
public void onClick(View arg0) {
TextView textView = (TextView)findViewById(R.id.hello_text);
textView.setText("じんぐる!");
}
});
MainActivity.java
突然ですが欠点を
View(UI)をActivity(コード)から名前で
参照している
名前を変えるなら両方の修正が必要
findViewById("…") の呪い
でも名前を付けないと、いろんなことが
できなくなっちゃう
View(UI)の型をActivity
(コード)側で意識している
TextView textView =
(TextView )findViewById(R.id.hello_text);
左辺の型推論があれば我慢できるけど…Javaめ!
View(UI)の型をActivity
(コード)側で意識しているが、コードが
本質的に扱いたいのは文字列だけ
→扱いたい内容にギャップが生じている
View
TextView
・Text
・色
・位置
・etc...
コード
"じんぐる"
(文字変数)
TextView
・Text
・色
・位置
・etc...
View(UI)の型をActivity
(コード)側で意識しないで、本質的に扱
いたい文字列をUIに設定できれば...
View
TextView
・Text
・色
・位置
・etc...
コード
"じんぐる"
(文字変数)
What is
Android-Binding
いけてない所を解決するライブラリ
https://code.google.com/p/android-binding/
https://github.com/gueei/AndroidBinding
バインド 【 bind 】
束縛(する)、拘束(する)、結びつける、関連付け
る、などの意味を持つ英単語。ITの分野では、何
らかの要素やデータ、ファイルなどが相互に関連
付けられている状態や、そのような状態を実現す
る機能などのことを指すことが多い。
データベース管理システム(DBMS)で、データベー
スを操作するプログラムを作成する際に、SQL文に
プログラムの変数を埋め込むことをバインド変数
という。
libsの下に配置
Android-Binding
概念編
Viewに対しコードが本質的に扱いたいもの
や振る舞いを定義するクラス
「名前」を管理する変数
ViewModelView
名前を入力するUI
ViewのプロパティとViewModelの変数を関連づける宣言
Bind可能なソースは、~~Observableという変数
<TextView
binding:text="yourName" />
StringObservable yourName;
ViewModelView
ViewModelの変数を変更するとViewに反映され
る
このときView(UI)の名前やViewの型を
一切使っていない!
→依存関係が少なくなる
StringObservable yourName;
yourName.set(“じんぐる");
ViewModelView
じんぐる
~~Observableに変更が発生したとき、
Binding先に変更があったことを通知する
仕組みを内蔵している。これにより
ViewModel側はViewの型を意識しなくて済
む!
StringObservable yourName;
yourName.set(“じんぐる");
ViewModelView
①値が変わったよ!
②了解、参照しますね
じんぐる
片方向
双方向
<TextView
binding:text="yourName" />
StringObservable yourName;
<TextView
binding:text="yourName" />
StringObservable yourName;
Viewのイベントをコード側のメソッドと関
連付ける宣言
従来、setOn~~Listenerとやっていた箇所
buttonClick = new Command() {
};
<Button
binding:onClick="buttonClick"
/>
ViewModelView
CommandのInvokeメソッドが実行される
このときもView(UI)の名前を
一切使っていない!
public Command buttonClick = new Command() {
@Override
public void Invoke(View parent, Object... args) {
yourName.set("じんぐる");
}
};
View(UI)とViewModelを紐づける機構
setAndBindRootViewで紐づけ
public class MainActivity extends BindingActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//ViewModelをインスタンス化
MainActivityViewModel vm = new MainActivityViewModel();
setAndBindRootView(R.layout.activity_main, vm);
}
}
アプリ初期化のおまじない
Appの起動クラスとAndroid-Bindingライブラリの初期化
を追加
起動クラスを
Android.manifestへ宣言
// Applicationエントリーポイント
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
// Android-Bindingライブラリの初期化
Binder.init(this);
}
}
Before
Android-Binding
public class MainActivity extendsActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button)findViewById(R.id.hello_button);
button.setOnClickListener(newOnClickListener() {
@Override
public void onClick(View arg0) {
TextView textView = (TextView)findViewById(R.id.hello_text);
textView.setText("じんぐる");
After
Android-Binding
public class MainActivity extends BindingActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MainActivityViewModel vm
= new MainActivityViewModel();
setAndBindRootView (
R.layout.activity_main, vm);
}
}
public class MainActivityViewModel {
public StringObservable yourName = new StringObservable();
public Command buttonOnClick = new Command() {
@Override
public void Invoke(View parent, Object... args) {
yourName.set("じんぐる!!");
}
};
複雑な
Androidアプリ
1. EditTextに入力
2. Addボタン押下でListViewに項目追加
3. ListViewの項目押下でToast表示
ListView
MainActivityクラス ArrayAdapterクラス
// ListViewに表示するデータ
ArrayList<String> datas;
// ListViewの1行を表示するメソッド
View getView(int position,View
convertView,ViewGroup parent) {
inflater.inflate(R.layout.list_item, null);
}
list_item.xml
ListView1行のView
main_activity.xml
メイン画面のView
ArrayAdapter
R.layout.list_item
list_item.xml
ListView1行のView
activity_main.xml
メイン画面のView
MainActivity
R.layout.nameListView
setOnClickListener
setOnItemClickListener
list_item.xml
ListView1行のView
activity_main.xml
メイン画面のView
MainActivityViewModel
// ListViewのItemsとBindするインスタンス
publicArrayListObservable<ListViewItemViewModel> datas;
// ListViewでクリックされたItemとBindするインスタンス
publicObjectObservable clickedListViewItem;
ListViewItemViewModel
// ListView ItemのデータとBind
public StringObservable data
MainActivity
<TextView binding:text="data" />
<ListView
binding:itemSource="datas"
binding:clickedItem="clickedListViewItem"
binding:onItemClicked="listViewOnItemClick"
binding:itemTemplate="@layout/list_item">
public StringObservable yourName;
public ArrayListObservable<ListViewItemViewModel> datas;
public ObjectObservable clickedListViewItem ;
public Command listViewOnItemClick;
// ListView ItemのデータとBind
public StringObservable data;
MainActivity
// Add ButtonのClick処理
publicCommand buttonOnClick = new Command() {
@Override
public void Invoke(View parent, Object... args) {
// ListViewItemのためのViewModelを生成
ListViewItemViewModel viewModel =
new ListViewItemViewModel(yourName.get());
// ListViewのItemsにBindしている
//インスタンスにデータを追加
// これによりListViewへ追加が行われる
datas.add(viewModel); // ArrayListObservable<ListViewItemViewModel> datas
// EditTextの入力値をクリア
yourName.set("");
}
};
メリット
• findViewById(...)から解放される
• コード側がViewの型を意識しなくてよくなる
• 分業とか...は理想論ですねw
デメリット
• Layout.xml の タグ
binding:xxx="yyy" が手打ち
 Android-Bindingでスッキリしたコードを目
指せる
 Microsoft.NETのXAMLと同じ概念ですので、
XAMLerな方はAndroid-BindingでAndroid開
発者にデビューできちゃう!(かも)
 Android-BindingはMITライセンス
(昔はLGPLだった)
 Javaはとっとと型推論を!
Android-Binding Before/After (Hokuriku,NET)

Android-Binding Before/After (Hokuriku,NET)