
Android Developers > スタートガイド > Kotlin と Android をゼロから学ぶ > Unit2 – レイアウト >Unit2-1 第4回 の内容をまとめたものです(翻訳ではありません)
Unit2 – 1 第4回 のポイント

- AndroidアプリのUI画面を、Android Studio の Layout Editor をつかう代わりにXMLエディタを使って書いてみます
- XMLはいろいろな用途に使われています。Android Studio でもUI画面の記述だけでなく、strings.xml のようにUIで使う文字列を保存しておくのにも使われています
- UI画面に、編集可能なテキストフィールド、ラジオボタン、スイッチなどを作成してみます
- Androidにある次のUI部品(View)を使ってみることにします
EditText
– 編集可能なテキスト入力フィールドTextView
– 結果をテキスト表示するRadioButton
– ひとつひとつのラジオボタンRadioGroup
– ラジオボタンをまとめる部品Switch
– on/off できるスイッチ
- 新規にプロジェクトを作成しておきます
- アプリの名前は Tip Time
- テンプレートは Empty Activity
- 言語は Kotlin
- Minimum SDK は API 19 : Android 4.4 (KitKat)
UI部品(View)と階層
レイアウトには階層があるんですね
- AndroidアプリのUI部品(View,コンポーネント,ウィジェット)には階層があって、それが画面に表示されている。レイアウト自体もUI部品(View)のひとつと考えます
- XMLをつかって画面に表示するUI部品(View)の階層(containment hierarchy)を記述します。
- たとえば、ConstraintLayout(親のView)は
Buttons
,TextViews
,ImageViews
などの View を子として持ちます - ConstraintLayout は ViewGroup(View の一種)のクラスです。子になる View 部品を取りまとめます
- たとえば、ConstraintLayout(親のView)は
- UI部品(View)の階層(containment hierarchy)は親が子を完全に取り込んでいく構造です。前回出てきたクラスの階層(class hierarchy)は子が親の機能を引き継いで飲み込んでいく感じなので同じ親子階層でも考え方が違います
- UI部品(View)はXMLファイル中でタグで囲まれたXML要素であらわされます。書き方はHTMLと似ています。Layout Editor でUI部品(View)を配置すると、こんな感じのXMLファイルが作られます(簡略に書きました。実際はもっといろいろ書き込まれます)
<ConstraintLayout>
<TextView
text="Hello World!">
</TextView>
</ConstraintLayout>
XMLでのViewの表し方
レイアウトはこんな風にXMLで表されます
<タグ タグの属性・・・> 子になるUI部品・・・ </タグ>
- 通常は構造が見やすいようにインデントされてこんな風になっている
<タグ タグの属性1 タグの属性2 ・・・ > 子になるUI部品1 子になるUI部品2 ・・・ </タグ>
子になるUI部品がない場合・・・空要素タグ(empty-element tag)
コンパクトにも書けるんですね
<TextView 属性いろいろ ></TextView>
<TextView
android:text="Hello World!"
></TextView>
<TextView 属性いろいろ />
・・・こんな風に書いてもよい
<TextView
android:text="Hello World!"
/>
activity_main.xml を表示してみる
Android Studio が最初に生成した XML ファイルを見てみますね
- Layout Editor で activity_main.xml を開いて、画面右上のほうにある「Code」をクリックするとXMLでの表示をみることができます
- 「Split」をクリックすると Design EditorとXMLが両方表示されます。これでもかまいません
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
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:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
- 1行目はこれがXMLファイルであることを示している宣言。ただしすべてのXMLファイルに書いてあるとは限りません
- インデントされていて階層が分かりやすくなっています
- Android Studio 上では見やすいように色分けもされています
- ConstraintLayout は TextView と違って、実際には
androidx.constraintlayout.widget.ConstraintLayout
と記述されています。これは ConstraintLayout が Android Jetpack という追加機能ライブラリで提供されているためです。Jetpack で提供されているものはandroidx
で始まります - タグの属性(attribute)
- 属性はネームスペースと呼ばれるグループに分けられています
- xmlns: は XML namespace の意味。xmlns: に続けて属性のネームスペースを定義しています
- たとえばandroid: は Android システムで定義された属性であることを示しています
- レイアウト用のXMLに記述する属性は、かならずこのネームスペースから指定します
むずかしそうだけど、表示が整っていて見やすいですね!
- Android Studio にはXMLを見やすいように自動で整形してくれる機能があります。XMLの規約に従うようにフォーマットしなおす方法もあります
- XMLファイルにコメントをしたいときは
<!--
と-->
で囲みます - Android Studio ではXMLに問題があると赤で表示されます。赤く表示されているところにマウスカーソルを合わせて何が問題なのか確認しておきます。原因がはっきりしないときはインデントや色の指定のあたりに問題がないかチェックしてみます
XMLで画面レイアウトを作ってみる
直接 XML ファイルを書き換えてみますね
- Design View で、画面右上の「Split」を選んで XML と Desing Editor を両方表示しておきます
- XML あるいは Design Editor に表示されている部品をクリックすると、それぞれの該当する箇所がどこなのかわかるようになっています
- XMLファイルを書き換えてみる
TextView
を削除してみる・・・XMLで<TextView ~ />
までを削除する。Desing Editor 上からも消えることを確認します- ConstraintLayout の枠から
16dp
だけ、かならず部品を離すようにする・・・XMLのConstraintLayout の属性の中にandroid:padding="16dp"
を追加する
<androidx.constraintlayout.widget.ConstraintLayout
...
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
tools:context=".MainActivity">
EditText を追加してみる
UI部品の追加って、XMLに直接書いてもできるんですね
XMLファイルにUI部品を追加する手順
- Android Developers の APIレファレンスで追加したいUI部品(View)のドキュメントを探します
- ドキュメント中のサンプルXMLを、アプリのXMLファイルにコピペします
- 追加した部品の constraint(制約)をXMLで書き加えます
うん、EditText だったら ドキュメントのこの辺 を見てこんな感じにコピペするの
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<EditText
android:id="@+id/plain_text_input"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:inputType="text"/>
</androidx.constraintlayout.widget.ConstraintLayout>
UI部品(View)に constraint(制約)を設定する
EditText が赤く表示されちゃってます
うん、constraint(制約)が設定されないとそうなるの。以下の行を追加しますね
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
- Androidを日本語や英語で使う場合、レイアウトファイルの Start は Left の意味、End は Right の意味です
layout_constraint<Source>_to<Target>Of
は、<Source>
(constraintを設定する部品の場所)から<Target>
(指定した部品の場所) に constraint(制約)を設定するという意味です- まとめると、こんな感じになります
<EditText
android:id="@+id/plain_text_input"
android:layout_height="wrap_content"
android:layout_width="match_parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:inputType="text"/>
リソースID を書き換える
EditText の リソースID を変えてみます
- リソースIDは @+id/plain_text_input となっているので、これを @+id/cost_of_service と書き換えます
- リソースIDは @+id ではじめます
- リソースID名は snake_case で記述します
- リソースIDをKotlinコードから参照したいときは R.<type>.<name> と記述します
- たとえば
View
(UI部品)のIDの<type>
はid
なのでR.id.button
で参照できる
大きさを調整する
表示する大きさも変えてみます
- wrap_content は、部品に表示する内容の大きさに合うように大きさが変化する
- match_parent は ConstraintLayout の子Viewには使えません。とりあえず 160dp に変更しておきます
入力についての属性を設定する
入力についての細かい設定もできるの
- inputType は text と設定されていますが、数値(小数)だけ受け付けるように変更してみます
- text のところを消す(ダブルコーテーションは残しておく)
- 消したあとに n と入れると、リストが出てくるのでその中から numberDecimal を選択する(小数だけが入力できるようになる)
- Android Studio にはその部分で可能な選択肢を提案してきたり、最低限必要なものを自動で書き込んでくれたりする機能があります。これらをうまく利用します(タイピングや勘違いのミスも減る)
- text や numberDecimal 以外の入力方法についてはドキュメント(ここ)を読んで確認しましょう
- 入力欄にユーザーへのメッセージ(入力例など)を表示するには次のようにします
android:hint="Cost of Service"
メッセージ表示用の TextView を追加する
TextView を追加してみますね
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<EditText
android:id="@+id/cost_of_service"
android:hint="Cost of Service"
android:layout_height="wrap_content"
android:layout_width="160dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:inputType="numberDecimal"/>
<TextView
android:id="@+id/service_question"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="How was the service?"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cost_of_service"/>
</androidx.constraintlayout.widget.ConstraintLayout>
ラジオボタンを作ってみる
ラジオボタンも作ってみますね
- Android でのラジオボタンの作り方が知りたいときは “radio button android” でググる(Googleで検索する)ようにします。他の機能も同じようにググって探し当てるのがおすすめです
- ラジオボタンは、まず RadioGroup を作ってその中に RadioButton を入れていきます。RadioGroup が親View で RadioButtonが子Viewになります
こんな感じですね
<RadioGroup
android:id="@+id/tip_options"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/service_question"
app:layout_constraintStart_toStartOf="parent"
android:orientation="vertical">
<RadioButton
android:id="@+id/option_twenty_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Amazing (20%)" />
<RadioButton
android:id="@+id/option_eighteen_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Good (18%)" />
<RadioButton
android:id="@+id/option_fifteen_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="OK (15%)" />
</RadioGroup>
デフォルトで選択されるボタンを指定します
最初に選択されているボタンは、RadioGroup の属性に android:checkedButton
で指定するの
<RadioGroup
android:id="@+id/tip_options"
android:checkedButton="@id/option_twenty_percent"
...
全体はこんなかんじかな?
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<EditText
android:id="@+id/cost_of_service"
android:hint="Cost of Service"
android:layout_height="wrap_content"
android:layout_width="160dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:inputType="numberDecimal"/>
<TextView
android:id="@+id/service_question"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="How was the service?"
app:layout_constraintTop_toBottomOf="@id/cost_of_service"
app:layout_constraintStart_toStartOf="parent" />
<RadioGroup
android:id="@+id/tip_options"
android:checkedButton="@id/option_twenty_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/service_question"
app:layout_constraintStart_toStartOf="parent"
android:orientation="vertical">
<RadioButton
android:id="@+id/option_twenty_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Amazing (20%)" />
<RadioButton
android:id="@+id/option_eighteen_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Good (18%)" />
<RadioButton
android:id="@+id/option_fifteen_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="OK (15%)" />
</RadioGroup>
</androidx.constraintlayout.widget.ConstraintLayout>
Switch, Button, TextView の追加
Switch(UI部品)を追加します
Switch の XML ですね
<Switch
android:id="@+id/round_up_switch"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:checked="true"
android:text="Round up tip?"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tip_options" />
- Switch をレイアウトの幅いっぱいにしたいとき、ConstraintLayout では幅の constraint(制約)を 0dp とします
- ConstraintLayout に含める UI部品(View)では match_parent は使えません。代わりに 0dp を使うので注意しましょう
Button(UI部品)を追加します
うん、これは Button
<Button
android:id="@+id/calculate_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Calculate"
app:layout_constraintTop_toBottomOf="@id/round_up_switch"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
計算結果を表示するためのTextViewを追加します
TextView はすこし見慣れてきたかも
<TextView
android:id="@+id/tip_result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/calculate_button"
android:text="Tip Amount" />
strings.xml の利用
UI画面(レイアウト)で使う文字列には、できるだけ strings.xml を使ってくださいね
- 以前のチュートリアルでも出てきたんですけれども、XML中に文字列をハードコード(コードの中に直接書き込む)すると警告の黄!が表示されます。activity_main.xml を開いてこれらをクリック、strings.xml を利用する形に修正します
- 修正した strings.xml を確認しておきます。Project から開くことができます( app > res > values > strings.xml )
- strings.xml を開くと次のような感じになっています(実際に表示される内容は書き込んだ情報によって異なります)
<resources>
<string name="app_name">Tip Time</string>
<string name="cost_of_service">Cost of Service</string>
<string name="how_was_the_service">How was the service?</string>
<string name="amazing_service">Amazing (20%)</string>
<string name="good_service">Good (18%)</string>
<string name="ok_service">Okay (15%)</string>
<string name="round_up_tip">Round up tip?</string>
<string name="calculate">Calculate</string>
<string name="tip_amount">Tip Amount</string>
</resources>
XMLファイルの整形
Android Studio を使うと、自動で見やすくしてくれるんですね
- Android Studio には XMLファイルの自動整形機能があります。
- XMLの書き方として推奨されているような、見やすくて一貫性のある書き方に直すことができます
- 次のようにすると整形できます
- XMLファイル(たとえばactivity_main.xml)を開いて Ctrl+a ですべてを選択します
- Code > Reformat Code を選択します
ということで、今回作成した activity_main.xml はこんな感じですね
うーん、やっぱりXMLを手で書くのはたいへん。Layout Editor ってすごいかも…
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
tools:context=".MainActivity">
<EditText
android:id="@+id/cost_of_service"
android:layout_width="160dp"
android:layout_height="wrap_content"
android:hint="@string/cost_of_service"
android:inputType="numberDecimal"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/service_question"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/how_was_the_service"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cost_of_service" />
<RadioGroup
android:id="@+id/tip_options"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checkedButton="@id/option_twenty_percent"
android:orientation="vertical"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/service_question">
<RadioButton
android:id="@+id/option_twenty_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/amazing_service" />
<RadioButton
android:id="@+id/option_eighteen_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/good_service" />
<RadioButton
android:id="@+id/option_fifteen_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ok_service" />
</RadioGroup>
<Switch
android:id="@+id/round_up_switch"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/round_up_tip"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tip_options" />
<Button
android:id="@+id/calculate_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/calculate"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/round_up_switch" />
<TextView
android:id="@+id/tip_result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tip_amount"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/calculate_button" />
</androidx.constraintlayout.widget.ConstraintLayout>
strings.xml ファイルは次の通りです
<resources>
<string name="app_name">Tip Time</string>
<string name="cost_of_service">Cost of Service</string>
<string name="how_was_the_service">How was the service?</string>
<string name="amazing_service">Amazing (20%)</string>
<string name="good_service">Good (18%)</string>
<string name="ok_service">Okay (15%)</string>
<string name="round_up_tip">Round up tip?</string>
<string name="calculate">Calculate</string>
<string name="tip_amount">Tip Amount</string>
</resources>
Unit2 – 1 第4回のまとめ
Layout Editor を使うときに XML をイメージしてみるといいかも
- XML (Extensible Markup Language) ・・・タグ(tag), 要素(element), 属性(attribute)を使って構造的に記述されたテキストです
- Androidアプリのレイアウトは XML で記述されています
EditText
(UI部品のView)は、アプリのユーザがテキストを編集・入力するのに使います- EditText には hint の機能があります
android:inputType
属性を使うと、ユーザが入力できるテキストの種類を制限できます
- ラジオボタンを作るには
RadioButtons
とRadioGroup
を使いますRadioGroup
では、ボタンを並べる方向(縦あるいは横)、デフォルトで選択されているボタンを決めておくことができます
- 2つの状態(on/off)を選択できるようにするには
Switch
(UI部品のView)を使いますSwitch
には属性でラベルが付けられます(TextView
を別途追加する必要がありません)
ConstraintLayout
に置かれたUI部品(View)には、必ずそれぞれに縦方向と横方向の constraint(制約)を設定します- constraint(制約)の Start と End は、日本語や英語では Left と Right という意味です(アラビア語のような右から左に書く言語では逆になります)
- constraint(制約)は、次のような書式で設定します・・・
layout_constraint<Source>_to<Target>Of
- UI部品(View)の横幅を ConstraintLayout の枠いっぱいに表示したいときは、左右の constraint(制約)を match_parent ではなく、0dp に設定します(ConstraintLayout で match_parent は使えません)
長かったですね、お疲れさま!