Window Breakpoints Window breakpoint utilities for building adaptive Compose layouts.
View Markdown
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.widthIn
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.composables.uripainter.rememberUriPainter
import com.composeunstyled.CrossAxisAlignment
import com.composeunstyled.ProvideWindowWidthBreakpoints
import com.composeunstyled.Stack
import com.composeunstyled.StackOrientation
import com.composeunstyled.Text
import com.composeunstyled.WidthBreakpoint
import com.composeunstyled.WindowWidthBreakpoints
import com.composeunstyled.buildModifier
import com.composeunstyled.currentWindowWidthBreakpoint
import com.composeunstyled.demo.colors
import com.composeunstyled.demo.contentToken
import com.composeunstyled.demo.inputBackgroundToken
import com.composeunstyled.demo.mutedContentToken
import com.composeunstyled.demo.surfaceToken
import com.composeunstyled.theme.Theme
private val Compact = WidthBreakpoint ( "compact" )
private val Medium = WidthBreakpoint ( "medium" )
private val Expanded = WidthBreakpoint ( "expanded" )
private val DemoWidthBreakpoints = WindowWidthBreakpoints {
Compact startsAt 0 .dp
Medium startsAt 600 .dp
Expanded startsAt 840 .dp
}
@Preview
@Composable
fun BreakpointsDemo () {
ProvideWindowWidthBreakpoints (DemoWidthBreakpoints) {
val widthBreakpoint = currentWindowWidthBreakpoint ()
val imagePainter = rememberUriPainter (
"https://images.unsplash.com/photo-1500530855697-b586d89ba3ee" +
"?auto=format&fit=crop&w=1200&q=80" ,
)
Box (
modifier = Modifier. fillMaxSize (),
contentAlignment = Alignment.Center,
) {
Stack (
modifier = Modifier
. widthIn (max = if (widthBreakpoint isAtLeast Expanded) 860 .dp else 360 .dp)
. background (Theme[colors][surfaceToken])
. border ( 1 .dp, Theme[colors][contentToken])
. padding ( 14 .dp),
orientation = if (widthBreakpoint isAtLeast Expanded) {
StackOrientation.Horizontal
} else {
StackOrientation.Vertical
},
crossAxisAlignment = CrossAxisAlignment.Start,
spacing = 18 .dp,
) {
Image (
painter = imagePainter,
contentDescription = null ,
contentScale = ContentScale.Crop,
modifier = Modifier
. background (Theme[colors][inputBackgroundToken]) then buildModifier {
if (widthBreakpoint isAtLeast Expanded) {
add (Modifier. size (width = 320 .dp, height = 280 .dp))
} else {
add (Modifier. fillMaxWidth (). height ( 280 .dp))
}
},
)
Stack (
modifier = Modifier then buildModifier {
if (widthBreakpoint isAtLeast Expanded) {
add (Modifier. weight ( 1f ))
} else {
add (Modifier. fillMaxWidth ())
}
},
orientation = StackOrientation.Vertical,
spacing = 12 .dp,
) {
Text (
text = "Adaptive layouts" ,
color = Theme[colors][contentToken],
fontSize = 24 .sp,
lineHeight = 30 .sp,
)
Text (
text = "This card switches from vertical to horizontal at ${Expanded.name}" ,
color = Theme[colors][mutedContentToken],
fontSize = 15 .sp,
lineHeight = 22 .sp,
)
}
}
}
}
} Show Code
Define custom width and/or height breakpoints.
Build responsive layouts around named semantics instead of copy-pasting dimensions.
Emit new state only when the resolved breakpoint changes, not on every window resize.
implementation ( "com.composables:composeunstyled-breakpoints:2.10.0" )
val Compact = WidthBreakpoint ( "compact" )
val Medium = WidthBreakpoint ( "medium" )
val widthBreakpoints = WindowWidthBreakpoints {
Compact startsAt 0 .dp
Medium startsAt 600 .dp
}
ProvideWindowWidthBreakpoints (widthBreakpoints) {
val widthBreakpoint = currentWindowWidthBreakpoint ()
}
WidthBreakpoint/HeightBreakpoint define a named breakpoint.
WindowWidthBreakpoints/WindowHeightBreakpoints define the minimum window size where each breakpoint
starts.
Every breakpoint scale must include one breakpoint that starts at 0.dp.
ProvideWindowWidthBreakpoints/ProvideWindowHeightBreakpoints make one breakpoint scale available
to their content scope.
ProvideWindowBreakpoints makes both width and height breakpoint scales available to its content
scope.
currentWindowWidthBreakpoint()/currentWindowHeightBreakpoint() return a new resolved breakpoint
only when the current window crosses into another breakpoint.
Define the window widths your layout should respond to using WindowWidthBreakpoints.
Then use ProvideWindowWidthBreakpoints near the root of your app to make the current breakpoint available down the UI tree.
Use currentWindowWidthBreakpoint() to access the currently resolved breakpoint:
val Compact = WidthBreakpoint ( "compact" )
val Medium = WidthBreakpoint ( "medium" )
val Expanded = WidthBreakpoint ( "expanded" )
val widthBreakpoints = WindowWidthBreakpoints {
Compact startsAt 0 .dp
Medium startsAt 600 .dp
Expanded startsAt 840 .dp
}
ProvideWindowWidthBreakpoints (widthBreakpoints) {
val widthBreakpoint = currentWindowWidthBreakpoint ()
val expanded = widthBreakpoint isAtLeast Expanded
if (expanded) {
BasicText ( "Expanded layout" )
} else {
BasicText ( "Compact layout" )
}
} Show Code
Use ProvideWindowHeightBreakpoints with currentWindowHeightBreakpoint() when layout behavior
depends on available height:
val Short = HeightBreakpoint ( "short" )
val Tall = HeightBreakpoint ( "tall" )
val heightBreakpoints = WindowHeightBreakpoints {
Short startsAt 0 .dp
Tall startsAt 720 .dp
}
ProvideWindowHeightBreakpoints (heightBreakpoints) {
val heightBreakpoint = currentWindowHeightBreakpoint ()
val canShowDetails = heightBreakpoint isAtLeast Tall
} Show Code
Parameter
Type
Description
name
String
Parameter
Type
Description
name
String
Parameter
Type
Description
content
WindowWidthBreakpointsBuilder.() -> Unit
Parameter
Type
Description
content
WindowHeightBreakpointsBuilder.() -> Unit
Parameter
Type
Description
value
WidthBreakpoint
name
String
Parameter
Type
Description
value
HeightBreakpoint
name
String
Parameter
Type
Description
width
WindowWidthBreakpoints
height
WindowHeightBreakpoints
content
() -> Unit
Parameter
Type
Description
breakpoints
WindowWidthBreakpoints
content
() -> Unit
Parameter
Type
Description
breakpoints
WindowHeightBreakpoints
content
() -> Unit
Parameter
Type
Description
returns
ResolvedWidthBreakpoint
Parameter
Type
Description
returns
ResolvedHeightBreakpoint