前人未踏の領域へ アプリ開発編

Android, iOSアプリ開発に関する調査メモ置き場。ほとんどAndroid。古い記事にはアプリ以外も含まれます。

Jetpack Compose:アイコン付きテキストを作る

試行錯誤の記録。慣れるまでが一苦労。Android Studioのレイアウトエディターとか完全に無用の長物になってしまったな。

アイコン付きテキスト

左にアイコンがあってテキストが続くようなよくあるケース

@Composable
fun TextWithIcon() {
    Row(verticalAlignment = Alignment.CenterVertically,
        modifier = Modifier.wrapContentHeight()) {
        Icon(
            vectorResource(id = R.drawable.ic_info_black_20px),
            modifier = Modifier
                .height(18.dp)
                .width(18.dp)
                .align(Alignment.CenterVertically)
        )
        Spacer(modifier = Modifier.width(16.dp))
        Text(
            text = stringResource(id = R.string.sample_text),
            fontSize = 12.sp,
            modifier = Modifier.align(Alignment.CenterVertically)
        )
    }
}

ポイント

  • 横に並べたいのでRowを使う
  • アイコンとテキストの高さを揃えたいので親のRowで verticalAlignment() を指定
  • SVG画像は vectorResource(id=) で取得
  • アイコンとテキスト間の余白は Spacer で確保

Retrofit:responseBodyがnullのsuspend関数を定義する

課題

Retrofit2でレスポンスが空のsuspend関数を定義したい場合、以下の書き方だとエラーになる。

suspend fun like( itemId:Int ) :Unit  // 単にCallを外しただけだとNG。Void, Unit?も同様
<クラス名> was null but response body type was declared as non-null

対応

Response<Unit> とすることで レスポンスbodyのnullチェックが行われなくなる。

suspend fun like( itemId:Int ) : Response<Unit> // Response<Void>も可
suspend fun postLike() :Response<Unit>

問題

Response<Unit> を使っているとレスポンスコードが200台以外でも例外にならないようだ。

参考

github.com

suspend関数を処理可能なラムダパラメータを定義する

タイトルも本文も何言ってるか分からないかもしれないけれどちょっと感動したので。

課題

ViewModel内の関数で、コルーチン内部でラムダを実行させたい。 このラムダは内部でRetrofitによるsuspend関数のAPI呼び出しを行うためsuspend関数の実行が必要である。どうすればよいか。

対応

ラムダをsuspend関数化したパラメータとして受け取るようにする。

// 共通のレスポンスを返すAPIを扱う関数
fun doQuery(text:String, query: suspend (id:Int) -> Response) {
    viewModelScope.launch {

        // 共通の前処理

        // APIを実行
        val response = query(id)
        
        // 以下、responseを使った共通処理
    }
}

呼び出し側(1)

   doQuery("ほげ") { id ->
         repository.getHogeItems(id)
   }

呼び出し側(2)

   doQuery("ふが") { id ->
         repository.getFugaItems(id)
   }

query: suspend (id:Int) -> Response) がポイント。 ラムダ定義のとこに suspend つけてあげるとそれがsuspend関数になる。 いや〜、Kotlin便利だわ。