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).

1 件のコメント:

  1. If you need your ex-girlfriend or ex-boyfriend to come crawling back to you on their knees (no matter why you broke up) you have to watch this video
    right away...

    (VIDEO) Why your ex will NEVER get back...

    返信削除