MVVM基礎
Coroutineの記事だがMVVMの基礎から書いてあり、関連記事のマルチモジュール化も含めて参考になる
tech.gunosy.io
これから自社に導入していくときの参考に
どっかで時間作ってJetpack Compose Pathwaysやりたい
tech.gunosy.io
そのほかの記事含めgunosyのテックブログかなり参考になりそう。
DroidKaigi2023見逃してたセッション
Androidアプリの良いユニットテストを考える
www.youtube.com
基本方針は以下で良さそう
- Androidフレームワークに依存したコードと依存していないアプリのロジックを切り離してPure Local Test(Robolectricでない単純なテスト)で実行できるようにする
- Androidフレームワークに依存したコードはRobolectricで実行する
- 上記で不足している箇所をInstrumentation Testで実行する
mockito等のスタブについて
使いすぎるとテストコードと実装が密接に結びついてしまいテストコードのメンテナンスにコストがかかりやすくなるので必要のない箇所では使わない方がいい。
スタブを使うべき箇所として以下があげられていた
- 現在時刻や乱数に依存する箇所
- APIや外部サービス等アプリの外部から入力を受け取る箇所
- BuildConfigなどappモジュールに実態があるものを他モジュールでも参照している箇所
- 発生させるのが難しいエラーをエミュレートしたいとき
- 依存オブジェクトからの非同期処理に対して遅延している状態をエミュレートしたいとき
スパイを使うべき箇所
- APIや外部サービスなどアプリの外部への出力をする箇所
- 依存オブジェクトのメソッドを呼び出す順序や呼び出す回数が重要な箇所
参考資料として挙げられてたテストの書き方について
GitHub - DeNA/android-modern-architecture-test-handson
テスト周りは公式ドキュメントも含めて色々覚える必要がある
DroidKaigi2023 Day2オンライン参加のメモ
リッチUIについて色々な事例紹介
speakerdeck.com
文字列や画像のグラデーションや背景追加や矩形追加等
かなりのパターンのアニメーションについても紹介されている
音量制御についてのセッション
docs.google.com
音量制御はあまり触れてこなかったので参考になった
音量設定は端末差異があるので数値で指定すると意図しないものになる可能性がある
SoundPool, MediaPlayer, AudioTrackを使い分ける
パフォーマンス監視ツールとJetpackComposeの導入
speakerdeck.com
パフォーマンス指標を図ることでJetpackComposeの導入のメリットを明確にすることにより採択されるようにしていった
各監視ツールの特徴がまとめられている
Jetpack ComposeでAndroid/iOSアプリを作る
AndroidとiOS向けアプリを両方作る
UIはComposeで作ってビジネスロジック部分はKolin Multiplatformで作る話
Compose for iOSはα版なのでまだまだ実用には遠そう
Jetpack ComposeのSide-Effectを使いこなす
LaunchedEffect
LaunchedEffect(key)の形なのでkeyが変わったら動く(初回は必ず実行される)
内部はCoroutineで動いてるらしい
keyにUnitとか固定値を入れると最初の1回だけ動くようにできる
keyを複数指定も可能で指定したどれか1つが変わったら動く
LaunchedEffectのCoroutines
キャンセルするタイミングは
・keyが変わってLaunchedEffectが再起動するとき
・CompositionからLeaveするとき
rememberCoroutineScope
val scope = rememberCoroutineScope()
ボタンとかのイベント処理で使いそう
キャンセルのタイミングはCompositionからLeaveするとき
DisposableEffect
最後に何か処理をしたい場合によく使う
これはLaunchedEffectと違ってCoroutineでは起動してない
例ではライフサイクルの監視処理を起動させて最後に破棄する例だった
初回起動時はonDisposeが実行されず、次回起動時に前回の値でonDispose起動→それ以外の処理が今回の値で起動する
rememberUpdatedState
ComposeのStateを返す
内部としてはrecompositionのたびにvalueを書き換えてる
どういうときに必要か
- Composeの外で変化する状態を参照している
- LauchedEffect, DisposableEffectのkeyではない状態を参照
- 時間が経過して使用される状態への参照
- コールバック関数
SideEffect
Compositionが成功したときに実行される
Composable内でエラーが起きた場合には実行されないので正常時だけ動くような制御ができる
ログの抑止にも使えるかも
derivedStateOf
val listState = rememberLazyListState() // スクロールの度に状態が変わる
LazyColumn(state = listState) { /* */ }
val showButton = listState.firstVisibleItemIndex > 0 // スクロールの度にrecompositionされてしまう
if (showButton) {
Button() {
Text("ScrollTop")
}
}本来はshowButtonが変わった時だけ動かしたい
val showButton by remember {
derivedStateOf {
listState.firstVisibleItemIndex > 0
}
}こうするとshowButtonが変わった時だけrecompositionされる
LazyList系が一番使われそう
produceState
Composeの外の処理をComposeに変換してくれる
snapshotState
ComposeのStateをComposeの外でFLowとして監視したい
ログ出力にTimber使ってるので調べてみる
DroidKaigi2023 Day1オンライン参加のメモ
オンラインで参加して気になったセッションのメモ
よくあるUIのサンプル
github.com
結構使えそうな事例があるので参考になる。
1. ローディング
2. ボトムナビゲーション
3. ボトムシート
4. アコーディオン
5. カルーセル
6. クレジットカード番号入力
7. 固定ヘッダー
8. 特定位置へのスクロール
9. もっと見る
NestedScrollについて
scrollStateを渡すことでスクロール可能なコンポーネントにできる。
JetpackComposeとAndroidViewをつないで動かす事例とかも紹介されてた。
val scrollState = rememberScrollState()
Column(modifier = Modifier.verticalScroll(scrollState)) { ... }
AndroidStudioの環境いろいろ
Firebase TestLab with Gradle Managed Devices
テスト自動化 使えそうなので調べる
Gradle Build Script
build.gradle→build.gradle.ktsでKotinになる。
Google的には移行推奨らしい。
App Quality Insightsを使った品質検査
Firebase Crashlyticsレポートを確認できる
Composeのトレース
Compose UI 1.3.0-beta以上
Compose Compilier 1.3.0以上
何が契機でrecomposeされたか追えるようになる
JetpackComposeで上下左右の位置関係を反転できるレイアウトを作る
qiita.com
これの「子を右から左に配置したい」のところを参考にして上下も変更可能にカスタムした。
@Composable
fun InversionLayoutExample(
layoutDirection: LayoutDirection = LayoutDirection.Ltr,
idStart: Boolean = true) {
Column(modifier = Modifier.width(200.dp)) {
ProvideLayoutDirection(layoutDirection = layoutDirection) {
InversionLayout(idStart)
}
}
}
@Composable
private fun ProvideLayoutDirection(
layoutDirection: LayoutDirection,
content: @Composable () -> Unit,
) {
CompositionLocalProvider(
LocalLayoutDirection provides layoutDirection,
content = content,
)
}
@Composable
private fun InversionLayout(isStart: Boolean = true) {
Row(
modifier = Modifier
.padding(16.dp)
.width(200.dp),
horizontalArrangement = Arrangement.SpaceBetween,
) {
Box(
modifier = Modifier
.width(100.dp)
.height(200.dp)
.background(Color.Red),
contentAlignment = if (isStart) {
Alignment.TopStart
} else {
Alignment.BottomStart
}
) {
Text(
text = "AAA",
textAlign = TextAlign.End
)
}
Box(
modifier = Modifier
.width(100.dp)
.height(200.dp)
.background(Color.Blue)
)
}
}パラメータのパターンによる違いは以下の通り
InversionLayoutExample(LayoutDirection.Ltr, true)

InversionLayoutExample(LayoutDirection.Ltr, false)

InversionLayoutExample(LayoutDirection.Rtl, true)

InversionLayoutExample(LayoutDirection.Rtl, false)

中心点から対象に配置したいとかそういうときに使えるかも
9/7の学習内容
Kotlin Coroutines Flowについて
qiita.com
これまでstreamを扱っていた箇所をこれで実装できるかも
ViewModelとRetrofitでの通信実装例
satoshun.github.io
かなり近い形で使えそう
エラーハンドリングこれまでtry-catchでやってたけどrunCatchingの方が見た目もスッキリ感ある
XML→JetpackComposeの導入事例
今日の学習内容
- パーミッション取得
Jetpack ComposeでPermissionを取得したい - 縁側プログラミング
- LazyXXXのかくつき
こっちはまさにLazyVerticalGrid使ってて気になってたとこだった
LazyColumnのスクロールがカクカクするときの確認ポイント(Stableアノテーション) - 縁側プログラミング
- Jetpack Compose内でのコルーチン
ボタンのonClickで時間かかる処理をしたいときはrememberCoroutineScope()を使う
コンポーザブルでコルーチンを使いたい場合は、LaunchedEffectを使う
コルーチンのキャンセルとかの例もあり参考になる
Jetpack ComposeのonClickでコルーチンを使いたい - 縁側プログラミング
- マテリアルアイコンの使い方
Icons.Default.XXXで使える
全てのアイコンを使えるようにするにはmaterial-icons-extendedをbuild.gradleに追加する必要あり
Jetpack Composeでマテリアルアイコンを表示したい - 縁側プログラミング
- Navitionで遷移を実装している場合のonPause, onResume処理
Navigationを使ってActivityやFragment内の遷移を実装していて
onPause, onResumeのタイミングで処理したい場合、Lifecycleイベントを使って実現する
Jetpack ComposeでonResumeやonPauseの処理を書きたい - 縁側プログラミング