androidx.wear.protolayout.material3


Classes

ButtonGroupScope

Scope for the children of a buttonGroup

ColorScheme

A ColorScheme holds all the named color parameters for a MaterialTheme.

EdgeButtonColors

Represents the container and content colors used in textEdgeButton or iconEdgeButton.

EdgeButtonStyle

Provides style values for edge button component.

MaterialScope

Receiver scope which is used by all ProtoLayout Material3 components and layout to support opinionated defaults and to provide the global information for styling Material3 components.

Shapes

Material surfaces can be displayed in different shapes.

Objects

ButtonGroupDefaults

Contains the default values used by buttonGroup

EdgeButtonDefaults
Typography

Class holding typography definitions as defined by the Wear Material3 typography specification.

Annotations

Top-level functions summary

ColorScheme
dynamicColorScheme(context: Context, defaultColorScheme: ColorScheme)

Creates a dynamic color scheme.

Boolean

Returns whether the dynamic colors scheme (colors following the system theme) is enabled.

LayoutElementBuilders.LayoutElement
materialScope(
    context: Context,
    deviceConfiguration: DeviceParametersBuilders.DeviceParameters,
    allowDynamicTheme: Boolean,
    defaultColorScheme: ColorScheme,
    layout: MaterialScope.() -> LayoutElementBuilders.LayoutElement
)

Creates a top-level receiver scope MaterialScope that calls the given layout to support for opinionated defaults and building Material3 components and layout, with default dynamic theme.

Extension functions summary

LayoutElementBuilders.LayoutElement
MaterialScope.buttonGroup(
    width: DimensionBuilders.ContainerDimension,
    height: DimensionBuilders.ContainerDimension,
    spacing: @Dimension(unit = 0) Float,
    content: ButtonGroupScope.() -> Unit
)

ProtoLayout Material3 component-layout that places its children in a horizontal sequence.

LayoutElementBuilders.LayoutElement
MaterialScope.icon(
    protoLayoutResourceId: String,
    size: DimensionBuilders.ImageDimension,
    tintColor: ColorBuilders.ColorProp
)

Returns the icon components with the defined style.

LayoutElementBuilders.LayoutElement
MaterialScope.iconEdgeButton(
    onClick: ModifiersBuilders.Clickable,
    contentDescription: TypeBuilders.StringProp,
    colors: EdgeButtonColors,
    iconContent: MaterialScope.() -> LayoutElementBuilders.LayoutElement
)

ProtoLayout Material3 component edge button that offers a single slot to take an icon or similar round, small content.

LayoutElementBuilders.LayoutElement

ProtoLayout Material3 full screen layout that represents a suggested Material3 layout style that is responsive and takes care of the elements placement, together with the recommended margin and padding applied.

LayoutElementBuilders.LayoutElement
MaterialScope.text(
    text: TypeBuilders.StringProp,
    stringLayoutConstraint: TypeBuilders.StringLayoutConstraint,
    typography: Int,
    color: ColorBuilders.ColorProp,
    italic: Boolean,
    underline: Boolean,
    scalable: Boolean,
    maxLines: Int,
    multilineAlignment: Int,
    overflow: Int,
    modifiers: ModifiersBuilders.Modifiers
)

ProtoLayout component that represents text object holding any information.

LayoutElementBuilders.LayoutElement
MaterialScope.textEdgeButton(
    onClick: ModifiersBuilders.Clickable,
    contentDescription: TypeBuilders.StringProp,
    colors: EdgeButtonColors,
    labelContent: MaterialScope.() -> LayoutElementBuilders.LayoutElement
)

ProtoLayout Material3 component edge button that offers a single slot to take a text or similar long and wide content.

Top-level functions

fun dynamicColorScheme(
    context: Context,
    defaultColorScheme: ColorScheme = ColorScheme()
): ColorScheme

Creates a dynamic color scheme.

Use this function to create a color scheme based on the current watchface. If the user changes the watchface colors, this color scheme will change accordingly. This function checks whether the dynamic color scheme can be used and returns defaultColorScheme otherwise.

Parameters
context: Context

The context required to get system resource data.

defaultColorScheme: ColorScheme = ColorScheme()

The fallback ColorScheme to return if the dynamic color scheme is switched off or unavailable on this device.

isDynamicColorSchemeEnabled

fun isDynamicColorSchemeEnabled(context: Context): Boolean

Returns whether the dynamic colors scheme (colors following the system theme) is enabled.

If enabled, and elements or MaterialScope are opted in to using dynamic theme, colors will change whenever system theme changes.

fun materialScope(
    context: Context,
    deviceConfiguration: DeviceParametersBuilders.DeviceParameters,
    allowDynamicTheme: Boolean = true,
    defaultColorScheme: ColorScheme = ColorScheme(),
    layout: MaterialScope.() -> LayoutElementBuilders.LayoutElement
): LayoutElementBuilders.LayoutElement

Creates a top-level receiver scope MaterialScope that calls the given layout to support for opinionated defaults and building Material3 components and layout, with default dynamic theme.

Parameters
context: Context

The Android Context for the Tile service

deviceConfiguration: DeviceParametersBuilders.DeviceParameters

The device parameters for where the components will be rendered

allowDynamicTheme: Boolean = true

If dynamic colors theme should be used on components, meaning that colors will follow the system theme if enabled on the device. If not set, defaults to using the system theme

defaultColorScheme: ColorScheme = ColorScheme()

Color Scheme with static colors. The color theme to be used, when allowDynamicTheme is false, or when dynamic theming is disabled by the system or user. If not set, defaults to default theme.

layout: MaterialScope.() -> LayoutElementBuilders.LayoutElement

Scoped slot for the content of layout to be displayed

Extension functions

fun MaterialScope.buttonGroup(
    width: DimensionBuilders.ContainerDimension = expand(),
    height: DimensionBuilders.ContainerDimension = expand(),
    spacing: @Dimension(unit = 0) Float = DEFAULT_SPACER_SIZE_DP,
    content: ButtonGroupScope.() -> Unit
): LayoutElementBuilders.LayoutElement

ProtoLayout Material3 component-layout that places its children in a horizontal sequence.

These behave as a group which fill the available space to maximize on screen real estate. The color and size of the child elements should be changed in order to create hierarchy and priority.

The width and height of the Button/Card should be flexible (set to androidx.wear.protolayout.DimensionBuilders.expand or androidx.wear.protolayout.DimensionBuilders.weight) and their proportion should be either equal or weight based. However the buttonGroup displays correctly too if the sizes of elements provided are set to a fixed width/height, although it can lead to more empty space on large screen sizes.

A buttonGroup with more than one row can be created by using multiple buttonGroup and Spacers inside a androidx.wear.protolayout.LayoutElementBuilders.Column:

Column.Builder()
.setWidth(expand())
.setHeight(expand())
.addContent(buttonGroup {...})
.addContent(DEFAULT_SPACER_BETWEEN_BUTTON_GROUPS)
.addContent(buttonGroup {...})
.build()
}

Note that, having more than 2 rows in a Column could lead to too small height of elements that aren't in line with minimum tap target.

Parameters
width: DimensionBuilders.ContainerDimension = expand()

The width of this button group

height: DimensionBuilders.ContainerDimension = expand()

The height of this button group

spacing: @Dimension(unit = 0) Float = DEFAULT_SPACER_SIZE_DP

The amount of spacing between buttons

content: ButtonGroupScope.() -> Unit

The content for each child. The UX guidance is to use no more than 3 elements within a this button group.

fun MaterialScope.icon(
    protoLayoutResourceId: String,
    size: DimensionBuilders.ImageDimension = defaultIconStyle.size,
    tintColor: ColorBuilders.ColorProp = defaultIconStyle.tintColor
): LayoutElementBuilders.LayoutElement

Returns the icon components with the defined style.

Material components provide proper defaults for this icon. In order to take advantage of those, this should be used with the resource ID only: icon("id").

Parameters
protoLayoutResourceId: String

The protolayout resource id of the icon. Node that, this is not an Android resource id.

size: DimensionBuilders.ImageDimension = defaultIconStyle.size

The side of an icon that will be used for width and height.

tintColor: ColorBuilders.ColorProp = defaultIconStyle.tintColor

The color used to tint the icon.

fun MaterialScope.iconEdgeButton(
    onClick: ModifiersBuilders.Clickable,
    contentDescription: TypeBuilders.StringProp,
    colors: EdgeButtonColors = filled(),
    iconContent: MaterialScope.() -> LayoutElementBuilders.LayoutElement
): LayoutElementBuilders.LayoutElement

ProtoLayout Material3 component edge button that offers a single slot to take an icon or similar round, small content.

The edge button is intended to be used at the bottom of a round screen. It has a special shape with its bottom almost follows the screen's curvature. It has fixed height, and takes 1 line of text or a single icon. This button represents the most important action on the screen, and it must occupy the whole horizontal space in its position as well as being anchored to the screen bottom.

This component is not intended to be used with an image background.

import androidx.wear.protolayout.material3.icon
import androidx.wear.protolayout.material3.iconEdgeButton
import androidx.wear.protolayout.material3.materialScope
import androidx.wear.protolayout.material3.text

materialScope(context, deviceConfiguration) {
        iconEdgeButton(onClick = clickable, contentDescription = "Description of a button".prop()) {
            icon("id")
        }
    }
Parameters
onClick: ModifiersBuilders.Clickable

Associated Clickable for click events. When the button is clicked it will fire the associated action.

contentDescription: TypeBuilders.StringProp

The content description to be read by Talkback.

colors: EdgeButtonColors = filled()

The colors used for this button. If not set, EdgeButtonDefaults.filled will be used as high emphasis button. Other recommended colors are EdgeButtonDefaults.filledTonal and EdgeButtonDefaults.filledVariant. If using custom colors, it is important to choose a color pair from same role to ensure accessibility with sufficient color contrast.

iconContent: MaterialScope.() -> LayoutElementBuilders.LayoutElement

The icon slot for content displayed in this button. It is recommended to use default styling that is automatically provided by only calling icon with the resource ID.

fun MaterialScope.primaryLayout(
    mainSlot: MaterialScope.() -> LayoutElementBuilders.LayoutElement,
    titleSlot: (MaterialScope.() -> LayoutElementBuilders.LayoutElement)? = null,
    bottomSlot: (MaterialScope.() -> LayoutElementBuilders.LayoutElement)? = null,
    labelForBottomSlot: (MaterialScope.() -> LayoutElementBuilders.LayoutElement)? = null,
    onClick: ModifiersBuilders.Clickable? = null
): LayoutElementBuilders.LayoutElement

ProtoLayout Material3 full screen layout that represents a suggested Material3 layout style that is responsive and takes care of the elements placement, together with the recommended margin and padding applied.

This layout is meant to occupy the whole screen, so nothing else should be added on top of it.

On the top, there is an icon that will be automatically placed by the system, followed by the optional title slot. The icon slot needs to be reserved for the whole ProtoLayout Layout and no other content should be added at the top of the screen as it will be overlapped with the system placed icon.

At the bottom, there is an optional fixed slot for either {@link EdgeButton} as a main action or small non tappable content.

The middle of the layout is main content, that will fill the available space. For the best results across different screen sizes, it's recommended that this content's dimension are also DimensionBuilders.expand or DimensionBuilders.weight. Additional content in the main one can be added after a 225dp breakpoint.

import androidx.wear.protolayout.LayoutElementBuilders
import androidx.wear.protolayout.LayoutElementBuilders.LayoutElement
import androidx.wear.protolayout.ModifiersBuilders
import androidx.wear.protolayout.material3.buttonGroup
import androidx.wear.protolayout.material3.icon
import androidx.wear.protolayout.material3.iconEdgeButton
import androidx.wear.protolayout.material3.materialScope
import androidx.wear.protolayout.material3.primaryLayout
import androidx.wear.protolayout.material3.text

materialScope(context, deviceConfiguration) {
        primaryLayout(
            titleSlot = { text("App title".prop()) },
            mainSlot = {
                buttonGroup {
                    // To be populated with proper components
                    buttonGroupItem {
                        LayoutElementBuilders.Box.Builder()
                            .setModifiers(
                                ModifiersBuilders.Modifiers.Builder()
                                    .setBackground(
                                        ModifiersBuilders.Background.Builder()
                                            .setCorner(shapes.full)
                                            .build()
                                    )
                                    .build()
                            )
                            .build()
                    }
                }
            },
            bottomSlot = { iconEdgeButton(clickable, "Description".prop()) { icon("id") } }
        )
    }
Parameters
mainSlot: MaterialScope.() -> LayoutElementBuilders.LayoutElement

The main, central content for this layout. It's recommended for this content to fill the available width and height for the best result across different screen size. This layout places proper padding to prevent content from being cropped by the screen. Note that depending on the corner shapes and different elements on the screen, there might be a need to change padding on some of the elements in this slot. The content passed here can also have an additional content value added to it, after 225dp breakpoint. Some of the examples of content that can be passed in here are: * buttonGroup with buttons or cards * two [buttonGroup * Expanded card

titleSlot: (MaterialScope.() -> LayoutElementBuilders.LayoutElement)? = null

The app title in the top slot, just below the icon. This should be one line of text with Typography.TITLE_SMALL typography, describing the main purpose of this layout. Title is an optional slot which can be omitted to make space for other elements. Defaults to ColorScheme.onBackground color.

bottomSlot: (MaterialScope.() -> LayoutElementBuilders.LayoutElement)? = null

The content for bottom slot in this layout, that will be anchored to the bottom edge of the screen. This should be either a small non tappable content such as Text with optional label for it or tappable main action with textEdgeButton or iconEdgeButton which is designed to have its bottom following the screen's curvature. This bottom slot is optional, if unset the main content will expand more towards the edge of the screen.

labelForBottomSlot: (MaterialScope.() -> LayoutElementBuilders.LayoutElement)? = null

The label displayed just above the bottomSlot. Default will be one line of text with Typography.TITLE_SMALL typography, ColorScheme.onSurface color that should contain additional description of this layout. When the bottomSlot is not provided or it an edge button, the given label will be ignored.

onClick: ModifiersBuilders.Clickable? = null

The clickable action for whole layout. If any area (outside of other added tappable components) is clicked, it will fire the associated action.

fun MaterialScope.text(
    text: TypeBuilders.StringProp,
    stringLayoutConstraint: TypeBuilders.StringLayoutConstraint = StringLayoutConstraint.Builder(text.value).build(),
    typography: Int = defaultTextElementStyle.typography,
    color: ColorBuilders.ColorProp = defaultTextElementStyle.color,
    italic: Boolean = defaultTextElementStyle.italic,
    underline: Boolean = defaultTextElementStyle.underline,
    scalable: Boolean = defaultTextElementStyle.scalable,
    maxLines: Int = defaultTextElementStyle.maxLines,
    multilineAlignment: Int = defaultTextElementStyle.multilineAlignment,
    overflow: Int = defaultTextElementStyle.overflow,
    modifiers: ModifiersBuilders.Modifiers = Modifiers.Builder().build()
): LayoutElementBuilders.LayoutElement

ProtoLayout component that represents text object holding any information.

There are pre-defined typography styles that can be obtained from Materials token system in Typography.

import androidx.wear.protolayout.material3.Typography
import androidx.wear.protolayout.material3.materialScope
import androidx.wear.protolayout.material3.text

materialScope(context, deviceConfiguration) {
        text(text = "Hello Material3".prop(), typography = Typography.DISPLAY_LARGE)
    }
import androidx.wear.protolayout.TypeBuilders.StringLayoutConstraint
import androidx.wear.protolayout.TypeBuilders.StringProp
import androidx.wear.protolayout.expression.DynamicBuilders.DynamicString
import androidx.wear.protolayout.material3.Typography
import androidx.wear.protolayout.material3.materialScope
import androidx.wear.protolayout.material3.text

materialScope(context, deviceConfiguration) {
        text(
            text =
                StringProp.Builder("Static")
                    .setDynamicValue(DynamicString.constant("Dynamic"))
                    .build(),
            stringLayoutConstraint = StringLayoutConstraint.Builder("Constraint").build(),
            typography = Typography.DISPLAY_LARGE,
            color = colorScheme.tertiary,
            underline = true,
            maxLines = 5
        )
    }
Parameters
text: TypeBuilders.StringProp

The text content for this component.

stringLayoutConstraint: TypeBuilders.StringLayoutConstraint = StringLayoutConstraint.Builder(text.value).build()

The layout constraints used to correctly measure Text view size and align text when text has dynamic value.

typography: Int = defaultTextElementStyle.typography

The typography from Typography to be applied to this text. This will have predefined default value specified by each components that uses this text, to achieve the recommended look.

color: ColorBuilders.ColorProp = defaultTextElementStyle.color

The color to be applied to this text. It is recommended to use predefined default styles created by each component or getColorProp(token).

italic: Boolean = defaultTextElementStyle.italic

Whether text should be displayed as italic.

underline: Boolean = defaultTextElementStyle.underline

Whether text should be displayed as underlined.

scalable: Boolean = defaultTextElementStyle.scalable

Whether text should scale with the user font size.

maxLines: Int = defaultTextElementStyle.maxLines

The maximum number of lines that text can occupy.

multilineAlignment: Int = defaultTextElementStyle.multilineAlignment

The horizontal alignment of the multiple lines of text.

overflow: Int = defaultTextElementStyle.overflow

The overflow strategy when text doesn't have enough space to be shown.

modifiers: ModifiersBuilders.Modifiers = Modifiers.Builder().build()

The additional Modifiers for this text.

fun MaterialScope.textEdgeButton(
    onClick: ModifiersBuilders.Clickable,
    contentDescription: TypeBuilders.StringProp,
    colors: EdgeButtonColors = filled(),
    labelContent: MaterialScope.() -> LayoutElementBuilders.LayoutElement
): LayoutElementBuilders.LayoutElement

ProtoLayout Material3 component edge button that offers a single slot to take a text or similar long and wide content.

The edge button is intended to be used at the bottom of a round screen. It has a special shape with its bottom almost follows the screen's curvature. It has fixed height, and takes 1 line of text or a single icon. This button represents the most important action on the screen, and it must occupy the whole horizontal space in its position as well as being anchored to the screen bottom.

This component is not intended to be used with an image background.

import androidx.wear.protolayout.material3.materialScope
import androidx.wear.protolayout.material3.text
import androidx.wear.protolayout.material3.textEdgeButton

materialScope(context, deviceConfiguration) {
        textEdgeButton(onClick = clickable, contentDescription = "Description of a button".prop()) {
            text("Hello".prop())
        }
    }
Parameters
onClick: ModifiersBuilders.Clickable

Associated Clickable for click events. When the button is clicked it will fire the associated action.

contentDescription: TypeBuilders.StringProp

The content description to be read by Talkback.

colors: EdgeButtonColors = filled()

The colors used for this button. If not set, EdgeButtonDefaults.filled will be used as high emphasis button. Other recommended colors are EdgeButtonDefaults.filledTonal and EdgeButtonDefaults.filledVariant. If using custom colors, it is important to choose a color pair from same role to ensure accessibility with sufficient color contrast.

labelContent: MaterialScope.() -> LayoutElementBuilders.LayoutElement

The label slot for content displayed in this button. It is recommended to use default styling that is automatically provided by only calling text with the content.