2021/06/15
Jetpack Composeで一覧表示に利用するCard Viewを実装してみる
以下のような構成のCard ViewをJetpack Composeで作成しました。
- バナー画像
- カード全体にfitするように表示する
- UIのメインスレッドとは非同期で読み込みを行うようにする ← Coilの出番
- タイトル
- タグ(Chips)
- 複数あったときに複数行に渡って折り返して(wrapped)表示されるようにする ← FlowLayoutの出番
- サブタイトル
準備
以下のライブラリをインストールしておきます。
dependencies {
final def accompanist_version = '0.11.0'
implementation "com.google.accompanist:accompanist-coil:$accompanist_version"
implementation "com.google.accompanist:accompanist-flowlayout:$accompanist_version"
}
Cardに表示するModelの定義
@Immutable
data class Activity(
val id: Long,
val slug: String,
val title: String,
val subtitle: String?,
val bannerImageUrl: String?,
val tags: Array<String>,
)
Card Viewの実装
ポイント
rememberCoilPainter
を使って非同期でインターネットから画像をダウンロードして表示されるようにするFlowRow
を使って、タグが複数あり、1行で表示されない場合は折り返されるようにする
@Composable
fun ActivityCard(
activity: Activity,
onClick: () -> Unit,
) {
val elevation = 8.dp
Card(
shape = MaterialTheme.shapes.medium,
modifier = Modifier.fillMaxWidth(),
backgroundColor = MyTheme.colors.getUiBackgroundForElevation(elevation = elevation),
elevation = elevation
) {
Column(
modifier = Modifier
.clickable(onClick = onClick)
.fillMaxWidth()
) {
activity.bannerImageUrl?.let { bannerImageUrl ->
Image(
painter = rememberCoilPainter(bannerImageUrl),
contentDescription = null,
modifier = Modifier
.fillMaxWidth()
.height(225.dp),
contentScale = ContentScale.Crop
)
}
Spacer(modifier = Modifier.height(8.dp))
Text(
text = activity.title,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
style = MaterialTheme.typography.subtitle2,
color = MyTheme.colors.content,
modifier = Modifier.padding(horizontal = 16.dp)
)
if (activity.tags.isNotEmpty()) {
Spacer(modifier = Modifier.height(4.dp))
FlowRow(
mainAxisSpacing = 4.dp,
crossAxisSpacing = 4.dp,
modifier = Modifier.padding(horizontal = 16.dp),
) {
activity.tags.forEach { tag ->
Chip(text = tag)
}
}
}
activity.subtitle?.let { subtitle ->
Spacer(modifier = Modifier.height(4.dp))
Text(
text = subtitle,
style = MaterialTheme.typography.caption,
color = MyTheme.colors.contentSecondary,
modifier = Modifier.padding(horizontal = 16.dp)
)
}
Spacer(modifier = Modifier.height(16.dp))
}
}
}
プレビューで確認
@Preview("activity card default")
@Preview("activity card dark theme", uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
fun ActivityCardPreview() {
MyTheme {
val activity = Activity(
id = 1L,
slug = "copy-text-to-clipboard-with-vuejs",
title = "Vue.jsでクリップボードにコピーするコントロールを作る",
subtitle = "Vue.jsのボタンクリックでテキストをクリップボードにコピーしてみました",
bannerImageUrl = "https://api.kumano-te.com/api/v1/activities/32/banner?rev=100",
tags = arrayOf("vuejs", "nuxtjs", "javascript", "clipboard", "hoge", "fuga", "hogehoge", "fugafuga"),
)
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
modifier = Modifier.fillMaxWidth().padding(8.dp)
) {
ActivityCard(
activity = activity,
onClick = {}
)
}
}
}
以上です。
関連する記事
UI ComponentにJetpackComposeを採用したアプリを開発してみました
Jetpack Composeメインのアプリ開発を行いました。アプリ内で紹介しているAvatar Componentの開発方法を紹介します。
[Jetpack Compose]プログラミング言語のシンタックスハイライト
github.com/kbiakov/CodeView-Androidを少し改造して、Jetpack Composeでコードビューを実装してみました
[Jetpack Compose]Analytics / Crashlytics / FCMを導入
FirebaseをJetpack Composeアプリに導入して、プッシュ通知を受取り対応する画面を開くようにしました。またAnalyticsやCrashlyticsも同時に導入しました。
[Jetpack Compose]ローディングアニメーションつきカードコンポーネントの作成
rememberinfinitetransitionをうまく活用し、Jetpack Composeでローディングアニメーションつきのカードコンポーネントを作成しました。