Skip to content

material2_appbars

Zakir Sheikh edited this page Feb 15, 2024 · 10 revisions

AppBar

App bars are containers that provide the user access to key features and navigation items. There are two types of app bars, top app bars and bottom app bars. Their respective appearance and purpose are as follows:

Type Appearance Purpose
Top app bar Across the top of the screen. Provides access to key tasks and information. Generally hosts a title, core action items, and certain navigation items.
Bottom app bar Across the bottom of the screen. Typically includes core navigation items. May also provide access to other key actions, such as through a contained floating action button.
Figure - A top app bar (left) and a bottom app bar (right).

TopAppBar

The following table outlines the 2 types of top app bars:

Type Visual
TopAppBar: For screens that don't require a lot of navigation or actions. image
LargeTopAppBar: For screens that require a lot of navigation and actions. image

API surface

The various composables that allow you to implement the four different top app bars are quite similar. They share several key parameters:

  • title: The text that appears across the app bar.
  • navigationIcon: The primary icon for navigation. Appears on the left of the app bar.
  • actions: Icons that provide the user access to key actions. They appear on the right of the app bar.
  • scrollBehavior: Determines how the top app bar responds to scrolling of the scaffold's inner content.
  • style: Determines how the app bar appears.

Preview

Collapsable ExitUnitCollapsed LargeTopBar Collapsable ExitUnitCollapsed TopAppBar Collapsable EnterAlways

Usage

The largeTopBar is a composable function that allows you to easily create dynamic app bars in your Android apps. By customizing its scrollBehaviours, you can achieve various collapsing behaviors similar to the LargeTopAppBar in Material3. Additionally, setting different values for the maxHeight property lets you create medium-sized app bars, giving you more flexibility in your UI design.

val topAppBarScrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
Scaffold(
    // Utilize nested scroll from topAppBarScrollBehavior.
    modifier = Modifier.nestedScroll(topAppBarScrollBehavior.nestedScrollConnection),
    topBar = {
        // Employ LargeAppBar for comprehensive app bar functionality.
        LargeAppBar(  
            isLarge = showLargeBar,
            windowInsets: WindowInsets = TopAppBarDefaults.windowInsets,
            style: TopAppBarStyle = TopAppBarDefaults.largeAppBarStyle(),
            label = "Title",
            onBack = onBack,
            navigationIcon = {
                // TODO - Implement Navigation Icon
            },
            actions = {
                // TODO - Implement Action Row
            },
            scrollBehavior = topAppBarScrollBehavior
        )
    }
) { inner ->
    // Implement content.
}

CollapsableAppBarLayout

This is the actual implementation of CollapsibleAppBarLayout. It serves as the foundation for both LargeTopAppBar and TopAppBar. In the future, it will be extracted to a separate module or library. You have the freedom to create your own implementation based on this one, similar to howLargeTopAppBar is designed. The provided modifiers, such as Modifier.road and Modifier.parallax, offer customization options. Additionally, you can specify a layoutId to assign a default function to a component, like LayoutIdNavIcon`` from TopBarDefaults. This ensures that the navigation icon is laid out according to the `LargeTopAppBar` implementation.

Figure - Preview CollapsableTopBarLayout

Example code for Custom impl of CollapsableTopBarLayout

@Composable
CollapsableTopBarLayout(
    height = 56.dp,
    maxHeight = 220.dp,
    insets = insets,
    scrollBehavior = behaviour,
    modifier = modifier
) {
    // Background with image representation and gradient
    val id by state.carousel.collectAsState()
    val colors = Material.colors
    val gradient =
        Brush.verticalGradient(colors = listOf(Color.Transparent, colors.background))

    // Background
    Crossfade(
        targetState = Repository.toAlbumArtUri(id ?: 0),
        animationSpec = tween(4_000),
        modifier = Modifier
            .fillMaxSize()
            .foreground(lerp(colors.surfaceColorAtElevation(2.dp), Color.Transparent, fraction))
            .foreground(gradient)
            .layoutId(TopAppBarDefaults.LayoutIdBackground),
        content = { value ->
            // Impleent the background along with effect 
        }
    )

    // Navigation Icon.
    val provider = LocalSystemFacade.current
    IconButton(
        onClick = { provider.launchAppStore() },
        painter = rememberVectorPainter(image = Icons.Outlined.Info),
        contentDescription = "about us",
        modifier = Modifier.layoutId(TopAppBarDefaults.LayoutIdNavIcon)
    )

    // Actions  (Buy and settings)
    Row(
        verticalAlignment = Alignment.CenterVertically,
        modifier = Modifier.layoutId(TopAppBarDefaults.LayoutIdAction),
        content = {
            // Implement Actions
        }
    )

    // Title with smooth transition between sizes and positions
    Text(
        text = textResource(id = R.string.library_title),
        fontWeight = FontWeight.Light,
        style = lerp(NormalTopBarTitle, LargeTopBarTitle, fraction),
        modifier = Modifier
            // Custom road modifier.
            .road(Alignment.CenterStart, Alignment.BottomStart)
            // pass standard layoutId for support 
            .layoutId(TopAppBarDefaults.LayoutIdCollapsable_title)
            .offset {
                val dp = lerp(0.dp, 16.dp, fraction)
                IntOffset(dp.roundToPx(), -dp.roundToPx())
            }
    )
}
Download Audiofy to explore a working implementation of the CollapsibleAppBarLayout component.