【Jetpack Compose/Android】Scaffoldの使い方!アプリバーやフローティングボタン
この記事からわかること
- Kotlin/Android Jetpack ComposeのScaffoldの使い方
- アプリバーやフローティングボタンの実装方法
index
[open]
\ アプリをリリースしました /
環境
- Android Studio:Narwhal Feature Drop
- Kotlin:2.1.10
- Material3
- AGP:8.9.2
- Gradle:8.11.1
- Mac M1:Sequoia 15.6.1
Jetpack Compose自体の基本的な使用方法に関しては以下の記事を参考にしてください。
Scaffold
Jetpack ComposeのScaffoldはアプリの基本的なレイアウト構造を、Material Designをベースにして構築するための土台となるUIコンポーザブルです。
Scaffoldではアプリバー(上部バー)やフローティングボタン、ボトムバー、SnackbarなどをMaterial Designを使用して簡単に実装することが可能になります。Scaffoldは「足場」という意味なので、意味をわかっていれば想像しやすいかもしれません。
似たような土台を構築するコンポーザブルにSurfaceがあります。Surfaceとの違いの1つにEdge-to-edgeに対応しているかどうかです。Scaffoldをベースにしていた画面は自動で上下のシステムバーやノッチ周りの余白を調整してくれます。
定義を確認してみると色々なプロパティが存在することがわかります。今回はこの中でもよく使うtopBar、bottomBar、floatingActionButtonなどの使い方を解説していきます。
@Composable
fun Scaffold(
modifier: Modifier = Modifier,
topBar: @Composable () -> Unit = {},
bottomBar: @Composable () -> Unit = {},
snackbarHost: @Composable () -> Unit = {},
floatingActionButton: @Composable () -> Unit = {},
floatingActionButtonPosition: FabPosition = FabPosition.End,
containerColor: Color = MaterialTheme.colorScheme.background,
contentColor: Color = contentColorFor(containerColor),
contentWindowInsets: WindowInsets = ScaffoldDefaults.contentWindowInsets,
content: @Composable (PaddingValues) -> Unit
)
似たような実装方法でFlutterのScaffoldもあるので興味があれば参考にしてください。
Scaffoldの使い方
Scaffoldは土台部分を構成するコンポーザブルなので画面単位の土台として活用します。新規プロジェクト立ち上げ時のデフォルトのサンプルコードであるMainActivityにも実際に使われています。それぞれの部分を切り出しながら実装を確認していきます。
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
ComposeTestAppTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Greeting(
name = "Android",
modifier = Modifier.padding(innerPadding)
)
}
}
}
}
}
Composable
content: @Composable (PaddingValues) -> Unit
Scaffoldでラップした中に配置するComposableは引数contentのクロージャーの中に指定します。ここでは引数にPaddingValuesを受け取っており、これを子供のComposableに指定しないとエラーになります。
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Greeting(
name = "Android",
// 指定しないとエラーになる
modifier = Modifier.padding(innerPadding)
)
}
このパディングを指定することで画面に綺麗に収まるようにViewが配置されるので基本指定しておけば良いですが、明示的に未指定にしたい場合は@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")を指定することで回避することも可能です。
TopAppBar
topBarではアプリバー(上部バー)部分のUIを構築するTopAppBarを指定します。Material3のTopAppBarはまだ安定していないので@ExperimentalMaterial3Apiを付与する必要があります。
Scaffold(
topBar = {
TopAppBar(
title = { Text("My Screen") },
colors = TopAppBarDefaults.topAppBarColors(
// 背景色
containerColor = Color(0xFFBBDEFB),
// タイトル文字色
titleContentColor = Color.White
)
)
}
) { innerPadding ->
Greeting(
name = "Android",
modifier = Modifier.padding(innerPadding)
)
}
背景色や文字色を変更したい場合はtopAppBarColors型でそれぞれの色を指定します。
FloatingActionButton
floatingActionButtonでは画面の右下に浮いているように表示されるボタンのUIを構築するFloatingActionButtonを指定します。onClickにタップ時に実行したい処理を渡します。
Scaffold(
floatingActionButton = {
FloatingActionButton(
// 背景色
containerColor = Color(0xFFBBDEFB),
// 中のアイコン色
contentColor = Color.White,
onClick = { /* クリック処理 */ },
) {
Icon(
Icons.Default.Add,
contentDescription = "Add"
)
}
},
) { innerPadding ->
Greeting(
name = "Android",
modifier = Modifier.padding(innerPadding)
)
}
BottomAppBar
bottomBarではボトムバー(下部バー)部分のUIを構築するBottomAppBarを指定します。
Scaffold(
bottomBar = {
BottomAppBar(
// 背景色
containerColor = Color(0xFFBBDEFB),
// コンテンツ文字色
contentColor = Color.White
) {
Text("Bottom Bar", modifier = Modifier.padding(16.dp))
}
},
) { innerPadding ->
Greeting(
name = "Android",
modifier = Modifier.padding(innerPadding)
)
}
SnackbarHost
snackbarHostではスナックバーの状態管理するためのSnackbarHostを指定します。あとはボタンのクリックなどでshowSnackbarを呼び出すことでマテリアルデザインに沿ったスナックバーが表示されるようになります。
ComposeTestAppTheme {
// Snackbar の状態を管理する HostState
val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()
Scaffold(
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
floatingActionButton = {
FloatingActionButton(
// 背景色
containerColor = Color(0xFFBBDEFB),
// 中のアイコン色
contentColor = Color.White,
onClick = {
scope.launch {
// Snackbar を表示
snackbarHostState.showSnackbar(
message = "Hello Snackbar!",
actionLabel = "OK"
)
}
},
) {
Icon(
Icons.Default.Add,
contentDescription = "Add"
)
}
},
) { innerPadding ->
Greeting(
name = "Android",
modifier = Modifier.padding(innerPadding)
)
}
}
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。







