Android で画面遷移をする場合、Activity を利用するように書かれていることが多い。つまり「Activity = ウィンドウ」というとらえ方だが、実際には Activity は Intent 経由で呼び出す単位であり、Activity を分けることにより、アプリケーションの機能の一部を外部から利用できるようになる。Activity を切り替えると、呼び出し元の Activity は pause 状態になり、呼び出し先の Activity が実行中の状態になる。このため、Activity の切り替えは比較的重い処理で、Activity 間の情報のやりとりも Intent 経由で行わなければならなくなる。
前置きが長くなったが、Activity を切り替えずに画面遷移をしたいという理由で ViewGroup を自作してみることにした。もちろん、ViewGroup を自作しなくても、Activity 内でsetContentView(int)を呼び出せば、レイアウト用の XML を利用して View を切り替えることができるのだが、XML に定義した一部分が切り替わるようにしたかったのだ。たとえば以下のような感じ。
<HogeViewGroup android:layout_width="fill_parent" android:layout_height="fill_parent" > <include layout="@layout/layout1" /> <include layout="@layout/layout2" /> <include layout="@layout/layout3" /> </HogeViewGroup>
早速調べてみた。Android のレイアウト XML の中では、ViewGroup を継承したクラスだけが子の要素を持つことができる。最初は ViewGroup の中で XML を解析しているのかと思ったが、ソースコードを見ると XML を解析している様子がない。どうも、LayoutInflater が ViewGroup の addView を呼び出しているようだ。実験のために、FrameLayout を継承して addView をオーバーライドしてログを出力してみると、以下の順で呼び出された。
addView(View), android.widget.LinearLayout addView(View, int), android.widget.LinearLayout addView(View, int, ViewGroup.LayoutParams), android.widget.LinearLayout
ログを詳細に見てみると、
- Activity の onStart => onResume
- HogeViewGroup の子要素の View のインスタンスを生成
- HogeViewGroup の addView の呼び出し
という順序になっていた。ViewGroup の addView はいくつか定義されているが、コードを読むと最終的には、addView(View, int, ViewGroup.LayoutParams)が呼び出されるようなので、オーバーライドすれば動作を変更できそうだ。ただ、子要素の View のインスタンスは自動的に生成されてしまうのが少し気になる。今回はまだできあがってないので(^^;;; 実際にうまくいくかどうか分からないが、ViewGroup の動きのまとめとして残しておくことにした。