Mono Works

チラシのすきま

メモ:ビューの配置 - LinearLayout と RelativeLayout

レイアウト用 xmlファイルのサンプルを作っていると、よく見かける LinearLayoutと RelativeLayoutについて調べてみました。

日本語にすると、そのまんまです。

LinearLayout(直線的な配置)

RelativeLayout(相対的な配置)

LinearLayoutは、ビューを縦方向または横方向一列に並べる配置です。

RelativeLayoutは、親の位置を基準として相対的な指示でビューを配置する方法です。親を配置可能エリア全体とするか、任意の配置済みビューとするかで指示の方法が異なります。

LinearLayoutで縦一列に並べる

android:orientationに「vertical」を指定して、配置するビューを順番に記述するだけなので、実際にどんな感じに配置されるかイメージしやすいです。ただし、配置が一列に限られるので、縦横入り乱れた配置にする場合は、LinearLayoutの中にLinearLayoutを記述して、入れ子構造にする必要があります。

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

  <TextView
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:background="@color/blue900"
    android:textColor="@color/white"
    android:text="001"
    android:gravity="center" />

  <TextView
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:background="@color/blue400"
    android:textColor="@color/white"
    android:text="002"
    android:gravity="center" />

  <TextView
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:background="@color/blue900"
    android:textColor="@color/white"
    android:text="003"
    android:gravity="center" />

</LinearLayout>
androiddevmemo20150911_01

LinearLayoutで横一列に並べる

android:orientationに「horizontal」を指定。縦と横でここしか違いはありません。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="horizontal" >

  <TextView
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:background="@color/blue900"
    android:textColor="@color/white"
    android:text="001"
    android:gravity="center" />

  <TextView
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:background="@color/blue400"
    android:textColor="@color/white"
    android:text="002"
    android:gravity="center" />

  <TextView
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:background="@color/blue900"
    android:textColor="@color/white"
    android:text="003"
    android:gravity="center" />

</LinearLayout>
androiddevmemo20150911_02

配置可能エリア全体を親として相対的に配置する

LinearLayoutに比べると、配置できる自由度が高いので、いろいろなパターンがありますが、配置エリア全体を基準にしているので、レイアウトの指示を見ていけば、比較的、実際の配置がイメージしやすいです。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
   android:layout_height="match_parent" >

  /* 親(配置可能エリア全体)の左上 */
  <TextView
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"
    android:background="@color/blue900"
    android:textColor="@color/white"
    android:text="001"
    android:gravity="center" />

  /* 親(配置可能エリア全体)の中央上 */
  <TextView
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:layout_centerHorizontal="true"
    android:layout_alignParentTop="true"
    android:background="@color/blue900"
    android:textColor="@color/white"
    android:text="002"
    android:gravity="center" />

  /* 親(配置可能エリア全体)の右上 */
  <TextView
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:layout_alignParentRight="true"
    android:layout_alignParentTop="true"
    android:background="@color/blue900"
    android:textColor="@color/white"
    android:text="003"
    android:gravity="center" />

  /* 親(配置可能エリア全体)の左中 */
  <TextView
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:layout_alignParentLeft="true"
    android:layout_centerVertical="true"
    android:background="@color/blue900"
    android:textColor="@color/white"
    android:text="004"
    android:gravity="center" />

  /* 親(配置可能エリア全体)の中央 */
  <TextView
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:layout_centerInParent="true"
    android:background="@color/blue900"
    android:textColor="@color/white"
    android:text="005"
    android:gravity="center" />

  /* 親(配置可能エリア全体)の右中 */
  <TextView
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:layout_alignParentRight="true"
    android:layout_centerVertical="true"
    android:background="@color/blue900"
    android:textColor="@color/white"
    android:text="006"
    android:gravity="center" />

  /* 親(配置可能エリア全体)の左下 */
  <TextView
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:layout_alignParentLeft="true"
    android:layout_alignParentBottom="true"
    android:background="@color/blue900"
    android:textColor="@color/white"
    android:text="007"
    android:gravity="center" />

  /* 親(配置可能エリア全体)の中央下 */
  <TextView
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:layout_centerHorizontal="true"
    android:layout_alignParentBottom="true"
    android:background="@color/blue900"
    android:textColor="@color/white"
    android:text="008"
    android:gravity="center" />

  /* 親(配置可能エリア全体)の右下 */
  <TextView
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:layout_alignParentRight="true"
    android:layout_alignParentBottom="true"
    android:background="@color/blue900"
    android:textColor="@color/white"
    android:text="009"
    android:gravity="center" />

</RelativeLayout>
androiddevmemo20150911_03

あるビューを親として相対的に配置する

画面を親として相対的に配置する方法に比べて、さらに自由度が高いですが、レイアウトの指示が分かりにくく、実際の配置がイメージしにくいです。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
   android:layout_height="match_parent" >

/* 画面全体の中央(基準となるビュー) */
  <TextView
    android:id="@+id/baseview"
    android:layout_width="200dp"
    android:layout_height="200dp"
    android:layout_centerInParent="true"
    android:background="@color/blue900"
    android:textColor="@color/white"
    android:text="000"
    android:gravity="center" />

  /* 親(ビュー000)の左上・外側 */
  <TextView
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:layout_toLeftOf="@id/baseview"
    android:layout_above="@id/baseview"
    android:background="@color/blue400"
    android:textColor="@color/white"
    android:text="001"
    android:gravity="center" />

  /* 親(ビュー000)の中央上・外側 */
  <TextView
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:layout_centerHorizontal="true"
    android:layout_above="@id/baseview"
    android:background="@color/blue400"
    android:textColor="@color/white"
    android:text="002"
    android:gravity="center" />

  /* 親(ビュー000)の右上・内側 */
  <TextView
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:layout_alignRight="@id/baseview"
    android:layout_alignTop="@id/baseview"
    android:background="@color/blue400"
    android:textColor="@color/white"
    android:text="003"
    android:gravity="center" />

  /* 親(ビュー000)の左中央・外側 */
  <TextView
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:layout_toLeftOf="@id/baseview"
    android:layout_centerVertical="true"
    android:layout_alignBaseline="@id/baseview"
    android:background="@color/blue400"
    android:textColor="@color/white"
    android:text="004"
    android:gravity="center" />

  /* 親(ビュー000)の右中央・内側 */
  <TextView
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:layout_alignRight="@id/baseview"
    android:layout_centerVertical="true"
    android:background="@color/blue400"
    android:textColor="@color/white"
    android:text="005"
    android:gravity="center" />

  /* 親(ビュー000)の左下・内側 */
  <TextView
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:layout_alignLeft="@id/baseview"
    android:layout_alignBottom="@id/baseview"
    android:background="@color/blue400"
    android:textColor="@color/white"
    android:text="006"
    android:gravity="center" />

  /* 親(ビュー000)の中央下・内側 */
  <TextView
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:layout_centerHorizontal="true"
    android:layout_alignBottom="@id/baseview"
    android:background="@color/blue400"
    android:textColor="@color/white"
    android:text="007"
    android:gravity="center" />

  /* 親(ビュー000)の右下・外側 */
  <TextView
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:layout_toRightOf="@id/baseview"
    android:layout_below="@id/baseview"
    android:background="@color/blue400"
    android:textColor="@color/white"
    android:text="008"
    android:gravity="center" />

</RelativeLayout>
androiddevmemo20150911_04

実際の配置では、これまでに紹介したレイアウトを組み合わせて配置したり、本日紹介できなかったレイアウトもあります。画面のレイアウトって、単に並べているだけのように見えて、実際は、かなり面倒な作業なんですね。

ちなみに色指定のcolors.xmlには、こんな感じで指定しました。

<resources>
  <color name="blue900">#0D47A1</color>
  <color name="blue400">#42A5F5</color>
  <color name="white">#FFFFFF</color>
</resources>

おひれ

RTL(right-to-left)言語は、アラビア語など右から左へ記述する言語です。Androidでは、言語の設定でアラビア語などを選択すると、全体のレイアウトが左右逆の配置になります。なので、もしこれらの言語への対応を考える場合は、左右を基準に記述せずにStart、Endを基準にして記述しておきます。

具体的には、layout_alignLeftやlayout_toRightといった左右の指定方法から、下記のような記述に切り替えれると対応できます。なお、minSdkVersionが17未満の場合は、Left、RightとStart、Endを併記する必要がありますが、、17以上ならStart、Endのみで大丈夫です。

android:layout_alignStart="@+id/baseview"
android:layout_alignEnd="@+id/baseview"
android:layout_toStartOf="@+id/baseview"
android:layout_toEndOf="@+id/baseview"

あとは、AndroidManifest.xml<application>内にadd android:supportsRtl="true"と記述したり、細かいところでは、アラビア語に対応したstrings.xmlとかも用意することになります。

【参考サイト】

LinearLayout | Android Developers

LinearLayout.LayoutParams | Android Developers

RelativeLayout | Android Developers

RelativeLayout.LayoutParams | Android Developers

コメント

コメントなどありましたら、GitHubのディスカッションへお願いします。(書き込みには、GitHubのアカウントが必要です)
執筆者
"ぽぽろんち" @pporoch
pporoch120
Mono Worksの中の人。好きなことをつらつらと書き留めてます。
ギターを始めてから 練習動画をYouTubeにアップしてます。ご笑納ください。
"DQX@ぬここ(UD487-754)、コツメ(NO078-818)"
採用案内