Jetpack ComposeのScaffold — 概要、プロパティ、動作方法

著者: IT Sectr 公開日: 2026-06-29 読了時間: 11 分

ScaffoldはJetpack Composeのcomposable関数で、Material Design仕様に従った基本的な画面構造を実装します。ScaffoldはTopAppBar、BottomBar、FloatingActionButton、Drawer、Snackbarのスロットを提供します。Google Android Documentation, 2025によると、ScaffoldはMaterial Designシステムコンポーネントのマージンを管理するため、Composeアプリケーションのほとんどの画面で必須の要素です。

重要なポイント

  • Scaffoldは、TopAppBar、BottomBar、FAB、Drawer、Snackbarのスロットを正しいマージンで提供するMaterial Design画面の枠組みです。
  • ScaffoldStateはDrawerとSnackbarの状態を管理し、サイドメニューの開閉と通知の表示を可能にします。
  • topBarbottomBarfloatingActionButtonは、標準のMaterial Designコンポーネントを統合するためのScaffoldのスロットです。
  • drawerGesturesEnabledはサイドメニューを開くスワイプジェスチャーを制御し、snackbarHostはカスタムSnackbar表示を制御します。
  • ScaffoldはinnerPaddingを通じてステータスバーとナビゲーションバーのマージンを自動的に管理します。

Jetpack ComposeのScaffoldとは

Scaffoldは、Material Design仕様に従って画面の枠組みを実装するcomposable関数です。Scaffoldは従来の意味でのコンテナではなく、画面上の複数の標準Materialコンポーネントの配置を調整するレイアウトマネージャーです。

ScaffoldはTopAppBar、BottomBar、FloatingActionButtonのマージンを管理し、さらにシステム要素(ステータスバーとナビゲーションバー)も管理します。これにより、コンテンツがシステム要素と重ならず、Material Designのガイドラインに準拠することが保証されます。

Material Design Guidelines, 2025によると、Scaffoldはすべてのアプリ画面のルート要素であるべきです。これはViewシステムの古いCoordinatorLayoutを置き換え、画面レイアウトを構築するためのよりシンプルで宣言的なAPIを提供します。

Scaffoldの基本シグネチャ

Scaffoldはmodifier、scaffoldState、topBar、bottomBar、floatingActionButton、drawerContent、snackbarHost、contentのパラメータを受け入れます。contentパラメータはPaddingValues(メインコンテンツが考慮すべきマージン)を受け取ります。

kotlin
@Composable
fun BasicScaffold() {
    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text("ホーム") }
            )
        },
        floatingActionButton = {
            FloatingActionButton(onClick = {}) {
                Icon(Icons.Default.Add, contentDescription = "Add")
            }
        }
    ) { innerPadding ->
        Column(
            modifier = Modifier.padding(innerPadding)
        ) {
            Text("メインコンテンツ")
        }
    }
}

Scaffoldのスロット: topBar、bottomBar、floatingActionButton

topBarはアプリのトップバーを配置するスロットで、通常はTopAppBarまたはLargeTopAppBarです。ScaffoldはコンテンツがtopBarと重ならないように、innerPaddingに自動的にマージンを追加します。TopAppBarにはタイトル、ナビゲーションアイコン、アクションを含めることができます。

bottomBarは下部ナビゲーションバーのスロットです。BottomNavigation、BottomAppBar、NavigationBarをサポートしています。ScaffoldはコンテンツのinnerPaddingを計算する際にbottomBarの高さを考慮します。Material Design Guidelines, 2025によると、bottomBarは3~5つのナビゲーションポイントを持つ画面で使用すべきです。

floatingActionButtonはフローティングアクションボタンのスロットです。ScaffoldはMaterial Design仕様に従ってFABを自動的に配置します(正しいマージンで右下隅)。floatingActionButtonPositionを使用すると、FABを画面の下端中央に移動できます。

すべてのスロットを使用した例

この例では、Scaffoldがすべての主要スロットを使用しています:タイトル付きのTopAppBar、3つのナビゲーション項目を持つBottomBar、メインアクション用のFloatingActionButton。

kotlin
@Composable
fun FullScaffold() {
    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text("アプリ") },
                navigationIcon = {
                    IconButton(onClick = {}) {
                        Icon(Icons.Default.Menu, "Menu")
                    }
                }
            )
        },
        bottomBar = {
            NavigationBar {
                NavigationBarItem(
                    icon = { Icon(Icons.Default.Home, "ホーム") },
                    label = { Text("Home") },
                    selected = true,
                    onClick = {}
                )
                NavigationBarItem(
                    icon = { Icon(Icons.Default.Search, "検索") },
                    label = { Text("Search") },
                    selected = false,
                    onClick = {}
                )
            }
        },
        floatingActionButton = {
            FloatingActionButton(onClick = {}) {
                Icon(Icons.Default.Add, "Add")
            }
        }
    ) { innerPadding ->
        Box(modifier = Modifier.padding(innerPadding)) {
            Text("画面コンテンツ")
        }
    }
}

ScaffoldState: DrawerとSnackbarの管理

ScaffoldStateはDrawerStateとSnackbarHostStateを組み合わせたScaffoldの状態オブジェクトです。DrawerStateはサイドメニューの開閉を管理し、SnackbarHostStateはSnackbarの表示と非表示を管理します。状態はrememberScaffoldState()を使用して作成され、scaffoldStateパラメータに渡されます。

DrawerStateはプログラムによるDrawer制御のためのopenメソッドとcloseメソッドを提供します。Drawerの状態は開く、閉じる、部分的に開くのいずれかです。drawerGesturesEnabledを使用すると、Drawerを開くスワイプジェスチャーを無効にし、ボタンによるプログラム的な開封のみを残すことができます。

SnackbarHostStateはSnackbar(画面下部の一時的な通知)を管理します。showSnackbarメソッドは、メッセージとオプションのアクションを持つSnackbarを表示します。Material Design Guidelines, 2025によると、Snackbarは重大な情報を含まない簡潔なメッセージに使用すべきです。

kotlin
@Composable
fun ScaffoldWithDrawer() {
    val scaffoldState = rememberScaffoldState()
    val scope = rememberCoroutineScope()

    Scaffold(
        scaffoldState = scaffoldState,
        topBar = {
            TopAppBar(
                title = { Text("メニュー") },
                navigationIcon = {
                    IconButton(onClick = {
                        scope.launch {
                            scaffoldState.drawerState.open()
                        }
                    }) {
                        Icon(Icons.Default.Menu, "Menu")
                    }
                }
            )
        },
        drawerContent = {
            Column(modifier = Modifier.padding(16.dp)) {
                Text("項目1")
                Text("項目2")
            }
        }
    ) { innerPadding ->
        Box(modifier = Modifier.padding(innerPadding)) {
            Text("コンテンツ")
        }
    }
}

Scaffoldを使用した画面構築の例

Scaffoldを使用した完全な画面例には、TopAppBar、BottomNavigation、FloatingActionButton、およびFAB押下時に通知を表示するSnackbarが含まれます。ScaffoldStateは状態の調整のためにすべてのコンポーネントに渡されます。

kotlin
@Composable
fun MainScreen() {
    val state = rememberScaffoldState()
    val scope = rememberCoroutineScope()

    Scaffold(
        scaffoldState = state,
        topBar = {
            TopAppBar(
                title = { Text("IT Sectr") },
                actions = {
                    IconButton(onClick = {}) {
                        Icon(Icons.Default.Notifications, "Notifications")
                    }
                }
            )
        },
        bottomBar = {
            NavigationBar {
                NavigationBarItem(icon = { Icon(Icons.Default.Home, "ホーム") },
                    label = { Text("Home") }, selected = true, onClick = {})
                NavigationBarItem(icon = { Icon(Icons.Default.Settings, "設定") },
                    label = { Text("Settings") }, selected = false, onClick = {})
            }
        },
        floatingActionButton = {
            FloatingActionButton(onClick = {
                scope.launch {
                    state.snackbarHostState.showSnackbar("完了")
                }
            }) {
                Icon(Icons.Default.Add, "Add")
            }
        }
    ) { padding ->
        Box(
            modifier = Modifier.padding(padding).fillMaxSize(),
            contentAlignment = Alignment.Center
        ) {
            Text("ようこそ")
        }
    }
}

InnerPaddingとScaffoldを使用したアダプティブレイアウト

innerPaddingはScaffoldがcontentブロックに渡すPaddingValuesです。これらには、コンテンツがstatusBar、navigationBar、topBar、bottomBarと重なるのを防ぐために必要なマージンが含まれています。異なるデバイスで正しく表示するには、innerPaddingの使用が必須です。

Scaffoldはシステムのマージンとインストールされたスロットの高さに基づいてinnerPaddingを自動的に計算します。カメラアイ島や画面の切り欠きがあるデバイスでは、Scaffoldはステータスバーのマージンを調整します。物理ボタンがある古いデバイスでは、下部のマージンが存在しない場合があります。

Android Developers, 2024によると、innerPaddingはModifier.padding(innerPadding)を使用してコンテンツのルートコンテナに適用する必要があります。コンテンツがスクロール可能なコンテナを使用する場合、キーボードとシステムジェスチャの正しい動作のために、innerPaddingはModifier.consumeWindowInsetsを介して適用されます。

  • Modifier.padding(innerPadding)を使用してコンテンツのルートコンテナにinnerPaddingを適用する
  • スクロール可能なコンテナにはModifier.consumeWindowInsets(innerPadding)を使用する
  • ステータスバーに追加のマージンを追加しない — Scaffoldが自動的に処理する
  • topBarまたはbottomBarがない場合、innerPaddingの対応するマージンはゼロになる

よくある質問

Scaffoldは通常のColumnやBoxとどう違うのですか?

Scaffoldはコンテナではなく、TopAppBar、BottomBar、FAB、Drawer、Snackbarのスロットを制御し、システムコンポーネントのマージンを自動的に処理するレイアウトマネージャーです。ColumnとBoxはMaterial Designを考慮せずに要素を配置するだけです。

すべての画面でScaffoldを使用する必要がありますか?

ScaffoldはMaterial Designコンポーネントを使用する画面で推奨されます。TopAppBar、BottomBar、FABのないシンプルな画面ではScaffoldは必須ではありませんが、innerPaddingを通じて正しいシステムマージンを提供するため、スロットがなくても有用です。

Scaffoldを介してSnackbarを表示するには?

ScaffoldのscaffoldStateパラメータにScaffoldStateを渡し、コルーチン内でstate.snackbarHostState.showSnackbar(“メッセージ”)を呼び出します。Scaffoldは自動的に画面下部にSnackbarを表示します。

scaffoldStateなしでScaffoldを使用できますか?

はい、ScaffoldはscaffoldStateが渡されない場合、デフォルトで内部状態を作成します。ただし、DrawerとSnackbarをプログラム的に制御するには、rememberScaffoldState()を使用してScaffoldStateを作成して渡す必要があります。

ScaffoldでFloatingActionButtonの位置を変更するには?

ScaffoldのfloatingActionButtonPositionパラメータを使用します。デフォルトではFABは右下(FabPosition.End)に配置されます。FabPosition.Centerを設定すると、FABを画面の下端中央に配置できます。

まとめ

  • Scaffoldは、TopAppBar、BottomBar、FAB、Drawer、Snackbarのスロット管理と自動システムマージンを備えたMaterial Design画面の枠組みです。
  • topBarbottomBarfloatingActionButtonは、正しい配置で標準コンポーネントを統合するためのScaffoldのスロットです。
  • ScaffoldStateはDrawerStateとSnackbarHostStateを組み合わせ、コルーチンを介してサイドメニューと通知をプログラム的に制御します。
  • innerPaddingはcontentブロックの必須パラメータで、システム要素とインストールされたScaffoldスロットのマージンを含みます。
  • drawerGesturesEnabledfloatingActionButtonPositionはScaffoldの動作を微調整するための追加パラメータです。
  • Scaffoldは異なる画面構成のデバイスでステータスバーとナビゲーションバーのマージンを自動的に処理します。
  • Materialコンポーネントのないシンプルな画面ではScaffoldは必須ではありませんが、正しいシステムマージン処理のためにルート要素として推奨されます。

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください