2011年11月21日月曜日

RelativeLayout内に書くViewの順番

RelativeLayout内に書くViewの順番

この記事には、筆者自身がよく分かっていない事柄を、臆面も無く、書いてある。例えば、「宣言」とか「参照」とか「生成」という用語の使い方だ。
しかし、筆者の経験からして、機能面ではほぼ間違いのない事実であるので、ここに書き留めておき備忘録としておきたい。

RelativeLayoutをxmlで書く方法
RelativeLayoutは、それに含まれるViewを相対的な位置に配置するGroupViewである。相互の相対的な位置であるから、配置コマンドの中にViewを指定して書くことになる。
Viewを指定して書く場合、その書く順番に留意をしなければならない。IDを宣言しているコマンドを上に書いて、その下に、そのIDを参照しているコマンドを書くのである。
下記のxmlのsample codeの例では、IDを宣言している箇所を赤色で塗った。そして、それを参照している箇所を青色で塗った。
宣言を先に書き、参照を後に書くのである。

下記sampleでは、BottomViewを、物理画面の下端に配置するため、そのコマンドを、xmlの一番下に書いてしまいそうになる。しかし、そのようにすると、参照ができなくなり、エラーになる。
このエラーを発生させないようにするため、+記号付きの書式で書くこともできるが、「エラーを発生させたくない」ということを動機として+記号付き書式を採用して良いのであろうか。。。。まあ、別に良いですけど。

xml sample code
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    >
    <TextView
        android:id="@+id/TopView"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/ThisIs"
        android:layout_alignParentTop="true"
        >
    </TextView>
    <TextView
        android:id="@+id/BottomView"
        android:text="@string/ThisIs"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:layout_alignParentBottom="true"
        >
    </TextView>
    <ScrollView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" 
        android:layout_above="@id/BottomView"
        android:layout_below="@id/TopView"
        >
(以下省略)

IDの書式
以上の事柄を理解するためには、resourceのIDを取り扱うコマンドの書式を理解しておく必要がある。次のような似た書き方がある。
  • "@+id/TopView"
  • "@id/TopView"
@の次に+記号を付けるかどうかの違いである。
筆者は、これらを正確に理解していない。しかし、経験上、次のことが言える。

+記号を付けると、その+記号の右側の文字列のディレクトリがR.javaに生成される。そして、そのディレクトリの下に、/の右側にある文字列をIDとするものが生成される。
例えば、適当なViewの属性に、次のように書いてみる。
<LinearLayout
    android:id="@+OhMyGod/What"
(以下省略)
これをコンパイルして、genディレクトリの下にあるR.javaのRを見ると、OhMyGodがあり、更にその下にWhatがある。
このことから、+記号を付けた書式では、IDが生成されることが分かる。

+記号の無い書式は、お馴染みである。
例えば、"@string/app_name"というのは、string resourceの中のapp_nameというIDを指している。そして、このIDに関連付けられている文字列を参照することができるのである。
つまり、+記号の無い書式は、resourceへの参照機能を有するのである。生成はしない。
xmlは、上の行から下の行に向かって解析される。上の方で、IDの生成を行っておき、少なくとも、その行よりも下で、そのIDへの参照を行わねばならない。生成が無い段階で、そのIDを参照しようとするとエラーになる。

実際の書き方
以上の説明は、書式の趣旨に沿って書く方法であった。
試作品を作る場合や、複雑な形状のRelativeLayoutを作る場合であれば、+記号がある書式を用いることも有り得る。例:"@+id/TopView"
この書式は、既に述べたように、IDへの参照では無く、IDの生成である。

同一のIDをあちこちで生成したとしても、エラーにはならず、生成したIDをお互いに共有する仕掛けになっているようである。このため、上記に書いたような、書く順番を無視して書くことができる。
エラーを発する「参照書式」よりも、エラーを発しない「ID生成書式」が好まれるかもしれない。

もし、エラーを発する書式で書くのであれば、エラーを発生させないように書かざるを得ない。そうすれば、堅牢な作りになると思われる。IDの生成は(複数書くのではなく)1か所だけに留める書き方にするのである。
もし、エラーを発生する仕掛けがあるならば、それを喜んで使えば良い。そして、エラーを発生させないように書けば良い。

参考
android developersのCommon Layout ObjectsのRelativeLayoutに下記の注意書きがあります。
Note that the attributes that refer to relative elements (e.g., layout_toLeft) refer to the ID using the syntax of a relative resource (@id/id).

For example, assigning the parameter toLeft="my_button" to a TextView would place the TextView to the left of the View with the ID my_button (which must be written in the XML before the TextView).

0 件のコメント:

コメントを投稿