Android Kotlin Fundamentalsで学ぶ その2
はじめに
この記事はGoogleが提供しているCodelabの中のAndroidを作りながら学ぶAndroid Kotlin Fundamentalsコースで学習した内容を自分用に残していくものです。間違っていることなどあればコメントをいただけるとありがたいです!
この記事について
その2では、Lesson2について残していきます。
このレッスンでは、LinearLayout
とConstraintLayout
を用いてレイアウトを作成する方法を学びます。また、findViewById
メソッドとdatabinding
による呼び出しの方法も説明しています。
LinearLayout using the Layout Editor
2-1LinearLayout
の2種類がある。
padding margin
- padding: ビューとコンテントとの内側のスペース
- margin: ビューの境界の外側のスペース
Add user interactivity
2-2この章では、AboutMe
アプリを作成しながら、EditText
とButton
のイベントハンドラを作成していきます。
ビューについて
-
EditText
: ユーザに期待する入力をしてもらうために、-
hint
: 何を入力したらいいか未入力のEditTextに表示 -
inputType
: 入力する形式を指定する。password
を指定すると入力している文字列がマスキングされたり、phone
を指定すると数字キーパッドが表示され、数字のみ入力できるようになる。
-
などの属性を追加するべき。
Attribute
-
layout_gravity
: 親のビューを中心に位置を指定
レイアウトファイルについて
レイアウトを編集する上で、ある程度決まっている部分(配色とか、文字サイズなど)はapp/src/main/res/values/
内にxmlファイルで指定する。大まかに以下のファイルがある。
-
colors.xml
: 色の指定に使用するカラーコードなどをまとめる -
strings.xml
: ビューに表示する文字列をまとめる -
dimens.xml
: フォントサイズ(sp)やデザインする際の大きさを(dp, px)などをまとめる -
styles.xml
: ビューの外観や書式を指定するプロパティをまとめる
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#00FF00"
android:typeface="monospace"
android:text="@string/hello" />
を下のスタイルにまとめることで、
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="CodeFont" parent="@android:style/TextAppearance.Medium">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textColor">#00FF00</item>
<item name="android:typeface">monospace</item>
</style>
</resources>
このようにすっきり書ける。
<TextView
style="@style/CodeFont"
android:text="@string/hello" />
クリックリスナー
ボタンイベントの追加について
findViewById<Button>(R.id.button).setOnClickListener {
action(it)
}
このようにfindViewById
でビュー(今回はボタン)と対応づけ、setOnClickListener
で処理を行う。この時、対応づけられたビューはsetOnClickListener
内ではit
として定義される。
ConstraintLayout using the Layout Editor
2-3ConstraintLayoutについて
- ビューを柔軟な方法で配置、またはサイズ変更することができるViewGroup
-
LinearLayout
のようにビューの配置をネストすることなしに、フラットな階層でxmlファイルをい記述できる - レイアウトエディタ(言い方が正しいかわからないけど)を使ってドラッグアンドドロップで配置できる
- 簡単なレイアウトはテキストを編集せずレイアウトを作ることができる
-
constraint
=制約
と訳される - 親レイアウトや他のビューとの水平垂直の位置関係・制約を設けることで配置していく
こんな感じ
上のレイアウトの場合、少し省略しますが、
<Button
android:id="@+id/button1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/button2" />
<Button
android:id="@+id/button2"
app:layout_constraintTop_toTopOf="@+id/button1"
app:layout_constraintStart_toEndOf="@+id/button1"
app:layout_constraintEnd_toEndOf="parent"/>
こんな感じでレイアウトされる。
制約としては、
- ボタン1
- Top: 親Top
- Start: 親Start
- End: ボタン2Start
- ボタン2
- Top: ボタン1Top
- Start: ボタン1End
- End: 親End
こんな感じ。
viewの制約について
layout_constraintA_toBOf
A, Bに入る制約は以下の通り
- 上部: Top
- 下部: Bottom
- 右部: End(Right)
- 左部: Start(Left)
で、Aは自身の制約, Bは相手の制約になる
だから上の例ではボタン1のStart(左側)は親レイアウトの左側との制約があり、ボタン1のEnd(右側)はボタン2の左側と制約がある。
(この制約あるなしって言い方が正しいのかどうか...)
実際に作ってみた
完成形
LinearLayoutと比較した時、ネストの少なさがとても魅力的だと感じた。
今回のレイアウトだと少し見にくいですが、この3つのレイアウトをネストする必要があるため、コードに記述しても見にくくなってしまう。
Data binding basics
2-4通常、ビューの参照にはfindViewById()
関数を使用する。ただ、ビューの数が多くなったり、レイアウトのネスト、階層が深く、大きくなってしまうと、ビューの検索に時間がかかり、パフォーマンスが落ちてしまう。
そこで、Binding
と呼ばれる各ビューの参照を含むオブジェクトを使うことで解決する。これをデータバインディングという。
こんな感じで記述する。(参照: Data binding basics)
Data Binding のメリット
-
findViewById()
よりもコードが短く、読みやすく、保守も簡単 - データとビューの分離
- アプリ起動時に1度全てのビューを取得
- ビューの型安全性を得られる
手順
- データバインディングを有効にする
android{
(省略)
buildFeatures {
dataBinding true
}
(省略)
}
- レイアウトファイルの変更
<layout> <-最も外側のタグに指定
<LinearLayout ... >
...
</LinearLayout>
</layout>
- バインディングオブジェクトの作成
import com.example.android.aboutme.databinding.ActivityMainBinding <- import部分に追加
import androidx.databinding.DataBindingUtil <- import部分に追加
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?){
binding = DataBindingUtil.setContentView(this、R.layout.activity_main)
(省略)
}
これでデータバインディングの設定は終了
binding.{ビューのid}
で参照可能
データクラス
データバインディングを使うことで、データクラスを直接利用できる。
手順
- データクラスの作成
package jp.sample.aboutme
data class SampleData(var name: String = "", var age: int = 0)
- レイアウトにデータクイラスを追加
xmlファイルの<layout>
の下に以下を追記
<layout>
<data>
<variable
name='sampleDataClass(データクラスの変数名)'
type='完全修飾名(パッケージ名+変数名)'
/>
</data>
(省略)
<TextView
~
android:text="@={sampleDataClass.name}"
</layout>
- データを作成する
private val sampleData: SampleData = SampleData("Aleks Haecky")
override fun onCreate(savedInstanceState: Bundle?) {
~
binding.sampleData = sampleData
~
}
まとめ
今回はLinearLayout, ConstraintLayoutのレイアウトの仕組み、書き方を学びました。ConstraintLayoutがとてもシンプルかつわかりやすく記述できることがとても有用であり、使うべきレイアウトだと感じました。また、ConstraintLayoutの制約の付け方はもっと自分でやってみてサラサラっと書くことができるようになればいいと思ってます。
Discussion