앱 바

앱 바는 사용자에게 주요 기능 및 탐색 항목에 대한 액세스 권한을 제공하는 컨테이너입니다. 앱 바에는 상단 앱 바와 하단 앱 바, 두 가지 유형이 있습니다. 각각의 모양과 목적은 다음과 같습니다.

유형

디자인

목적

상단 앱 바

화면 상단

주요 작업 및 정보에 대한 액세스를 제공합니다. 일반적으로 제목, 핵심 작업 항목, 특정 탐색 항목을 호스팅합니다.

하단 앱 바

화면 하단

일반적으로 핵심 탐색 항목을 포함합니다. 포함된 플로팅 작업 버튼 등을 통해 다른 주요 작업에 액세스할 수도 있습니다.

상단 및 하단 앱 바의 예
그림 1. 상단 앱 바 (왼쪽)와 하단 앱 바 (오른쪽)

상단 앱 바와 하단 앱 바를 구현하려면 각각 TopAppBarBottomAppBar 컴포저블을 사용합니다. 이를 통해 탐색 및 작업 컨트롤을 캡슐화하고 Material Design 원칙에 부합하는 일관된 인터페이스를 만들 수 있습니다.

상위 앱 바

다음 표에는 네 가지 유형의 상단 앱 바가 요약되어 있습니다.

유형

소형: 탐색이나 작업이 많지 않은 화면에 적합합니다.

작은 상단 앱 바

가운데 정렬: 단일 기본 작업이 있는 화면에 적합합니다.

가운데 정렬 상단 앱 바

중간 버전: 적당한 양의 탐색과 작업이 필요한 화면에 적합합니다.

중간 상단 앱 바

대형: 탐색 및 작업이 많은 화면에 적합합니다.

큰 상단 앱 바

API 노출 영역

서로 다른 4개의 상단 앱 바를 구현할 수 있는 다양한 컴포저블은 상당히 비슷합니다. 다음과 같은 몇 가지 주요 매개변수를 공유합니다.

  • title: 앱 바에 표시되는 텍스트입니다.
  • navigationIcon: 탐색의 기본 아이콘입니다. 앱 바의 왼쪽에 표시됩니다.
  • actions: 사용자가 주요 작업에 액세스할 수 있는 아이콘입니다. 앱 바의 오른쪽에 표시됩니다.
  • scrollBehavior: 상단 앱 바가 Scaffold의 내부 콘텐츠 스크롤에 응답하는 방식을 결정합니다.
  • colors: 앱 바가 표시되는 방식을 결정합니다.

스크롤 동작

사용자가 지정된 Scaffold의 내부 콘텐츠를 스크롤할 때 앱 바가 응답하는 방식을 제어할 수 있습니다. 이렇게 하려면 TopAppBarScrollBehavior 인스턴스를 만들어 scrollBehavior 매개변수의 상단 앱 바에 전달합니다.

TopAppBarScrollBehavior에는 세 가지 유형이 있습니다. 다음과 같습니다.

  • enterAlwaysScrollBehavior: 사용자가 Scaffold의 내부 콘텐츠를 가져오면 상단 앱 바가 접힙니다. 앱 바는 사용자가 내부 콘텐츠를 끌어 내리면 확장됩니다.
  • exitUntilCollapsedScrollBehavior: enterAlwaysScrollBehavior와 비슷하지만 사용자가 Scaffold 내부 콘텐츠의 끝에 도달하면 앱 바가 추가로 확장됩니다.
  • pinnedScrollBehavior: 앱 바는 그대로 유지되며 스크롤에 반응하지 않습니다.

다음 예에서는 이러한 옵션 중 여러 가지를 구현합니다.

다음 섹션에서는 스크롤 동작을 제어할 수 있는 방법에 관한 다양한 예를 포함하여 네 가지 유형의 상단 앱 바 구현을 제공합니다.

사이즈: S

작은 상단 앱 바를 만들려면 TopAppBar 컴포저블을 사용합니다. 이는 가장 간단한 상단 앱 바이며, 이 예에서는 제목만 포함합니다.

다음 예는 TopAppBarscrollBehavior 값을 전달하지 않으므로 내부 콘텐츠의 스크롤에 반응하지 않습니다.

@Composable
fun SmallTopAppBarExample() {
    Scaffold(
        topBar = {
            TopAppBar(
                colors = TopAppBarDefaults.topAppBarColors(
                    containerColor = MaterialTheme.colorScheme.primaryContainer,
                    titleContentColor = MaterialTheme.colorScheme.primary,
                ),
                title = {
                    Text("Small Top App Bar")
                }
            )
        },
    ) { innerPadding ->
        ScrollContent(innerPadding)
    }
}

이 구현은 다음과 같이 표시됩니다.

작은 상단 앱 바의 예
그림 2. 작은 상단 앱 바

가운데 정렬됨

가운데 정렬된 상단 앱 바는 본질적으로 작은 앱 바와 같지만 제목은 구성요소 중앙에 배치됩니다. 이를 구현하려면 전용 CenterAlignedTopAppBar 컴포저블을 사용하세요.

이 예에서는 enterAlwaysScrollBehavior()를 사용하여 scrollBehavior에 전달하는 값을 가져옵니다. 따라서 사용자가 Scaffold의 내부 콘텐츠를 스크롤하면 막대가 접힙니다.

@Composable
fun CenterAlignedTopAppBarExample() {
    val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())

    Scaffold(
        modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),

        topBar = {
            CenterAlignedTopAppBar(
                colors = TopAppBarDefaults.topAppBarColors(
                    containerColor = MaterialTheme.colorScheme.primaryContainer,
                    titleContentColor = MaterialTheme.colorScheme.primary,
                ),
                title = {
                    Text(
                        "Centered Top App Bar",
                        maxLines = 1,
                        overflow = TextOverflow.Ellipsis
                    )
                },
                navigationIcon = {
                    IconButton(onClick = { /* do something */ }) {
                        Icon(
                            imageVector = Icons.Filled.ArrowBack,
                            contentDescription = "Localized description"
                        )
                    }
                },
                actions = {
                    IconButton(onClick = { /* do something */ }) {
                        Icon(
                            imageVector = Icons.Filled.Menu,
                            contentDescription = "Localized description"
                        )
                    }
                },
                scrollBehavior = scrollBehavior,
            )
        },
    ) { innerPadding ->
        ScrollContent(innerPadding)
    }
}

이 구현은 다음과 같이 표시됩니다.

여기에 대체 텍스트를 작성하세요.
그림 3. 가운데 정렬된 상단 앱 바

Medium

중간 크기의 상단 앱 바는 추가 아이콘 아래에 제목을 배치합니다. 이를 만들려면 MediumTopAppBar 컴포저블을 사용하세요.

이전 스니펫과 마찬가지로 이 예에서는 enterAlwaysScrollBehavior()를 사용하여 scrollBehavior에 전달하는 값을 가져옵니다.

@Composable
fun MediumTopAppBarExample() {
    val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(rememberTopAppBarState())

    Scaffold(
        modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
        topBar = {
            MediumTopAppBar(
                colors = TopAppBarDefaults.topAppBarColors(
                    containerColor = MaterialTheme.colorScheme.primaryContainer,
                    titleContentColor = MaterialTheme.colorScheme.primary,
                ),
                title = {
                    Text(
                        "Medium Top App Bar",
                        maxLines = 1,
                        overflow = TextOverflow.Ellipsis
                    )
                },
                navigationIcon = {
                    IconButton(onClick = { /* do something */ }) {
                        Icon(
                            imageVector = Icons.Filled.ArrowBack,
                            contentDescription = "Localized description"
                        )
                    }
                },
                actions = {
                    IconButton(onClick = { /* do something */ }) {
                        Icon(
                            imageVector = Icons.Filled.Menu,
                            contentDescription = "Localized description"
                        )
                    }
                },
                scrollBehavior = scrollBehavior
            )
        },
    ) { innerPadding ->
        ScrollContent(innerPadding)
    }
}

이 구현은 다음과 같이 표시되며 enterAlwaysScrollBehavior()의 스크롤 동작이 어떻게 표시되는지 보여줍니다.

그림 4. 가운데 정렬된 상단 앱 바

크게

대형 상단 앱 바는 매체와 유사하지만 제목과 아이콘 사이의 패딩이 더 크고 전체적으로 화면에서 더 많은 공간을 차지합니다. 이를 만들려면 LargeTopAppBar 컴포저블을 사용하세요.

앞의 스니펫과 달리 이 예에서는 exitUntilCollapsedScrollBehavior()를 사용하여 scrollBehavior에 전달하는 값을 가져옵니다. 따라서 사용자가 Scaffold의 내부 콘텐츠를 스크롤하면 막대가 접히고 내부 콘텐츠의 끝까지 스크롤하면 막대가 확장됩니다.

@Composable
fun LargeTopAppBarExample() {
    val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(rememberTopAppBarState())

    Scaffold(
        modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
        topBar = {
            LargeTopAppBar(
                colors = TopAppBarDefaults.topAppBarColors(
                    containerColor = MaterialTheme.colorScheme.primaryContainer,
                    titleContentColor = MaterialTheme.colorScheme.primary,
                ),
                title = {
                    Text(
                        "Large Top App Bar",
                        maxLines = 1,
                        overflow = TextOverflow.Ellipsis
                    )
                },
                navigationIcon = {
                    IconButton(onClick = { /* do something */ }) {
                        Icon(
                            imageVector = Icons.Filled.ArrowBack,
                            contentDescription = "Localized description"
                        )
                    }
                },
                actions = {
                    IconButton(onClick = { /* do something */ }) {
                        Icon(
                            imageVector = Icons.Filled.Menu,
                            contentDescription = "Localized description"
                        )
                    }
                },
                scrollBehavior = scrollBehavior
            )
        },
    ) { innerPadding ->
        ScrollContent(innerPadding)
    }
}

이 구현은 다음과 같이 표시됩니다.

왼쪽에는 작업 아이콘을 위한 하단 앱 바와 오른쪽에 플로팅 작업 버튼이 있는 앱 화면
그림 5. 큰 상단 앱 바 구현의 예

하단 앱 바

하단 앱 바를 만들려면 BottomAppBar 컴포저블을 사용합니다. 이 컴포저블을 사용하는 방법은 이 페이지의 이전 섹션에 설명된 상단 앱 바 컴포저블과 매우 유사합니다. 다음과 같은 주요 매개변수에 컴포저블을 전달합니다.

  • actions: 막대의 왼쪽에 표시되는 일련의 아이콘입니다. 이는 일반적으로 특정 화면의 키 작업 또는 탐색 항목입니다.
  • floatingActionButton: 막대의 오른쪽에 표시되는 플로팅 작업 버튼입니다.

@Composable
fun BottomAppBarExample() {
    Scaffold(
        bottomBar = {
            BottomAppBar(
                actions = {
                    IconButton(onClick = { /* do something */ }) {
                        Icon(Icons.Filled.Check, contentDescription = "Localized description")
                    }
                    IconButton(onClick = { /* do something */ }) {
                        Icon(
                            Icons.Filled.Edit,
                            contentDescription = "Localized description",
                        )
                    }
                    IconButton(onClick = { /* do something */ }) {
                        Icon(
                            Icons.Filled.Mic,
                            contentDescription = "Localized description",
                        )
                    }
                    IconButton(onClick = { /* do something */ }) {
                        Icon(
                            Icons.Filled.Image,
                            contentDescription = "Localized description",
                        )
                    }
                },
                floatingActionButton = {
                    FloatingActionButton(
                        onClick = { /* do something */ },
                        containerColor = BottomAppBarDefaults.bottomAppBarFabColor,
                        elevation = FloatingActionButtonDefaults.bottomAppBarFabElevation()
                    ) {
                        Icon(Icons.Filled.Add, "Localized description")
                    }
                }
            )
        },
    ) { innerPadding ->
        Text(
            modifier = Modifier.padding(innerPadding),
            text = "Example of a scaffold with a bottom app bar."
        )
    }
}

이 구현은 다음과 같이 표시됩니다.

왼쪽에는 작업 아이콘을 위한 하단 앱 바와 오른쪽에 플로팅 작업 버튼이 있는 앱 화면
그림 6. 하단 앱 바 구현의 예

추가 리소스