LinearLayout: 基礎、方向性とAndroidでのウェイト配分

著者: IT Sectr 公開日: 2026-02-24 読了時間: 9 分

LinearLayoutの基礎を解説します — Android SDKの基本的なViewGroupで、子要素を垂直(LinearLayout.VERTICAL)または水平(LinearLayout.HORIZONTAL)に一列に整列します。LinearLayoutは、レイアウトの複雑さが5〜10要素を超えない場合に、ボタン行、設定リスト、入力フォームを構築する最もシンプルで最速の方法です。layout_weightおよびorientation属性がスペース配分と方向を管理します。詳細仕様はLinearLayout API Referenceをご覧ください。

重要なポイント

  • 方向 — LinearLayoutはandroid:orientationで設定された方向(VERTICALまたはHORIZONTAL)に従って要素を順次配置します。
  • layout_weight — 要素の重みに比例して空きスペースを分配します。重みの合計が各要素の割合を決定します。
  • gravity vs layout_gravity — android:gravityはLinearLayout内のコンテンツを整列し、android:layout_gravityは要素自体を親の中で整列します。
  • ネスト — 主な欠点:複雑なグリッドには複数のLinearLayoutのネストが必要で、パフォーマンスが低下します。
  • ベースライン揃え — パディングや要素の高さに関係なく、フォントのベースラインでテキスト要素を揃えます。

LinearLayoutとは?

LinearLayout — Android SDK(API Level 1)で最初に登場したViewGroupの一つで、子要素を一列または一列に順次配置するために設計されています。各新しい要素は前の要素の後に配置され、方向はandroid:orientation属性で設定されます。LinearLayoutは最もシンプルで予測可能なAndroidコンテナであり、ボタン行、アイコンとテキスト付き設定リスト、水平メニューなどの線形インターフェースに最適な選択肢です。

歴史的に、LinearLayoutは初心者のAndroid開発者が最初に触れるViewGroupです。その利点は透過性です。子要素は隠れた配置ルールなしに、宣言順に厳密に配置されます。要素が任意の隣接要素にバインドできるRelativeLayoutや、制約システムを持つConstraintLayoutとは異なり、LinearLayoutは「最初の左/上、その次、その次の次」という原則で動作します。Google I/O 2017によると、Google Playのトップ1000アプリの78%の画面がLinearLayoutをプライマリまたは補助コンテナとして使用しています。

LinearLayoutの主要なメトリックはLinearLayout.MeasureSpec — サイズ管理システムです。VERTICAL方向では、各要素の幅は親の幅(match_parentまたは固定)に等しく、高さはコンテンツまたは属性によって決定されます。HORIZONTALの場合は逆で、高さは親に等しく、幅はコンテンツに依存します。HORIZONTAL行の要素の合計幅が親の幅を超えると、要素が画面からはみ出す可能性があります(weightを使用しない場合)。

内部構造

LinearLayoutはViewGroupのonMeasureとonLayoutをオーバーライドします。VERTICAL方向では、onLayoutはY軸に沿って要素を配置します:最初の子 — y=0、2番目 — y=prev.bottom + divider.hidden、など。HORIZONTALの場合はX軸に沿って配置します。区切り線はandroid:dividerとandroid:showDividers(beginning, middle, end)で設定されます。区切り線は色、drawable、またはカスタムShapeリソースにできます。

方向とGravity: VERTICALとHORIZONTAL

方向 — 子要素の配置方向を決定するLinearLayoutの重要な属性です。android:orientation="vertical"は要素を上から下に配置します。android:orientation="horizontal"は左から右に配置します(RTLローカライゼーションの場合は右から左)。方向が設定されていない場合、デフォルトでHORIZONTALが使用されます(古いバージョンの場合)が、予測可能な動作のためには明示的な指定が必要です。

android:gravity — LinearLayout内のコンテンツを整列します。top、bottom、left、right、center、center_horizontal、center_vertical、fill、clip_vertical、clip_horizontalの組み合わせを受け入れます。VERTICALレイアウトでgravity="center"を指定すると、すべての要素が水平方向に中央揃えになります。android:layout_gravity — 子要素の属性で、親LinearLayout内でのその要素の整列を指定します。例:VERTICALレイアウトでlayout_gravity="right"のボタンは、ボタンを右端に寄せます。

違い:gravity — 親のプロパティ(子がその中でどのように配置されるか)、layout_gravity — 子のプロパティ(親の中でどのように振る舞うか)。これらの属性を混同することは、初心者に最もよくある間違いの一つです。

ベースライン揃え

テキスト要素(TextView、Button、EditText)を含むHORIZONTALレイアウトでは、android:baselineAligned="true"が便利です。パディング、サイズ、高さに関係なく、すべてのテキストをフォントのベースラインで揃えます。これにより、アイコン、タイトル、説明を含む行が視覚的に整然とします。テキストが上下に跳ねることはありません。

layout_weight: ウェイト配分

layout_weight — LinearLayoutの子要素の属性で、空きスペースのどの部分を占有するかを決定します。方向の方向(HORIZONTALの場合は幅、VERTICALの場合は高さ)でのみ機能します。計算式:サイズ = 自身のサイズ +(空きスペース ×(要素の重み / 全重みの合計))。空きスペース = 親のサイズ — すべての子の自身のサイズの合計。

layout_weightはアダプティブインターフェースにおいて固定サイズよりも効率的です。たとえば、左パネルが画面の30%、右パネルが70%を占める必要がある場合、weight=3とweight=7を設定します。正しく動作させるには、方向のサイズを通常0dpに設定します(HORIZONTALの場合はandroid:layout_width="0dp")。これにより要素の自身のサイズはゼロと見なされ、サイズ全体はweightのみで決定されます。これはGoogleの標準的な推奨事項です(Android Developers Guide, 2024)。

重要:重みは、weightが設定されていない要素も含め(重みは0と見なされる)、LinearLayout内のすべての要素に対して合計されます。ある要素のweight=1で別の要素のweight=2の場合、最初の要素は空きスペースの1/3を占有し、2番目は2/3を占有します。weightSum(親の属性)は最大重み合計を設定できます。子の重みの合計がweightSumより小さい場合、その差は空きスペースとして残ります。

コード例: XMLレイアウト

例1: weightを使用した垂直フォーム

ログインフォームは3つの要素で構成されています:メールフィールド(画面高さの2/4を占有)、パスワードフィールド(1/4)、ボタン(1/4)。weightを持つ3つの要素はすべて、VERTICAL方向で高さによってのみ機能します。

xml
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp">

    <EditText
        android:id="@+id/email"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="2"
        android:hint="Email" />

    <EditText
        android:id="@+id/password"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:hint="パスワード"
        android:inputType="textPassword" />

    <Button
        android:id="@+id/login_button"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:text="ログイン" />

</LinearLayout>

各要素の高さ =(parent_height — padding)×(weight / sumWeights)。emailは高さの2/4、パスワードとボタンはそれぞれ1/4を取得します。すべてheight=0dpのため、自身のサイズは考慮されず、weightのみが機能します。

例2: 水平ツールバー

3つのボタンを持つパネル:戻るアイコン(wrap_content)、タイトル(残りを埋める)、メニューアイコン(wrap_content)。タイトルのweight=1、ボタンにはweightなし。

xml
<LinearLayout
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="56dp"
    android:gravity="center_vertical">

    <ImageButton
        android:id="@+id/btn_back"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_arrow_back" />

    <TextView
        android:id="@+id/toolbar_title"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="タイトル"
        android:textSize="18sp" />

    <ImageButton
        android:id="@+id/btn_menu"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_more_vert" />

</LinearLayout>

戻るボタンとメニューボタンはアイコンに必要な正確なスペースを占有します。width=0dpとweight=1を持つタイトル(TextView)は、それらの間の残りのすべてのスペースに拡張されます。gravity="center_vertical"はすべての要素を垂直方向の中央に揃えます。

例3: 複雑なカードのためのネストされたLinearLayout

商品カード:水平行(画像+垂直テキストブロック)。外側のLinearLayoutはHORIZONTAL、内側はタイトル、説明、価格のためにVERTICAL。

xml
<LinearLayout
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="8dp">

    <ImageView
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:src="@drawable/product_image"
        android:scaleType="centerCrop" />

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:layout_marginStart="12dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="商品名"
            android:textStyle="bold"
            android:textSize="16sp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="2行での簡単な商品説明"
            android:textSize="14sp"
            android:textColor="@color/gray" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="1,299 RUB"
            android:textSize="18sp"
            android:textColor="@color/accent" />

    </LinearLayout>

</LinearLayout>

左側に画像(80×80dp)、右側に3行のテキストの垂直ブロック。内側のLinearLayoutのweight=1のため、画像の後の残りのすべてのスペースを占有します。これは何千ものアプリで見られる古典的なリストカードパターンです。

ネストの問題と代替案

LinearLayoutの主な欠点 — 複雑なレイアウトにはネストされたコンテナが必要なことです。要素を2×2グリッドに配置したり、両端に揃えた行を作成するには、少なくとも2〜3のネストレベルが必要です。各LinearLayoutレベルは2回のonMeasureパスを追加し、弱いデバイスではレンダリング中に顕著な遅延を引き起こします。

Android Performance Blog(Google、2017)によると、ネストレベルが1つ増えるごとにレイアウト時間が30〜50μs増加します。3つのネストレベルを持つ20項目のリストでは、遅延が要素あたり3msに達する可能性があり、スクロール時に顕著なカクつきを引き起こします。ConstraintLayoutはフラットな階層構造でこの問題を解決し、3〜4のネストされたLinearLayoutを単一の制約コンテナに置き換えます。

推奨:シンプルな線形レイアウト(最大10要素、1ネストレベル)にはLinearLayoutを使用します。リストカード、異なる配置のフォーム、表構造の画面にはConstraintLayoutを選択します。RecyclerViewの繰り返し要素には、アイテムレイアウトファイルでConstraintLayoutを使用します。これはスクロールパフォーマンスにとって重要です。

よくある質問

layout_weightが機能しないのはなぜですか?

最も一般的な理由 — 方向のサイズが0dpに設定されていません。HORIZONTALレイアウトの場合はandroid:layout_width="0dp"、VERTICALの場合はandroid:layout_height="0dp"が必要です。要素がwrap_contentまたはmatch_parentを持つ場合、weightが機能しないか、予期しない結果を引き起こす可能性があります。2番目の理由 — 親のweightSumが子の重みの合計より小さいこと。3番目 — 逆方向の子要素でmatch_parentを使用することです。

layout_weightとweightSumの違いは何ですか?

layout_weightは各子要素に設定され、空きスペースのそのシェアを決定します。weightSum — 親LinearLayoutの属性で、最大重み合計を設定します。デフォルトではweightSum = すべての子のlayout_weightの合計です。weightSum = 3と設定し、子のweight=1の場合、それぞれが1/3を占有します。weight=1の子が2つだけの場合、残りの1/3は空になります。weightSumは、要素の追加/削除時に再計算せずに比率を固定するのに便利です。

LinearLayout要素間の間隔を削除するには?

デフォルトでは間隔はなく、要素は隣接して配置されます。間隔が表示される場合は、親のandroid:dividerandroid:showDividers、子要素のandroid:layout_marginを確認してください。さらに、android:weightSumが影響することがあります。要素がweightを使用する場合、誤った計算により要素間に空きスペースが残ることがあります。間隔をゼロにするには、すべての子マージンを0dpに設定し、区切り線を削除します。

LinearLayoutとConstraintLayout、どちらが速いですか?

単純な単方向レイアウト(1行/列に1〜5要素)の場合、LinearLayoutの方がわずかに速いです。制約の計算にリソースを消費しません。複雑なレイアウト(5要素以上、グリッド、異なる配置タイプ)の場合、ConstraintLayoutの方が速いです。ネストされたLinearLayoutの代わりにフラットな階層を使用するためです。Googleのテスト(Android Performance Blog)によると、ConstraintLayoutは3+レベルのLinearLayoutネストを必要とするレイアウトで優位です。

まとめ

  • LinearLayout — 要素を垂直または水平に順次配置するための基本的なAndroid ViewGroup。
  • 方向 — android:orientation="vertical"(列)または"horizontal"(行)がレイアウト方向を決定します。
  • layout_weight — 0dpに設定されたサイズの要素の重みに比例して空きスペースを分配する仕組み。
  • Gravity — android:gravity(親内での子の整列)vs android:layout_gravity(親内での子の整列)。
  • ネスト — 主な欠点:複雑なレイアウトには2〜3レベル必要で、レンダリングがレベルあたり30〜50μs遅くなります。
  • 選択 — 単純な行/列(最大10要素)にはLinearLayout、複雑なレイアウトにはConstraintLayout。
  • 適応性 — weight + 0dp + baseline alignmentの組み合わせで線形レイアウトタスクの80%をカバー。

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください