Compose Material3 1.4.0 から AppBarRow
/ AppBarColumn
というオーバーフローした時に自動で省略してくれる API が追加されました。これを使うことでアクションの配置の Adaptive 対応がしやすくなります。
実装
AppBarRow
/ AppBarColumn
は以下のようなシンプルな引数になっています。
-
overflowIndicator
は Menu アイコンを表示する Slot -
maxItemCount
はアイテムの最大表示数- デフォルトの場合は画面に収まりきるまでの最大数を表示
-
AppBarRowScope
/AppBarColumnScope
では以下の 3 パターンのアイテムが設定可能clickableItem
toggleableItem
customItem
fun AppBarRow(
overflowIndicator: @Composable (AppBarMenuState) -> Unit,
modifier: Modifier = Modifier,
maxItemCount: Int = Int.MAX_VALUE,
content: AppBarRowScope.() -> Unit,
)
fun AppBarColumn(
overflowIndicator: @Composable (AppBarMenuState) -> Unit,
modifier: Modifier = Modifier,
maxItemCount: Int = Int.MAX_VALUE,
content: AppBarColumnScope.() -> Unit,
)
maxItemCount
を画面サイズで変えることによって Adaptive な表示にすることができます。
val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass
val maxItemCount = if (windowSizeClass.isWidthAtLeastBreakpoint(WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND)) {
5
} else {
3
}
AppBarRow(
maxItemCount = maxItemCount,
overflowIndicator = {
...
},
) {
...
}
Phone | Tablet |
---|---|
![]() |
![]() |
この AppBarRow
/ AppBarColumn
を TopAppBar
や FloatingToolbar
に使うことでアクションの配置を省略してくれるようになります。
AppBar(TopAppBar) で使う場合
TopAppBar(
title = {
Text("Title", maxLines = 1, overflow = TextOverflow.Ellipsis)
},
navigationIcon = {
IconButton(
onClick = { ... }
) {
Icon(
painterResource(R.drawable.ic_arrow_back),
contentDescription = "Back",
)
}
},
actions = {
val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass
val maxItemCount =
if (windowSizeClass.isWidthAtLeastBreakpoint(WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND)) {
5
} else {
3
}
AppBarRow(
maxItemCount = maxItemCount,
overflowIndicator = { menuState ->
IconButton(onClick = { menuState.show() }) {
Icon(
painterResource(R.drawable.ic_more_vert),
contentDescription = "Other options",
)
}
},
) {
clickableItem(
onClick = { ... },
icon = {
Icon(
painterResource(R.drawable.ic_search),
contentDescription = null,
)
},
label = "Search",
)
toggleableItem(
checked = isFavorited,
onCheckedChange = {
isFavorited = !isFavorited
},
icon = {
Icon(
painterResource(
if (isFavorited) {
R.drawable.ic_favorite_filled
} else {
R.drawable.ic_favorite
}
),
contentDescription = null,
)
},
label = if (isFavorited) {
"Remove from favotites"
} else {
"Add to favorites"
},
)
...
}
},
)
FloatingToolbar で使う場合
HorizontalFloatingToolbar(
modifier = Modifier.align(Alignment.BottomCenter).offset(y = -FloatingToolbarDefaults.ScreenOffset),
expanded = true,
leadingContent = { ... },
trailingContent = {
AppBarRow(
overflowIndicator = { menuState ->
IconButton(onClick = { menuState.show() }) {
Icon(
painterResource(R.drawable.ic_more_vert),
contentDescription = "Other options",
)
}
},
) {
clickableItem(
onClick = { ... },
icon = {
Icon(
painterResource(R.drawable.ic_arrow_back),
contentDescription = null,
)
},
label = "Back",
)
clickableItem(
onClick = { ... },
icon = {
Icon(
painterResource(R.drawable.ic_arrow_forward),
contentDescription = null,
)
},
label = "Forward",
)
toggleableItem(
checked = isFavorited,
onCheckedChange = {
isFavorited = !isFavorited
},
icon = {
Icon(
painterResource(
if (isFavorited) {
R.drawable.ic_favorite_filled
} else {
R.drawable.ic_favorite
}
),
contentDescription = null,
)
},
label = if (isFavorited) {
"Remove from favotites"
} else {
"Add to favorites"
},
)
...
}
},
content = {
FilledIconButton(
modifier = Modifier.width(64.dp),
onClick = { ... }
) {
Icon(painterResource(R.drawable.ic_add), contentDescription = "Add")
}
}
)