はじめに
Preview をより簡単に増やせる方法を学んだので、それらを備忘録としてまとめていこうと思います。
この記事で分かること
-
@PreviewParameter
の使い方 - Multipreview Annotations の使い方
今回 Preview させるもの
単純にメモのリストを表示させるような、非常に簡単なもので試していきたいと思います。Loading
時には CircularProgressIndicator()
を、Error
時には Dialog
を表示させています。
@SuppressLint("UnusedMaterialScaffoldPaddingParameter")
@Composable
fun ExampleScreen(uiState: ExampleUiState) {
Scaffold(
topBar = {
TopAppBar(
title = { Text(text = "ExampleScreen") }
)
}
) {
if (uiState.memos.isEmpty()) {
Text(
text = "まだメモがありません",
modifier = Modifier.fillMaxSize().padding(top = 40.dp),
textAlign = TextAlign.Center,
)
} else {
MemoList(memos = uiState.memos)
}
if (uiState.isLoading) {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
CircularProgressIndicator()
}
}
if (uiState.isError) {
Dialog(onDismissRequest = {}) {
Column(
modifier = Modifier.size(300.dp, 200.dp).background(Color.White),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "エラーです", color = Color.Black)
}
}
}
}
}
@Composable
fun MemoList(memos: List<Memo>) {
LazyColumn(
contentPadding = PaddingValues(horizontal = 16.dp),
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
items(memos) { memo ->
Text(text = memo.title)
}
}
}
簡略化のために Memo
は title
のみを持たせています。
data class ExampleUiState(
val memos: List<Memo> = emptyList(),
val isLoading: Boolean = false,
val isError: Boolean = false
)
data class Memo(
val title: String
)
単純にPreviewをさせる場合
以下のように、uiState の中身だけが異なる Preview が多発します。
// メモがない場合
@Preview
@Composable
fun Preview1() {
ExampleTheme {
ExampleScreen(
uiState = ExampleUiState()
)
}
}
// メモがある場合
@Preview
@Composable
fun Preview2() {
ExampleTheme {
ExampleScreen(
uiState = ExampleUiState(
memos = List(50) { Memo(title = "タイトル No.$it") }
)
)
}
}
// Loading 状態
@Preview
@Composable
fun Preview3() {
ExampleTheme {
ExampleScreen(
uiState = ExampleUiState(
memos = List(50) { Memo(title = "タイトル No.$it") },
isLoading = true
)
)
}
}
// Error状態
@Preview
@Composable
fun Preview4() {
ExampleTheme {
ExampleScreen(
uiState = ExampleUiState(
memos = List(50) { Memo(title = "タイトル No.$it") },
isError = true
)
)
}
}
最初は良くても増えてくると結構面倒になっていきます…。
@PreviewParameter
を使用
そんな時に活用するのが @PreviewParamerter
です。
まずは以下のようなクラスを作成しましょう。好きなだけ ExampleUiState
を作ることが出来ます。
class FakeExampleUiStateProvider : PreviewParameterProvider<ExampleUiState> {
override val values = sequenceOf(
ExampleUiState(),
ExampleUiState(
memos = List(50) { Memo(title = "タイトル No.$it") }
),
ExampleUiState(
memos = List(50) { Memo(title = "タイトル No.$it") },
isLoading = true
),
ExampleUiState(
memos = List(50) { Memo(title = "タイトル No.$it") },
isError = true
),
ExampleUiState(
memos = List(50) {
Memo(title = "長いタイトル長いタイトル長いタイトル長いタイトル長いタイトル長いタイトル No.$it")
}
)
)
}
そして以下のように @PreviewParameter
を使うだけで、先ほど作成した ExampleUiState
を使うことが出来ます。
@Preview
@Composable
fun ExamplePreview(
@PreviewParameter(FakeExampleUiStateProvider::class) uiState: ExampleUiState // ここ!
) {
ExampleTheme {
ExampleScreen(uiState = uiState)
}
}
結果は以下の通りになります。
それぞれの Preview をわざわざ5つ書かなくても @PreviewParameter
を使用すると簡単に表示出来て便利です。
これらをさらにLightモード、Nightモードの両方で確認したい場合があると思います。そんな際に便利なのが自分でアノテーションを作成する方法です。
Multipreview Annotations
以下にある通り、場合によっては使う事が出来ないので注意してください。
Note: This feature is available starting from Android Studio Dolphin and Jetpack Compose 1.2.0-beta01.(公式より)
まずは annotation class を作成し、
@Preview(
name = "light mode",
group = "ui modes",
uiMode = UI_MODE_NIGHT_NO
)
@Preview(
name = "night mode",
group = "ui modes",
uiMode = UI_MODE_NIGHT_YES
)
annotation class UiModePreviews
このアノテーションを表示したい Preview に付けるだけです。
@UiModePreviews // ここ!
@Composable
fun ExamplePreview(
@PreviewParameter(FakeExampleUiStateProvider::class)
uiState: ExampleUiState
) {
ExampleTheme {
ExampleScreen(uiState = uiState)
}
}
これでLightモード・Nightモードの両方を確認できます。
参考資料
おわりに
上記の通り、これらを活用すればより簡単に Preview を表示できるので便利です!
ここまで読んでいただき、ありがとうございました!何かありましたら、コメントをお願いいたします。