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

AppCard

Android

Component in Wear Material 3 Compose

Opinionated Wear Material 3 [Card] that offers a specific 5 slot layout to show information about an application, e.g. a notification. AppCards are designed to show interactive elements from multiple applications. They will typically be used by the system UI, e.g. for showing a list of notifications from different applications. However it could also be adapted by individual application developers to show information about different parts of their application.

The first row of the layout has three slots, 1) a small optional application [Image] or [Icon] of size [CardDefaults.AppImageSize]x[CardDefaults.AppImageSize] dp, 2) an application name (emphasised with the [CardColors.appColor()] color), it is expected to be a short start aligned [Text] composable, and 3) the time that the application activity has occurred which will be shown on the top row of the card, this is expected to be an end aligned [Text] composable showing a time relevant to the contents of the [Card].

The second row shows a title, this is expected to be a single row of start aligned [Text].

The rest of the [Card] contains the content which can be either [Text] or an [Image]. If the content is text it can be single or multiple line and is expected to be Top and Start aligned.

If more than one composable is provided in the content slot it is the responsibility of the caller to determine how to layout the contents, e.g. provide either a row or a column.

Last updated:

Installation

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

Overloads

@Composable
fun AppCard(
    onClick: () -> Unit,
    appName: @Composable RowScope.() -> Unit,
    title: @Composable RowScope.() -> Unit,
    modifier: Modifier = Modifier,
    onLongClick: (() -> Unit)? = null,
    onLongClickLabel: String? = null,
    enabled: Boolean = true,
    shape: Shape = CardDefaults.shape,
    colors: CardColors = CardDefaults.cardColors(),
    border: BorderStroke? = null,
    contentPadding: PaddingValues = CardDefaults.ContentPadding,
    interactionSource: MutableInteractionSource? = null,
    appImage: @Composable (RowScope.() -> Unit)? = null,
    time: @Composable (RowScope.() -> Unit)? = null,
    content: @Composable ColumnScope.() -> Unit,
)

Parameters

namedescription
onClickWill be called when the user clicks the card
appNameA slot for displaying the application name, expected to be a single line of start aligned text of [Typography.labelSmall]
titleA slot for displaying the title of the card, expected to be one or two lines of start aligned text of [Typography.titleMedium]
modifierModifier to be applied to the card
onLongClickCalled when this card is long clicked (long-pressed). When this callback is set, [onLongClickLabel] should be set as well.
onLongClickLabelSemantic / accessibility label for the [onLongClick] action.
enabledControls the enabled state of the card. When false, this card will not be clickable and there will be no ripple effect on click. Wear cards do not have any specific elevation or alpha differences when not enabled - they are simply not clickable.
shapeDefines the card's shape. It is strongly recommended to use the default as this shape is a key characteristic of the Wear Material Theme
colors[CardColors] that will be used to resolve the colors used for this card in different states. See [CardDefaults.cardColors].
borderA BorderStroke object which is used for drawing outlines.
contentPaddingThe spacing values to apply internally between the container and the content
interactionSourcean optional hoisted [MutableInteractionSource] for observing and emitting [Interaction]s for this card. You can use this to change the card's appearance or preview the card in different states. Note that if null is provided, interactions will still happen internally.
appImageA slot for a small ([CardDefaults.AppImageSize]x[CardDefaults.AppImageSize] ) [Image] associated with the application.
timeA slot for displaying the time relevant to the contents of the card, expected to be a short piece of end aligned text of [Typography.labelSmall].
contentThe main slot for a content of this card

Code Examples

AppCardSample

@Composable
fun AppCardSample() {
    AppCard(
        onClick = { /* Do something */ },
        appName = { Text("App name") },
        title = { Text("Card title") },
        time = { Text("now") },
    ) {
        Text("Card content")
    }
}

AppCardWithIconSample

@Composable
fun AppCardWithIconSample() {
    AppCard(
        onClick = { /* Do something */ },
        appName = { Text("App name") },
        appImage = {
            Icon(
                painter = painterResource(id = android.R.drawable.star_big_off),
                contentDescription = "Star icon",
                modifier =
                    Modifier.size(CardDefaults.AppImageSize)
                        .wrapContentSize(align = Alignment.Center),
            )
        },
        title = { Text("Card title") },
        time = { Text("now") },
    ) {
        Text("Card content")
    }
}

AppCardWithImageSample

@Composable
fun AppCardWithImageSample() {
    val configuration = LocalConfiguration.current
    // Add padding to the end of the image in order to maintain the correct proportions
    // between the image and the card.
    val imageEndPaddingDp = (0.15f * configuration.screenWidthDp).dp
    AppCard(
        onClick = { /* Do something */ },
        appName = { Text("App name") },
        appImage = {
            Icon(
                painter = painterResource(id = android.R.drawable.star_big_off),
                contentDescription = "Star icon",
                modifier =
                    Modifier.size(CardDefaults.AppImageSize)
                        .wrapContentSize(align = Alignment.Center),
            )
        },
        title = { Text("With image") },
        time = { Text("now") },
    ) {
        Spacer(modifier = Modifier.height(4.dp))
        Row(modifier = Modifier.fillMaxWidth()) {
            Image(
                modifier =
                    Modifier.weight(1f).aspectRatio(16f / 9f).clip(RoundedCornerShape(16.dp)),
                painter = painterResource(id = R.drawable.card_content_image),
                contentScale = ContentScale.Crop,
                contentDescription = null
            )
            Spacer(modifier = Modifier.width(imageEndPaddingDp))
        }
    }
}

OutlinedAppCardSample

@Composable
fun OutlinedAppCardSample() {
    AppCard(
        onClick = { /* Do something */ },
        appName = { Text("App name") },
        appImage = {
            Icon(
                Icons.Filled.Favorite,
                contentDescription = "Favorite icon",
                modifier = Modifier.size(CardDefaults.AppImageSize)
            )
        },
        title = { Text("App card") },
        time = { Text("now") },
        colors = CardDefaults.outlinedCardColors(),
        border = CardDefaults.outlinedCardBorder(),
    ) {
        Text("Card content")
    }
}
by @alexstyl