MVVMからAndroidのAdapterを考える

いまいちよくわからないAndroidのAdapterですが、WPFとMVVMを勉強してから戻ってきたらちょっと見え方が変わったよ、という話です。

Androidでリストビューなどにデータを設定するときはArrayAdapterというものを使います。

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
    new String[] { "AAA", "BBB", "CCC" });
ListView listView = (ListView)findViewById(R.id.listView1);
listView.setAdapter(adapter);

初めてみたときは、「なんだこれ、いかついなぁ」と思ったものです。
単純にリストを表示したいだけなのに、コレクションからAdapterに詰め替えをして、さらにandroid.R.layout.simple_list_item_1なるおまじないを書かなければならないのが初心者的には謎でした。
ちなみにWindows Formsではこんなです。ゎかりゃすぃょぅ。。

listView1.Items.Add("AAA");
listView1.Items.Add("BBB");
listView1.Items.Add("CCC");


ちょっと話が変わって、WPFXAMLにはBinding式という機能があります。
以下のようなViewModelがありまして、(細かいところは前回のエントリを)

class ViewModel : ViewModelBase {
    public ObservableCollection<String> Items { get; set; }

    public ViewModel()
    {
        Items = new ObservableCollection<string>();
    }
}

画面側のXAMLには以下のように書きます。

        <ListBox Margin="0" ItemsSource="{Binding Items}"/>

こうすることで、Itemsの内容を画面のリストビューに表示できます。
また、ObservableCollection(BindingListと呼べばピンとくるかも)を使っているので、コレクションに追加・削除するだけで変更が通知されて画面が更新されます。

Androidでも似たようなことができます。
実は上に書いたArrayAdapterがまさにそれで、

adapter.add("DDD");

とすると、画面のリストビューにも行が追加されます。

つまり、すごく大雑把にいえば、レイアウトXMLとアダプタの関係は、XAMLとObservableCollectionの関係と同じようなもんですね。
「アダプタ」というとレイアウトとコレクションの間をとりもつイメージがありますが、Adapterのみでコレクションの役目をこなすこともできます。


違いが見えてくるのは、一つのコレクションを複数のビューで見せようとした時です。
複数のビューというのは、たとえば画面上にリストビューが2個あって、一方は見出しのみ、もう一方は詳細表示するような場合です。
XAMLだと、単純に2つのリストビューを記述して、Binding式を埋め込むだけです。
Layout+Adapterだと、Adapterを作成するとき引数に指定するレイアウトはリストの1項目分のレイアウトのため、表示方法の違うビューがあればその数だけLayoutとAdapterを作成する必要があります。
絵にするとこんな感じでしょうか。

つまりArrayAdapterというのは、レイアウトとコレクションのデータのマッピングを司るとともに(Binding式に相当)、コレクションの更新状況を画面側に中継する(ObservableCollectionに相当)という、高度な使命をもったクラスだったのです。
.NETがシンプルに見えるのは、間に挟まったViewModelが、画面とロジックの間の入出力を「プロパティ」と「コマンド」に単純化してくれたのと、そのおかげで実現した「Binding式」が強力なためだと思います。

まとめます。
AndroidのArrayAdapterクラスは、その実、画面とコレクションの間に挟まって、データバインディングと更新通知を行うクラスでした。
これは表現の仕方こそ違いますが、.NETでXAMLMVVMパターンを使うのとやりたい事は一緒です。
MVVMパターンのほうが洗練されていると思いますが、クラスとXMLでなんでもやるぜ!という姿勢がいかにもJavaらしく、Eclipseとの親和性も高いので、日本ではAndroidのほうが流行る気がします。
Microsoftは常に先端を走っていて(少なくともプログラミング工学的には)いつもイカしたものを作るのに(C#とかDHTMLとか)、いまいち大勢に受け入れられてない気がするのが残念です。Linqとか、Linqとか、あとLinqとかですね。

今、試しに linq をググったら、トップに来るのが2011年デビューの九州発アイドルグループ「LinQ」ですよ。
Linqなんてネーミングがかぶるとは思わなかったけど、まさかのアイドル業界からダイナミックエントリーですよ。
上から3番目にようやっと「統合言語クエリ - Wikipedia
これは泣けます。
この3年間、MSの広報は何をやっていたのかと。
どうにかコラボできないか、真剣に検討していただきたい所です。