Revision 11 as of 2010-10-06 11:13:42

Clear message
Locked History Actions

Android/Views

AndroidのViewについて

AndroidのViewの概念は、一見他のGUIツールキットと同じように見えるのだが、大きく違うところがある。 様々な書籍やウェブサイトでの記事もこの点を明確に指摘しているところは、ほぼ存在しない。

つまり、Android特有の用語が何を意味するのか全く定義せずに話を進めているため、読む方としては 何のことやらわからないという状態になってしまう。 様々なGUIツールキットを経験している人間であるほど理解不能に陥ってしまう。

※私もまだよくわかっていないため、以下の記述はウソである可能性がある。

Swing等との違い

AndroidではSwing等のコンポーネントと同じように、Viewを入れ子にして画面を作成していく。 ViewはSwingの場合のコンポーネントに対応する。

しかし、ListViewなど、実行時までその中身の繰り返し数がわからない場合の扱いはSwingとAndroidでは全く異なる概念になる。

Swingでは、リストコンポーネント等に対してデータ(モデル)を与えれば、そのコンポーネント自体の大きさが変化して、すべてのデータが表示できるようにしてくれる。もし、このコンポーネントがScrollPaneの上にあれば、適切にスクロールバーがつけられる。

しかし、Androidではそうはいかないようだ。ListViewに任意の数のデータを表示するには、その同じ数のViewを用意して、それらをListViewに置いてやらないといけないらしい(実際にはそれほど面倒ではないし、必ずしもすべてを用意する必要もないのだが、概念的にはこういうことになる)。

Swingのコンポーネントのように、一つのコンポーネントの中で繰り返しデータをすべて表示するという発想ではなく、必要なだけViewを作成しなければならないのである。

※さらに細かいことを言えば、Swingの場合には、その中身(例えば、JTableのセル)の表示や編集においては、そのセルごとに異なるコンポーネントが作成できるようにはなっているが、実際には一つのコンポーネントが使いまわされるケースが多い。

Adapter

これを簡単に行ってくれるのがAdapterなのだが、この言葉はもちろんSwingのとは全く概念的に異なる。

Swingでは主にイベントリスナインターフェースの空の実装を差している場合が多い。 これに対してAndroidでは、「与えられたデータと同じ数の適当なViewを作成して、そこにデータを設定してListViewなどに載せてくれるもの」という意味である(再度、あくまでもこれは概念的な話)。

多くの書籍等の説明では、データとListViewなどをとりもつ役割などと簡単にしか説明していないので、Swing使いには「モデルの役割」であると誤解されてしまう可能性があるのだが、全くそうではない。

Inflater

さらに、Inflater, Inflate, Inflationという言葉は、これが何を差しているのか、どこを探しても全く説明が見つからない。

これは単純にリソース中のXMLに記述されたView定義をもとにJavaオブジェクトを作成するということらしい。

ただし、単純に一対一、つまり一つのXML定義からただ一つのJavaオブジェクトが作成されるのではなく、inflate操作を行うごとにいくつでもJavaオブジェクトを作成できるようだ。つまり、XML定義は単なるテンプレートである。

このため、例えば、先のAdapterのように「いくつのViewが必要であるかわからない」というケースでは、その数だけ該当するXML定義をInflateしてViewのJavaオブジェクトを作成してやるということになる。

※ただし、inflateは「重い」操作であるので、大量にViewオブジェクトを作成する場合は、inflateではなく直接Viewオブジェクトを作成してしまった方が良いようだ。

ショートカットによる誤解

例えば、ActivityのonCreate()のメソッド内でsetContentView(R.layout.main)などと、リソースIDを指定することを、単純に「コンテンツビューを指定する」などと説明してしまうと、これも大きな誤解のもとになる。

APIの説明は「Set the activity content from a layout resource. The resource will be inflated, adding all top-level views to the activity.」となっている。

つまり、リソースをコンテンツビューに指定するのではなく、指定されたリソースから作成された(inflateされた)Javaオブジェクトをコンテンツビューとして指定するのである。これは単純にショートカットに過ぎない。

そもそもリソースは後回しでよい

多くの書籍、多くのウェブサイトにて初めから「レイアウト」にまでリソースを使わせているが、これがそもそもおかしい。 リソースは必要になった時に使えばよいものであり、かつ必要であるかどうかはプログラムを記述している本人自身が認識すべきものである。 初めからリソースなど使う必要はないのである(もちろん、画像等はリソースにしておかなければアクセスできないようであるが)。

リソースを使うことによりコードが分断されると、それだけ理解しにくくなることは明らかである。 なおかつ、Androidのリソースには名前空間が無いので、巨大なプログラムを作成しようとすれば、この点は必ず問題になるはずなのであるが (あるいは、回避方法があるはずなのだが)、どういうわけかそのような指摘をしている書籍やウェブサイトも無いようだ。

APIが見つからない

例えば、少なくはないウェブサイトでActivity#getViewInflate()というメソッドについて言及されているが、このようなメソッドはどこを探しても見つからない。

単純に正規リリース前に定義されていたAPIなのであろうか?この点はまだよくわかっていない。