Build apps faster with our new App builder! Check it out →

ScreenScaffold

Android

Component in Wear Material 3 Compose

[ScreenScaffold] is one of the Wear Material3 scaffold components.

The scaffold components [AppScaffold] and [ScreenScaffold] lay out the structure of a screen and coordinate transitions of the [ScrollIndicator] and [TimeText] components.

[ScreenScaffold] displays the [ScrollIndicator] at the center-end of the screen by default and coordinates showing/hiding [TimeText] and [ScrollIndicator] according to [scrollState].

This version of [ScreenScaffold] has a special slot for a button at the bottom, that grows and shrinks to take the available space after the scrollable content.

Last updated:

Installation

dependencies {
   implementation("androidx.wear.compose:compose-material3:1.0.0-alpha27")
}

Overloads

@Composable
fun ScreenScaffold(
    scrollState: ScalingLazyListState,
    modifier: Modifier = Modifier,
    timeText: (@Composable () -> Unit)? = null,
    scrollIndicator: (@Composable BoxScope.() -> Unit)? = {
        ScrollIndicator(scrollState, modifier = Modifier.align(Alignment.CenterEnd))
    },
    bottomButton: (@Composable BoxScope.() -> Unit)? = null,
    content: @Composable BoxScope.() -> Unit,
)

Parameters

namedescription
scrollStateThe scroll state for [ScalingLazyColumn], used to drive screen transitions such as [TimeText] scroll away and showing/hiding [ScrollIndicator].
modifierThe modifier for the screen scaffold.
timeTextTime text (both time and potentially status message) for this screen, if different to the time text at the [AppScaffold] level. When null, the time text from the [AppScaffold] is displayed for this screen.
scrollIndicatorThe [ScrollIndicator] to display on this screen, which is expected to be aligned to Center-End. It is recommended to use the Material3 [ScrollIndicator] which is provided by default. No scroll indicator is displayed if null is passed.
bottomButtonOptional slot for a Button (usually an [EdgeButton]) that takes the available space below a scrolling list. It will scale up and fade in when the user scrolls to the end of the list, and scale down and fade out as the user scrolls up.
contentThe body content for this screen.
@Composable
fun ScreenScaffold(
    scrollState: TransformingLazyColumnState,
    modifier: Modifier = Modifier,
    timeText: (@Composable () -> Unit)? = null,
    scrollIndicator: (@Composable BoxScope.() -> Unit)? = {
        ScrollIndicator(scrollState, modifier = Modifier.align(Alignment.CenterEnd))
    },
    bottomButton: (@Composable BoxScope.() -> Unit)? = null,
    content: @Composable BoxScope.() -> Unit,
)

Parameters

namedescription
scrollStateThe scroll state for [TransformingLazyColumn], used to drive screen transitions such as [TimeText] scroll away and showing/hiding [ScrollIndicator].
modifierThe modifier for the screen scaffold.
timeTextTime text (both time and potentially status message) for this screen, if different to the time text at the [AppScaffold] level. When null, the time text from the [AppScaffold] is displayed for this screen.
scrollIndicatorThe [ScrollIndicator] to display on this screen, which is expected to be aligned to Center-End. It is recommended to use the Material3 [ScrollIndicator] which is provided by default. No scroll indicator is displayed if null is passed.
bottomButtonOptional slot for a Button (usually an [EdgeButton]) that takes the available space below a scrolling list. It will scale up and fade in when the user scrolls to the end of the list, and scale down and fade out as the user scrolls up.
contentThe body content for this screen.
@Composable
fun ScreenScaffold(
    scrollState: LazyListState,
    modifier: Modifier = Modifier,
    timeText: (@Composable () -> Unit)? = null,
    scrollIndicator: (@Composable BoxScope.() -> Unit)? = {
        ScrollIndicator(scrollState, modifier = Modifier.align(Alignment.CenterEnd))
    },
    bottomButton: (@Composable BoxScope.() -> Unit)? = null,
    content: @Composable BoxScope.() -> Unit,
)

Parameters

namedescription
scrollStateThe scroll state for [androidx.compose.foundation.lazy.LazyColumn], used to drive screen transitions such as [TimeText] scroll away and showing/hiding [ScrollIndicator].
modifierThe modifier for the screen scaffold.
timeTextTime text (both time and potentially status message) for this screen, if different to the time text at the [AppScaffold] level. When null, the time text from the [AppScaffold] is displayed for this screen.
scrollIndicatorThe [ScrollIndicator] to display on this screen, which is expected to be aligned to Center-End. It is recommended to use the Material3 [ScrollIndicator] which is provided by default. No scroll indicator is displayed if null is passed.
bottomButtonOptional slot for a Button (usually an [EdgeButton]) that takes the available space below a scrolling list. It will scale up and fade in when the user scrolls to the end of the list, and scale down and fade out as the user scrolls up.
contentThe body content for this screen.
@Composable
fun ScreenScaffold(
    scrollState: ScrollState,
    modifier: Modifier = Modifier,
    timeText: (@Composable () -> Unit)? = null,
    scrollIndicator: (@Composable BoxScope.() -> Unit)? = {
        ScrollIndicator(scrollState, modifier = Modifier.align(Alignment.CenterEnd))
    },
    content: @Composable BoxScope.() -> Unit,
)

Parameters

namedescription
scrollStateThe scroll state for a Column, used to drive screen transitions such as [TimeText] scroll away and showing/hiding [ScrollIndicator].
modifierThe modifier for the screen scaffold.
timeTextTime text (both time and potentially status message) for this screen, if different to the time text at the [AppScaffold] level. When null, the time text from the [AppScaffold] is displayed for this screen.
scrollIndicatorThe [ScrollIndicator] to display on this screen, which is expected to be aligned to Center-End. It is recommended to use the Material3 [ScrollIndicator] which is provided by default. No scroll indicator is displayed if null is passed.
contentThe body content for this screen.
@Composable
fun ScreenScaffold(
    bottomButton: @Composable BoxScope.() -> Unit,
    scrollInfoProvider: ScrollInfoProvider,
    modifier: Modifier = Modifier,
    timeText: (@Composable () -> Unit)? = null,
    scrollIndicator: (@Composable BoxScope.() -> Unit)? = null,
    content: @Composable BoxScope.() -> Unit,
)

Parameters

namedescription
bottomButtonslot for a Button (usually an [EdgeButton]) that takes the available space below a scrolling list. It will scale up and fade in when the user scrolls to the end of the list, and scale down and fade out as the user scrolls up.
scrollInfoProviderProvider for scroll information used to scroll away screen elements such as [TimeText] and coordinate showing/hiding the [ScrollIndicator], this needs to be a [ScrollInfoProvider].
modifierThe modifier for the screen scaffold.
timeTextTime text (both time and potentially status message) for this screen, if different to the time text at the [AppScaffold] level. When null, the time text from the [AppScaffold] is displayed for this screen.
scrollIndicatorThe [ScrollIndicator] to display on this screen, which is expected to be aligned to Center-End. It is recommended to use the Material3 [ScrollIndicator] which is provided by default. No scroll indicator is displayed if null is passed.
contentThe body content for this screen.
@Composable
fun ScreenScaffold(
    modifier: Modifier = Modifier,
    timeText: (@Composable () -> Unit)? = null,
    scrollInfoProvider: ScrollInfoProvider? = null,
    scrollIndicator: (@Composable BoxScope.() -> Unit)? = null,
    content: @Composable BoxScope.() -> Unit,
)

Parameters

namedescription
modifierThe modifier for the screen scaffold.
timeTextTime text (both time and potentially status message) for this screen, if different to the time text at the [AppScaffold] level. When null, the time text from the [AppScaffold] is displayed for this screen.
scrollInfoProviderProvider for scroll information used to scroll away screen elements such as [TimeText] and coordinate showing/hiding the [ScrollIndicator].
scrollIndicatorThe [ScrollIndicator] to display on this screen, which is expected to be aligned to Center-End. It is recommended to use the Material3 [ScrollIndicator] which is provided by default. No scroll indicator is displayed if null is passed.
contentThe body content for this screen.

Code Examples

ScaffoldSample

@Composable
fun ScaffoldSample() {
    // Declare just one [AppScaffold] per app such as in the activity.
    // [AppScaffold] allows static screen elements (i.e. [TimeText]) to remain visible
    // during in-app transitions such as swipe-to-dismiss.
    AppScaffold {
        // Define the navigation hierarchy within the AppScaffold,
        // such as using SwipeDismissableNavHost.
        // For this sample, we will define a single screen inline.
        val listState = rememberScalingLazyListState()

        // By default, ScreenScaffold will handle transitions showing/hiding ScrollIndicator
        // and showing/hiding/scrolling away TimeText.
        ScreenScaffold(scrollState = listState) {
            ScalingLazyColumn(state = listState, modifier = Modifier.fillMaxSize()) {
                items(10) {
                    Button(
                        onClick = {},
                        label = { Text("Item ${it + 1}") },
                    )
                }
            }
        }
    }
}

EdgeButtonListSample

@Composable
fun EdgeButtonListSample() {
    val state = rememberScalingLazyListState()
    ScreenScaffold(
        scrollState = state,
        bottomButton = {
            EdgeButton(
                onClick = {},
                buttonSize = EdgeButtonSize.Large,
                colors = buttonColors(containerColor = Color.DarkGray)
            ) {
                Text("Ok", textAlign = TextAlign.Center)
            }
        }
    ) {
        ScalingLazyColumn(
            state = state,
            modifier = Modifier.fillMaxSize(),
            autoCentering = null,
            contentPadding = PaddingValues(10.dp, 20.dp, 10.dp, 100.dp),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            items(10) {
                Card(onClick = {}, modifier = Modifier.fillMaxWidth(0.9f)) { Text("Item #$it") }
            }
        }
    }
}
by @alexstyl