ASとか

開発系の記事が多めです。タイトルのASはActionScriptの略です。

layout_weightの使い方

はじめに

layout_weightすごくよく使うけど本質を理解してなかったので調べたことをメモ

基本

layout_weightには、"親ビューの余白を振り分ける比率"を設定する

親ビューの余白

例えばlayout_heightが100dpに設定されたLinearLayoutの上にTextViewを2つ置く場合、それぞれのlayout_weightを1に設定すれば、50dpずつ振り分けられます。

<LinearLayout
    android:layout_width="match_parent"
    android:id="@+id/linearLayout1"
    android:orientation="vertical"
    android:layout_height="100dp"
    >
    <TextView
        android:id="@+id/textView1"
        android:text="TextView1"
        android:layout_height="0dp"
        android:layout_width="match_parent"
        android:layout_weight="1">
    </TextView>
    <TextView
        android:id="@+id/textView2"
        android:text="TextView2"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">
    </TextView>
</LinearLayout>

ここで気をつけたいのが、各TextViewのlayout_heightを0dpに指定していることです。この理由は、layout_weightを指定したとしてもlayout_heightが無視されるわけではないということです。例えばtextView1のlayout_heightを30dpに指定したとすると、親の余白は70dpとなり、textView1は(30dp + 35dp)、textView2は(35dp)の縦幅になってしまいます。もしtextView1にmatch_parentを指定した場合、textView2は画面に表示されなくなってしまいます。

妙な挙動について

こちらのブログで説明している、子ビュー全てをmatch_parent(ブログ内ではfill_parentですが)にした場合、妙な表示になってしまう件について、理解に少し時間がかかったのでメモ

サンプルプログラム

上記ブログ内サンプルの縦バージョンです

<LinearLayout
    android:layout_width="match_parent"
    android:id="@+id/linearLayout1"
    android:orientation="vertical"
    android:layout_height="100dp"
    >
    <TextView
        android:id="@+id/textView1"
        android:text="TextView1"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:layout_weight="1">
    </TextView>
    <TextView
        android:id="@+id/textView2"
        android:text="TextView2"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="2">
    </TextView>
    <TextView
        android:id="@+id/textView3"
        android:text="TextView3"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="3">
    </TextView>
</LinearLayout>

この表示は、textView1が画面の2/3、textView2が3/1を占拠し、textView3に至っては画面から消えてしまいます。

余白は負の値になりうる

TextViewを3つ置き、全てのlayout_widthをmatch_parentにした場合、余白は0でなく、TextViewの横幅(match_parentなので親ビューの幅)2つ分マイナスになるようです。

負の値に対するweightの動き

TextViewの横幅を1とすると、余白は-2となり、各TextViewのweightは

-2 * (設定したlayout_weight / 各TextViewのlayout_weight合計値)

となります。

textView1が画面の2/3になる理由

先ほどの式に当てはめると

-2 * (1/6) = -0.3

となり、横幅の1/3分マイナスとなります。ここに元々設定していたlayout_heightが合わさり

1 + (-0.3) = 0.7

となります。

textView2が画面の3/1になる理由

textView1の理由と変わりません。

textView3が表示されない理由

textView1の理由と(ry。合計値が0となってしまうため、画面上に表示されません。

まとめ

  • layout_weightとは、"親ビューの余白を振り分ける比率"である
  • 親ビューの余白は[親ビューの幅 - 各子ビューの幅(margin含む)]で求められる
  • 親ビューの余白は負の値になりうる
  • layout_weightを素直に反映させたい場合は、weightが反映される方(width or height)を0dpにする