ComposableのPreviewで下が見切れてしまう時の対応
GENDA Advent Calendar 2023 の17日目の記事です!
こちらの記事はComposableのPreview便利ですよね!
アプリを実装していく中で、画面や処理の状態によって、
オブジェクトの表示を変えることがありますよね?
状態が、4~5くらいであれば、管理も簡単ですが、
10個以上になってしまうことも少なくありません。
ComposeはPreview機能が充実しています。
1つの部品に対して、複数の状態のPreviewを用意できます。
下記のように1画面内で、複数の状態を確認できて、非常に便利です。
(画像はKotlinのマスコットKodee君です。)
表示する要素数が多くなければ、
下記のようにループしてPreviewを書くことが多いのではないでしょうか?
@Preview
@Composable
fun KodeeDisPlayPreview() {
Column {
KodeeState.entries.forEach {
KodeeDisplay(state = it)
}
}
}
要素数 == 多い && 十分な高さを持つ場合は・・・?
サンプルとして、18個の要素を持つEnum Classを作成しました。
enum class Type {
NORMAL,
FIRE,
WATER,
GRASS,
ELECTRIC,
ICE,
FIGHTING,
POISON,
GROUND,
FLYING,
PSYCHIC,
BUG,
ROCK,
GHOST,
DRAGON,
DARK,
STEEL,
FAIRY
}
そして、このTypeに応じて、表示を変えるComposable関数を用意しました。
Typeによって、背景の色とテキストが変わる簡単なComposable関数です。
高さは80dpで固定しています。
fun TypeDisplay(type: Type) {
Box(
modifier = Modifier
.fillMaxWidth()
.height(80.dp)
.clip(RoundedCornerShape(25.dp))
.background(getTypeColor(type))
) {
Text(
text = stringResource(getTypeText(type)),
modifier = Modifier.align(Alignment.Center),
fontSize = 20.sp,
color = Color.White,
textAlign = TextAlign.Center
)
}
}
Previewのコードは下記のように書きました。
ループで書いているので、新しいTypeが追加されても安心ですね!
@Preview
@Composable
fun PreviewTypeDisplay() {
Column(verticalArrangement = Arrangement.spacedBy(10.dp)) {
Type.entries.forEach {
TypeDisplay(it)
}
}
}
それでは、Previewを見てみましょう!
18個表示されるはずが、10個しか表示されません。
また10個目の「ひこう」は意図した高さを持っていないように見えます。
原因
Previewがデフォルトで1000dpまでしか大きくならないようです。
解決策1 Previewの高さを指定
Previewの高さを明示的に指定することが出来ます。
@Preview(heightDp = 2000)
@Composable
fun PreviewTypeDisplay() {
Column(verticalArrangement = Arrangement.spacedBy(10.dp)) {
Type.entries.forEach {
TypeDisplay(it)
}
}
}
これでも良いのですが、要素の追加などで
さらに高さが必要になった際に、追加修正が必要になる恐れがあります。
解決策2 PreviewParameterProviderを利用する
PreviewParameterProviderを用意して、引数として指定すると良いです。
valuesの数だけ、Previewが生成されます。
class PreviewGameControlButtonProvider : PreviewParameterProvider<Type> {
override val values: Sequence<Type>
get() = Type.entries.asSequence()
}
@Preview()
@Composable
fun PreviewTypeDisplay(
@PreviewParameter(PreviewGameControlButtonProvider::class) type: Type
) {
TypeDisplay(type = type)
}
下記のようなPreviewが表示されました。
画面キャプチャの関係で、「じめん」までしか写っていませんが、
スクロールすると18個全てが正常な大きさで表示されます。
個人的にはコチラをオススメします。
最後に
PreviewParameterProviderは、Enumの要素以外でも利用できますし、
適切なPreviewをより簡潔に書けるので、個人的には好みでした。
Previewを見る機会は、実装時だけでなく、コードレビューの際などにも利用することもあります。
そのため、プロダクトの品質向上やレビューコストの削減のためにも
意図しないPreviewが表示されてしまう事態は無くしていきたいと思いました。(小並感)
Discussion