Material 3 Expressive の実装例の紹介シリーズです。
今回は App bar 系を紹介します。
(androidx.compose.material3:material3:1.4.0-alpha15
時点での内容になります。)
Material 3 Expressive での変更点
- Top app bar から App bar にリネーム
- Search app bar の追加
- Material 3 で追加された Medium と Large の
TopAppBar
が廃止され、新たに Medium flexible と Large flexible の App bar が追加
実装
Small app bar
TopAppBar
に title や subtitle、navigationIcon、 actions 等が Slot として用意されています。
TopAppBar(
title = {
Text("Title", maxLines = 1, overflow = TextOverflow.Ellipsis)
}
)
// with subtitle
TopAppBar(
title = {
Text("Title", maxLines = 1, overflow = TextOverflow.Ellipsis)
},
subtitle = { Text("Subtitle", maxLines = 1, overflow = TextOverflow.Ellipsis) },
)
// with actions
TopAppBar(
title = {
Text("Title", maxLines = 1, overflow = TextOverflow.Ellipsis)
},
subtitle = {
Text("Subtitle", maxLines = 1, overflow = TextOverflow.Ellipsis)
},
navigationIcon = {
IconButton(onClick = {}) {
Icon(...)
}
},
actions = {
IconButton(onClick = {}) {
Icon(...)
}
}
)
// Center aligned
CenterAlignedTopAppBar(
title = {
Text("Title", maxLines = 1, overflow = TextOverflow.Ellipsis)
},
navigationIcon = {
IconButton(onClick = {}) { ... }
},
actions = {
IconButton(onClick = {}) { ... }
}
)
// Center aligned with subtitle
TopAppBar(
title = {
Text("Title", maxLines = 1, overflow = TextOverflow.Ellipsis)
},
subtitle = {
Text("Subtitle", maxLines = 1, overflow = TextOverflow.Ellipsis)
},
titleHorizontalAlignment = Alignment.CenterHorizontally,
navigationIcon = {
IconButton(onClick = {}) { ... }
},
actions = {
IconButton(onClick = {}) { ... }
}
)

Medium flexible app bar
MediumFlexibleTopAppBar
を使います。基本的には TopAppBar
の使い方と同じになっています。
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
Scaffold(
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
topBar = {
MediumFlexibleTopAppBar(
title = {
Text("Title", maxLines = 1, overflow = TextOverflow.Ellipsis)
},
subtitle = { Text("Subtitle", maxLines = 1, overflow = TextOverflow.Ellipsis) },
navigationIcon = { ... },
actions = { ... },
scrollBehavior = scrollBehavior
)
},
) { ... }

Large flexible app bar
LargeFlexibleTopAppBar
を使います。こちらも基本的には TopAppBar
の使い方と同じになっています。
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
Scaffold(
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
topBar = {
LargeFlexibleTopAppBar(
title = {
Text("Title", maxLines = 1, overflow = TextOverflow.Ellipsis)
},
subtitle = { Text("Subtitle", maxLines = 1, overflow = TextOverflow.Ellipsis) },
navigationIcon = { ... },
actions = { ... },
scrollBehavior = scrollBehavior
)
},
) { ... }

App bar + Adaptive actions
App bar の action 部分に AppBarRow
/ AppBarColumn
を使うことで、画面サイズで action のアイテムを自動で省略する実装ができます。
App bar の action のアイテム数は Compact の時は最大 2 つまでに留め、それ以上の場合は Toolbar を検討しましょう。
Toolbar の配置が困難な場合に AppBarRow
/ AppBarColumn
で省略するようにしましょう。
https://m3.material.io/components/app-bars/guidelines#224e8ca0-4177-45f4-9f4f-eef1fbb0e4b2
val sizeClass = currentWindowAdaptiveInfo().windowSizeClass
val maxItemCount = if (sizeClass.isWidthAtLeastBreakpoint(WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND)) {
5
} else {
3
}
TopAppBar(
title = {
Text("Title", maxLines = 1, overflow = TextOverflow.Ellipsis)
},
actions = {
AppBarRow(
maxItemCount = maxItemCount,
overflowIndicator = {
IconButton(onClick = { it.show() }) {
Icon(
painter = painterResource(R.drawable.ic_more),
contentDescription = "Other options"
)
}
}
) {
clickableItem(
onClick = {},
icon = {
Icon(
painter = painterResource(R.drawable.ic_add),
contentDescription = null
)
},
label = "Create"
)
clickableItem(
onClick = {},
icon = {
Icon(
painter = painterResource(R.drawable.ic_star),
contentDescription = null
)
},
label = "Favorites"
)
clickableItem(
onClick = {},
icon = {
Icon(
painter = painterResource(R.drawable.ic_search),
contentDescription = null
)
},
label = "Search"
)
clickableItem(
onClick = {},
icon = {
Icon(
painter = painterResource(R.drawable.ic_settings),
contentDescription = null
)
},
label = "Settings"
)
}
}
}
Compact | Medium |
---|---|
![]() |
![]() |
Search app bar
ガイドラインに記載されているような見た目の Search app bar の標準の実装はなく、現時点では SearchBar
をカスタムする形になります。
追加され次第追記します。
TwoRowsTopAppBar
によるカスタマイズ
MediumFlexibleTopAppBar
と LargeFlexibleTopAppBar
は TwoRowsTopAppBar
の上に実装されており、元となる TwoRowsTopAppBar
を使うことで自由な Flexible app bar を実装することができます。
引数で collapsedHeight
と expandedHeight
のサイズを指定すれば固定の高さに、未指定であればコンテンツの高さになります。
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
TwoRowsTopAppBar(
title = { expanded ->
if (expanded) {
Text("Expanded TopAppBar\nWith two lines")
} else {
Text("Collapsed TopAppBar", maxLines = 1, overflow = TextOverflow.Ellipsis)
}
},
subtitle = { expanded ->
if (expanded) {
Text(
"Expanded Subtitle",
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.padding(bottom = 24.dp)
)
} else {
Text("Collapsed Subtitle", maxLines = 1, overflow = TextOverflow.Ellipsis)
}
},
navigationIcon = { ... },
scrollBehavior = scrollBehavior
)
