Foundational layout components and surface containers for structuring app layouts. These components provide the building blocks for organizing content with proper Material3 elevation, theming, and visual hierarchy.
import androidx.compose.material3.*
import androidx.compose.material3.Surface
import androidx.compose.material3.Card
import androidx.compose.material3.OutlinedCard
import androidx.compose.material3.Scaffold
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.ExperimentalMaterial3ApiBasic Material3 surface container with elevation, shape, and color support for creating visual layers.
/**
* Material3 surface container providing foundation for other components with elevation and theming
* @param modifier Modifier to be applied to the surface
* @param shape Shape of the surface corners and borders
* @param color Background color of the surface
* @param contentColor Default color for content placed on this surface
* @param tonalElevation Elevation for color tinting (affects surface color)
* @param shadowElevation Elevation for drop shadow (affects shadow appearance)
* @param border Optional border stroke around the surface
* @param content The content to be placed on the surface
*/
@Composable
fun Surface(
modifier: Modifier = Modifier,
shape: Shape = RectangleShape,
color: Color = MaterialTheme.colorScheme.surface,
contentColor: Color = contentColorFor(color),
tonalElevation: Dp = 0.dp,
shadowElevation: Dp = 0.dp,
border: BorderStroke? = null,
content: @Composable () -> Unit
)Usage Examples:
// Basic surface
Surface {
Text("Content on surface")
}
// Elevated surface with custom shape
Surface(
modifier = Modifier.padding(16.dp),
shape = RoundedCornerShape(12.dp),
tonalElevation = 6.dp,
shadowElevation = 6.dp
) {
Column(
modifier = Modifier.padding(16.dp)
) {
Text("Elevated Content")
Text("Additional content")
}
}
// Surface with custom colors and border
Surface(
color = MaterialTheme.colorScheme.primaryContainer,
contentColor = MaterialTheme.colorScheme.onPrimaryContainer,
border = BorderStroke(1.dp, MaterialTheme.colorScheme.outline),
shape = RoundedCornerShape(8.dp)
) {
Text(
text = "Custom surface",
modifier = Modifier.padding(16.dp)
)
}Material3 card container with built-in elevation and styling for grouping related content.
/**
* Material3 card component for grouping related content with consistent elevation and styling
* @param modifier Modifier to be applied to the card
* @param shape Shape of the card corners
* @param colors Color scheme for the card in different states
* @param elevation Elevation configuration for the card shadow and tonal elevation
* @param border Optional border stroke around the card
* @param content The content to be placed inside the card (in ColumnScope)
*/
@Composable
fun Card(
modifier: Modifier = Modifier,
shape: Shape = CardDefaults.shape,
colors: CardColors = CardDefaults.cardColors(),
elevation: CardElevation = CardDefaults.cardElevation(),
border: BorderStroke? = null,
content: @Composable ColumnScope.() -> Unit
)Usage Examples:
// Basic card
Card {
Column(
modifier = Modifier.padding(16.dp)
) {
Text(
text = "Card Title",
style = MaterialTheme.typography.headlineSmall
)
Text(
text = "Card content goes here with additional details and information.",
style = MaterialTheme.typography.bodyMedium
)
}
}
// Card with custom elevation and colors
Card(
modifier = Modifier.fillMaxWidth(),
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.secondaryContainer
),
elevation = CardDefaults.cardElevation(
defaultElevation = 8.dp
)
) {
Text(
text = "Elevated colored card",
modifier = Modifier.padding(16.dp)
)
}Card variant with outline border and minimal elevation for subtle content grouping.
/**
* Material3 outlined card with border stroke and minimal elevation
* @param modifier Modifier to be applied to the card
* @param shape Shape of the card corners
* @param colors Color scheme for the card in different states
* @param elevation Elevation configuration (typically minimal for outlined cards)
* @param border Border stroke around the card
* @param content The content to be placed inside the card (in ColumnScope)
*/
@Composable
fun OutlinedCard(
modifier: Modifier = Modifier,
shape: Shape = CardDefaults.outlinedShape,
colors: CardColors = CardDefaults.outlinedCardColors(),
elevation: CardElevation = CardDefaults.outlinedCardElevation(),
border: BorderStroke = CardDefaults.outlinedCardBorder(),
content: @Composable ColumnScope.() -> Unit
)Usage Examples:
// Basic outlined card
OutlinedCard {
Column(
modifier = Modifier.padding(16.dp)
) {
Text(
text = "Outlined Card",
style = MaterialTheme.typography.headlineSmall
)
Text(
text = "This card has a border instead of elevation.",
style = MaterialTheme.typography.bodyMedium
)
}
}
// Outlined card with custom border
OutlinedCard(
border = BorderStroke(2.dp, MaterialTheme.colorScheme.primary)
) {
Text(
text = "Custom border card",
modifier = Modifier.padding(16.dp)
)
}Main app structure composable providing slots for common UI elements like app bars and floating action buttons.
/**
* Material3 scaffold providing structure for a screen with app bars, FAB, and content
* @param modifier Modifier to be applied to the scaffold
* @param topBar Content for the top app bar
* @param bottomBar Content for the bottom bar
* @param snackbarHost Host for displaying snackbars
* @param floatingActionButton Floating action button content
* @param floatingActionButtonPosition Position of the floating action button
* @param containerColor Background color of the scaffold
* @param contentColor Default content color for the scaffold
* @param contentWindowInsets Window insets to be applied to the content
* @param content Main content of the screen (receives PaddingValues for proper spacing)
*/
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Scaffold(
modifier: Modifier = Modifier,
topBar: @Composable () -> Unit = {},
bottomBar: @Composable () -> Unit = {},
snackbarHost: @Composable () -> Unit = {},
floatingActionButton: @Composable () -> Unit = {},
floatingActionButtonPosition: FabPosition = FabPosition.End,
containerColor: Color = MaterialTheme.colorScheme.background,
contentColor: Color = contentColorFor(containerColor),
contentWindowInsets: WindowInsets = ScaffoldDefaults.contentWindowInsets,
content: @Composable (PaddingValues) -> Unit
)Usage Examples:
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MyScreen() {
Scaffold(
topBar = {
TopAppBar(
title = { Text("My App") }
)
},
floatingActionButton = {
FloatingActionButton(
onClick = { /* handle FAB click */ }
) {
Icon(Icons.Default.Add, contentDescription = "Add")
}
}
) { innerPadding ->
// Screen content with proper padding
LazyColumn(
modifier = Modifier.padding(innerPadding)
) {
items(20) { index ->
Text(
text = "Item $index",
modifier = Modifier.padding(16.dp)
)
}
}
}
}
// Scaffold with bottom bar
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ScreenWithBottomBar() {
Scaffold(
topBar = {
TopAppBar(title = { Text("With Bottom Bar") })
},
bottomBar = {
NavigationBar {
NavigationBarItem(
selected = true,
onClick = { },
icon = { Icon(Icons.Default.Home, contentDescription = null) },
label = { Text("Home") }
)
NavigationBarItem(
selected = false,
onClick = { },
icon = { Icon(Icons.Default.Settings, contentDescription = null) },
label = { Text("Settings") }
)
}
}
) { innerPadding ->
Box(
modifier = Modifier
.padding(innerPadding)
.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Text("Content with top and bottom bars")
}
}
}Visual separators for organizing content sections.
/**
* Material3 horizontal divider for separating content vertically
* @param modifier Modifier to be applied to the divider
* @param thickness Thickness of the divider line
* @param color Color of the divider line
*/
@Composable
fun HorizontalDivider(
modifier: Modifier = Modifier,
thickness: Dp = DividerDefaults.Thickness,
color: Color = DividerDefaults.color,
)
/**
* Material3 vertical divider for separating content horizontally
* @param modifier Modifier to be applied to the divider
* @param thickness Thickness of the divider line
* @param color Color of the divider line
*/
@Composable
fun VerticalDivider(
modifier: Modifier = Modifier,
thickness: Dp = DividerDefaults.Thickness,
color: Color = DividerDefaults.color,
)Usage Examples:
// Horizontal divider in a list
Column {
Text("Item 1")
HorizontalDivider()
Text("Item 2")
HorizontalDivider()
Text("Item 3")
}
// Vertical divider in a row
Row(
modifier = Modifier.height(40.dp)
) {
Text("Left content")
VerticalDivider(
modifier = Modifier.padding(horizontal = 8.dp)
)
Text("Right content")
}
// Custom divider styling
HorizontalDivider(
thickness = 2.dp,
color = MaterialTheme.colorScheme.primary
)Default configurations and factory methods for card styling.
object CardDefaults {
/** Default shape for filled cards */
val shape: Shape
/** Default shape for outlined cards */
val outlinedShape: Shape
/**
* Creates default colors for filled cards
* @param containerColor Background color of the card
* @param contentColor Default content color for the card
* @param disabledContainerColor Background color when disabled
* @param disabledContentColor Content color when disabled
*/
fun cardColors(
containerColor: Color = Color.Unspecified,
contentColor: Color = Color.Unspecified,
disabledContainerColor: Color = Color.Unspecified,
disabledContentColor: Color = Color.Unspecified,
): CardColors
/**
* Creates default colors for outlined cards
* @param containerColor Background color of the outlined card
* @param contentColor Default content color for the outlined card
* @param disabledContainerColor Background color when disabled
* @param disabledContentColor Content color when disabled
*/
fun outlinedCardColors(
containerColor: Color = Color.Unspecified,
contentColor: Color = Color.Unspecified,
disabledContainerColor: Color = Color.Unspecified,
disabledContentColor: Color = Color.Unspecified,
): CardColors
/**
* Creates default elevation for filled cards
* @param defaultElevation Elevation in normal state
* @param pressedElevation Elevation when pressed
* @param focusedElevation Elevation when focused
* @param hoveredElevation Elevation when hovered
* @param draggedElevation Elevation when dragged
* @param disabledElevation Elevation when disabled
*/
fun cardElevation(
defaultElevation: Dp = 1.dp,
pressedElevation: Dp = 1.dp,
focusedElevation: Dp = 1.dp,
hoveredElevation: Dp = 3.dp,
draggedElevation: Dp = 6.dp,
disabledElevation: Dp = 0.dp,
): CardElevation
/**
* Creates default elevation for outlined cards
* @param defaultElevation Elevation in normal state (typically 0dp)
* @param pressedElevation Elevation when pressed
* @param focusedElevation Elevation when focused
* @param hoveredElevation Elevation when hovered
* @param draggedElevation Elevation when dragged
* @param disabledElevation Elevation when disabled
*/
fun outlinedCardElevation(
defaultElevation: Dp = 0.dp,
pressedElevation: Dp = 0.dp,
focusedElevation: Dp = 0.dp,
hoveredElevation: Dp = 1.dp,
draggedElevation: Dp = 6.dp,
disabledElevation: Dp = 0.dp,
): CardElevation
/**
* Default border stroke for outlined cards
*/
fun outlinedCardBorder(): BorderStroke
}Default configurations for scaffold layout.
object ScaffoldDefaults {
/** Default content window insets for scaffold */
val contentWindowInsets: WindowInsets
}Default configurations for dividers.
object DividerDefaults {
/** Default thickness for dividers */
val Thickness: Dp
/** Default color for dividers */
val color: Color
@Composable get
}interface CardColors {
/**
* Represents the container color for this card, depending on [enabled].
* @param enabled whether the card is enabled
*/
fun containerColor(enabled: Boolean): Color
/**
* Represents the content color for this card, depending on [enabled].
* @param enabled whether the card is enabled
*/
fun contentColor(enabled: Boolean): Color
}interface CardElevation {
/**
* Represents the shadow elevation used in a card, depending on [enabled] and [interactionSource].
* @param enabled whether the card is enabled
* @param interactionSource the interaction source for tracking card state
*/
@Composable
fun shadowElevation(enabled: Boolean, interactionSource: InteractionSource): State<Dp>
/**
* Represents the tonal elevation used in a card, depending on [enabled] and [interactionSource].
* @param enabled whether the card is enabled
* @param interactionSource the interaction source for tracking card state
*/
@Composable
fun tonalElevation(enabled: Boolean, interactionSource: InteractionSource): State<Dp>
}enum class FabPosition {
Start, Center, End
}interface WindowInsets {
fun getLeft(density: Density, layoutDirection: LayoutDirection): Int
fun getTop(density: Density): Int
fun getRight(density: Density, layoutDirection: LayoutDirection): Int
fun getBottom(density: Density): Int
}interface PaddingValues {
fun calculateLeftPadding(layoutDirection: LayoutDirection): Dp
fun calculateTopPadding(): Dp
fun calculateRightPadding(layoutDirection: LayoutDirection): Dp
fun calculateBottomPadding(): Dp
}interface Shape {
fun createOutline(
size: Size,
layoutDirection: LayoutDirection,
density: Density
): Outline
}
object RectangleShape : Shape