Kotlinメモ
方針
アプリを作成しながら、最近のAndroidアプリの主流?の設計を追っていく。
下記のような点が主になる予定
- MVVMっぽい実装の方法
- Jetpack Composeを使用したUIの作成
Jetpack Compose所感
- いわゆる宣言的UIみたいな感じで、xmlではなくkotlinファイル上でUIを作成するみたいなイメージ。
- Flutterに近い感じがする。
View Modelについて
UIで使用する値を保持・管理するもの。
これまで、
- onSaveInstanceState
- onRestoreInstanceState
などを使用して、アクティビティが破棄されたときにそなえて、手動で値を管理していたのを自動でやってくれるようになったイメージ。
マニュアル→オートマみたいな感じで楽にはなりそう😊
使いかたイメージ
by viewModels()で初期化ができるらしい。
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
private val sampleViewModel: SampleViewModel by viewModels()
by viewModels()を使うメリットは次のような感じ。
- ライフサイクルに依存するインスタンス管理をうまいことやってくれる
- 依存性注入(DI)ライブラリと組み合わせが楽
参考サイト
依存性注入(DI)についての所感
「依存先の生成(コンストラクタ)を意識させない」というイメージがしっくりきた。
つまり、「使い方=インターフェースで定義できるメソッド」など にだけ依存して、「作り方」には関与しないのでよしなにしてくれってことかな😑
メリットは依存先の変化に強くなること。
例えば、使用するクラスのコンストラクタの引数変更とかを気にしなくていいよは、ありそう
Kotlinのstatic
そんなものはない。
- クラスに所属しない関数を定義できるので、staticメソッドは不要
- companion objectで代用可能
Companion Object
クラスに関連付けられたオブジェクト。
「オブジェクト」はkotlinではシングルトン(単一のインスタンス)を示すらしい。
クラスというよりはJavaScriptのオブジェクトに近い気がする。
class Example {
companion object {
// static 変数的なやつ
val name = "test"
// static初期化子的なやつ
init {
// このコードはクラスがロードされるときに実行される
println("クラスがロードされました")
}
// staticメソッド的なやつ
fun staticMethod() {
println("静的メソッドが呼ばれました")
}
}
}
// Exampleクラスの使用例
fun main() {
// companion objectのプロパティにアクセス
println(Example.name) // 出力: test
// companion objectのメソッドを呼び出す
Example.staticMethod() // 出力: 静的メソッドが呼ばれました
}
参考サイト
Kotlinの型キャスト
as [class名] でキャスト可能。
より英文に近いキャストかな?
プログラミングが英文の順序 = 自然言語によっていることが多い気がする。
val notificationManager: NotificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
when式
ほぼswitch-case文だが、式として使えるという仕様がある(!!?)
式として使う場合は、返り値が必ず存在する必要があるので、全てにマッチする「else」を最後にいれる必要がある。
しかし、次のような場合はelseなしでOK
- enumやsealed classでインスタンスやクラスが有限個で列挙が可能な場合
- 文として使用する場合。(switch-case文みたいな)
参考サイト
switchも式として使えるようになっていたらしい。
普通に追えてなかっただけだわ😣
sealed class
継承するクラスが制限(sealed)されたクラス。
似た機能にenumがあるが、
- enum: インスタンスが制限
- sealed class: クラスが制限
という違いがあると理解した。
似てはいるが、クラス自体は違うので、同じsealed classを継承していても、異なるメソッドやメンバーをもつことができる。
継承について
基本的にはpermitsで継承できるクラスを宣言する。
sealed class Shape permits Circle, Square, Rectangle {
}
しかし、同一ファイルである場合に限り、permitsを省略できる。
sealed class Screen(val route: String, val title: String) {
object Home : Screen("home", "ホーム")
object Settings : Screen("settings", "設定")
}
objectについて
- 単一インスタンス(シングルトン)を簡単に定義できる
- Javaのstaticメンバーで定義していた定数や、staticメソッドで定義していたユーティリティ関数の代用が簡単にできそう。