-
Notifications
You must be signed in to change notification settings - Fork 354
2.01. アプリのレイアウト作成
この章では、Android アプリ画面のレイアウトの作り方を学びます。
参考:Layouts | Android Developers
参考:Supporting Different Densities | Android Developers
参考:Supporting Multiple Screens | Android Developers
- 画面を構成する要素
- [View を配置する](#View を配置する) - サイズ - パディング、マージン - 位置 - 単位 - dip - sp
- レイアウトを作成する - LinearLayout - [Layout Weight](#Layout Weight) - RelativeLayout - FrameLayout - ScrollView
- 実習・課題
画面を構成する要素となる View には以下のようなものがあります。
TextView、EditText、ImageView、Button、CheckBox、RadioButton といったウィジェット(Widget)と、
LinearLayout、RelativeLayout、FrameLayout といったウィジェットを取りまとめるレイアウト(Layout)です。
これらウィジェットとレイアウトをまとめて、View と呼びます。
View を配置する際に使用する各種パラメータについて説明します。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="hello_world" />
</RelativeLayout>
要素 | 意味 |
---|---|
android:layout_height | Viewの高さ |
android:layout_width | Viewの横幅 |
android:layout_height
とandroid:layout_width
で指定できる値は、数値 dp
,sp
,px
などとmatch_parent
(fill_parent
)とwrap_content
となります。
match_parent
は、親のViewと同じサイズに調整されます。
wrap_content
は、コンテンツを表示するのに十分なサイズに調整されます。上記サンプルの場合、TextViewのサイズは"hello_world"を表示するのに必要なサイズへと調整されます。
fill_parent
はmatch_parent
は同じ機能ですが、API Level 8から非推奨となっています。
API Level 7以下をターゲットとしないのであればmatch_parent
を使用しましょう。
padding(パディング)、margin(マージン)を使用することでViewの余白を設定することができます。
パディングでViewの内側の余白をマージンで外側の余白を調整することができます。
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#f2f2f2"
android:padding="12dp"
android:text="Padding"
android:textSize="30sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:background="#f2f2f2"
android:text="Margin"
android:textSize="30sp" />
要素 | 意味 |
---|---|
android:padding | 上下左右のパディング |
android:paddingTop | 上のパディング |
android:paddingBottom | 下のパディング |
android:paddingLeft | 左のパディング |
android:paddingRight | 右のパディング |
android:layout_margin | 上下左右のマージン |
android:layout_marginTop | 上のマージン |
android:layout_marginBottom | 上下のマージン |
android:layout_marginLeft | 左のマージン |
android:layout_marginRight | 右のマージン |
Androidには様々な画面サイズ、画面密度(解像度)の端末が存在します。
そのためpx(pixel)でサイズ指定をすると端末によって画像が小さくなったり大きくなったりしていしまいます。
Androidではこのような複数解像度の端末に対応するため以下の単位が用意されています。
dp(dip) は density-independent pixels (密度非依存のピクセル) の略です。
dipは160dpi(dots per inch) の画面を基準とされており、1dipは160dpiの画面では1ピクセルと同等と定義されています。
この関係を式にすると以下のようになり、解像度に対する1dipが何pxに相当するかがわかります。
px = dp * (dpi / 160)
320dpiの画面の場合だと1dipは2pxに自動的に換算され、画面上に反映されることになります。
よって、サイズにdpを使用することで特に意識することなく複数のが解像度端末に対応することができます。
dipとdpは両方使えますがdpの記述の方がspと統一感があるのでわかりやすいです。
spはscale-independent pixels(スケール非依存のピクセル)の略です。
指定したサイズは、解像度とユーザーが設定したフォントサイズにあわせて自動的にスケールされます。
Gravityを使用することでViewを指定した位置に配置することができます。
Gravityは重力をという意味です。Viewに重力をかけることによって、かけた方向へViewが配置されます。
Gravityにはandroid:gravity
とandroid:layout_gravity
が存在し、用途によって使い分けます。
要素 | 意味 |
---|---|
android:gravity | 内部の要素の位置を決めます |
android:layout_gravity | 自分の位置を決めます |
内部にTextView
を持ったLinearLayout
にandroid:gravity="right"
を指定すると以下のようになります。
このことより、TextView
が右に整列されるのがわかります。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"
android:gravity="right"
android:orientation="vertical" >
<TextView
android:layout_width="180dp"
android:layout_height="100dp"
android:background="@android:color/white"
android:text="Gravity Right1"
android:textSize="20sp" />
<TextView
android:layout_width="180dp"
android:layout_height="100dp"
android:background="@android:color/darker_gray"
android:text="Gravity Right2"
android:textSize="20sp" />
</LinearLayout>
次は、LinearLayout
内部のTextView
自体にandroid:gravity="right"
を指定すると以下のようになります。
このことより、TextView
内の文字が右に整列されます。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"
android:orientation="vertical" >
<TextView
android:layout_width="180dp"
android:layout_height="100dp"
android:background="@android:color/white"
android:gravity="right"
android:text="Gravity Right1"
android:textSize="20sp" />
<TextView
android:layout_width="180dp"
android:layout_height="100dp"
android:background="@android:color/darker_gray"
android:gravity="right"
android:text="Gravity Right2"
android:textSize="20sp" />
</LinearLayout>
内部にTextView
を持ったLinearLayout
にandroid:layout_gravity="right"
を指定すると以下のようになります。
LinearLayout
自体の位置が右に移動しTextView
のLinearLayout
内での位置は変わっていません。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"
android:orientation="vertical" >
<LinearLayout
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:background="#d1992f"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:text="Gravity Right1"
android:textSize="20sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/darker_gray"
android:text="Gravity Right2"
android:textSize="20sp" />
</LinearLayout>
</LinearLayout>
次に、LinearLayout
内部のTextView
自体にandroid:layout_gravity="right"
を指定すると以下のようになります。
このことより、TextView
が右に整列されます。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"
android:orientation="vertical" >
<LinearLayout
android:layout_width="200dp"
android:layout_height="wrap_content"
android:background="#d1992f"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:background="@android:color/white"
android:text="Gravity Right1"
android:textSize="20sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:background="@android:color/darker_gray"
android:text="Gravity Right2"
android:textSize="20sp" />
</LinearLayout>
</LinearLayout>
レイアウトはUIの構造を定義します。
LinearLayout、RelativeLayout、FrameLayout、GridLayout、ListView、ScrollViewなどがあり、用途によって使い分けます。
Viewを縦横に並べることができます。
android:orientation
で並べる方向を決めます。"horizontal" か "vertical"を指定します。
未設定の場合はhorizontalが適用されます。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text2" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text3" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text4" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text5" />
</LinearLayout>
android:orientation="horizontal"
を指定することによりTextView
が横に並んでいます。
(android:orientation="horizontal"
を記述していなくても同様の画面レイアウトになります)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text2" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text3" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text4" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text5" />
</LinearLayout>
android:orientation="vertical"
を指定することによりTextView
が縦に並んでいます。
LinearLayoutは個々の内部View(子View)に対してandroid:layout_weight
を割り当てることができます。
android:layout_weight
はViewを配置したときに残っているスペースを埋めることができるとても重要な機能です。
例えば、2つボタンが横並びに配置されているとします。片方のボタンにのみandroid:layout_weight="1"
を指定します。
指定していないボタンのandroid:layout_weight
は0
として扱われます。
android:layout_weight
は指定された値を元にスペースを割り当てます。この例では割り当てられる比率は1:0となります。
よって、指定されたボタンは残っているスペースを全て使うことになり目一杯横方向に伸びます。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Button1" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button2" />
</LinearLayout>
相対的にVeiwを配置することができます。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<Button
android:id="@+id/a"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="A"
android:textSize="16sp" />
<Button
android:id="@+id/b"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/a"
android:layout_toRightOf="@+id/a"
android:text="B" />
<Button
android:id="@+id/c"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/b"
android:layout_below="@+id/b"
android:text="C" />
<Button
android:id="@+id/d"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/c"
android:layout_alignTop="@+id/b"
android:layout_toRightOf="@+id/b"
android:text="D" />
</RelativeLayout>
- ボタンAを
android:layout_centerHorizontal="true"
で横方向の中心に、さらにandroid:layout_centerVertical="true"
で縦方向の中心に配置しています。またandroid:id="@+id/a"
と宣言することでボタンAの識別子を付与しています。 - ボタンBは
android:layout_toRightOf="@+id/a"
を指定することでボタンAの右に配置しており、android:layout_alignTop="@+id/a"
で上端をボタンAの上端に合わせています。 - ボタンCは
android:layout_below="@+id/b"
を指定することでボタンBの下に配置しており、android:layout_alignLeft="@+id/b"
で左端をボタンBの左端に合わせるようにしています。 - ボタンDは
android:layout_toRightOf="@+id/b"
を指定することでボタンBの右に配置しており、android:layout_alignTop="@+id/b"
で上端をボタンBの上端、android:layout_alignBottom="@+id/c"
で上端をボタンBの下端に配置するようにしています。
要素 | 意味 |
---|---|
android:layout_above | 指定したidのViewの上に配置します |
android:layout_alignBaseline | 指定したidのViewのベースラインにあわせて配置します |
android:layout_alignBottom | 指定したidのViewの下端にあわせて配置します |
android:layout_alignLeft | 指定したidのViewの左端にあわせて配置します |
android:layout_alignParentBottom | 親となるViewの下端にあわせて配置します |
android:layout_alignParentLeft | 親となるViewの左端にあわせて配置します |
android:layout_alignParentRight | 親となるViewの右端にあわせて配置します |
android:layout_alignParentTop | 親となるViewの上端にあわせて配置します |
android:layout_alignRight | 指定したidのViewの右端にあわせて配置します |
android:layout_alignTop | 指定したidのViewの上端にあわせて配置します |
android:layout_below | 指定したidのViewの下に配置します |
android:layout_centerHorizontal | 親となるViewの横方向の中央に配置します |
android:layout_centerInParent | 親となるViewの中央に配置します |
android:layout_centerVertical | 親となるViewの縦方向の中央に配置します |
android:layout_toLeftOf | 指定したidのViewの左に配置します |
android:layout_toRightOf | 指定したidのViewの右に配置します |
FrameLayoutはViewを重ねて配置するのに使用します。
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/FrameLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<!-- 赤 -->
<ImageView
android:layout_width="200dp"
android:layout_height="200dp"
android:background="#FF0000" />
<!-- 緑 -->
<ImageView
android:layout_width="190dp"
android:layout_height="190dp"
android:background="#00FF00" />
<!-- 青 -->
<ImageView
android:layout_width="180dp"
android:layout_height="180dp"
android:background="#0000FF" />
</FrameLayout>
FrameLayout
内の上から順にViewが配置されます。
上記の場合は、赤のImageView
の上に青のImageView
が配置され、その上に緑のImageView
が配置されています。
ScrollViewは画面にレイアウトが収まらない場合、収まらない分をスクロールして表示するための使用します。
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/ScrollView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="hello_world"
android:textSize="30dp" />
・・・
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="hello_world"
android:textSize="30dp" />
</LinearLayout>
</ScrollView>
ScrollView
が持つルートとなるViewは1つでなければなりません。
上記サンプルの場合、複数のTextView
をLinearLayout
でまとめ、LinearLayout
をルートとしています。
ScrollView
の直下にTextView
を複数配置するということはできません。
以下の項目に取り組んでください。
レイアウトの参考として、スクリーンショットと同じようなレイアウトになるようにします。
実習・課題の詳細は、各レイアウトファイルの中に記述されています。
- (実習) LinearLayoutPractice の 1 と 2 に取り組んでください。
- (実習) RelativeLayoutPractice の 1 と 2 に取り組んでください。
- (実習) FrameLayoutPractice の 1 と 2 に取り組んでください。
- (実習) ScrollViewPractice の 1 に取り組んでください。
- (課題) 下記の画像のようなレイアウトが作成されています。このレイアウトを元に、自由にレイアウトを編集してください。
- (課題)
layout_weight
がネストしているので、LinearLayout
をRelativeLayout
に置き換かえてネストを解消してください。
-
layout_weight
のネストは、パフォーマンスに悪影響を及ぼします。 - スクリーンショット
- (課題) 下記の画像のようなレイアウトを作成してください(課題 6 と同じプロジェクトで実行する)
- (課題) 下記の画像のようなレイアウトを作成してください。レイアウトファイル中に、指示と条件、ヒントがあります。
Portions of this page are reproduced from work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.