22 March 2023
Posted by Jolanda Verhoef, Android Developer Relations Engineer
Today, as part of the Compose March ‘23 Bill of Materials, we’re releasing version 1.4 of Jetpack Compose, Android's modern, native UI toolkit that is used by apps such as Booking.com and Airbnb. This release contains new features like Pager and Flow Layouts, and new ways to style your text, such as hyphenation and line-break behavior. It also improves the performance of modifiers and fixes a number of bugs.
Compose now includes out-of-the-box support for vertical and horizontal paging between different content. Using VerticalPager or HorizontalPager enables similar functionality to the ViewPager in the view system. However, just like the benefits of using LazyRow and LazyColumn, you no longer need to create an adapter or fragments! You can simply embed a composable inside the Pager:
// Display 10 items
HorizontalPager(pageCount = 10) { page ->
// Your specific page content, as a composable:
Text(
text = "Page: $page",
modifier = Modifier.fillMaxWidth()
)
} |
These composables replace the implementation in the Accompanist library. If you already use the Accompanist implementation, check out the migration guide. See the Pager documentation for more information.
FlowRow and FlowColumn provide an efficient and compact way to lay out items in a container when the size of the items or the container are unknown or dynamic. These containers allow the items to flow to the next row in the FlowRow or next column in the FlowColumn when they run out of space. These flow layouts also allow for dynamic sizing using weights to distribute the items across the container.
Here’s an example that implements a list of filters for a real estate app:
@Composable
fun Filters() {
val filters = listOf(
"Washer/Dryer", "Ramp access", "Garden", "Cats OK", "Dogs OK", "Smoke-free"
)
FlowRow(
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
filters.forEach { title ->
var selected by remember { mutableStateOf(false) }
val leadingIcon: @Composable () -> Unit = { Icon(Icons.Default.Check, null) }
FilterChip(
selected,
onClick = { selected = !selected },
label = { Text(title) },
leadingIcon = if (selected) leadingIcon else null
)
}
}
} |
The major internal Modifier refactor we started in the October release has continued, with the migration of multiple foundational modifiers to the new Modifier.Node architecture. This includes graphicsLayer, lower level focus modifiers, padding, offset, and more. This refactoring should bring performance improvements to these APIs, and you don't have to change your code to receive these benefits. Work on this continues, and we expect even more gains in future releases as we migrate Modifiers outside of the ui module. Learn more about the rationale behind the changes in the ADS talk Compose Modifiers deep dive.
Along with various performance improvements, API stabilizations, and bug fixes, the compose-text 1.4 release brings support for the latest emoji version, including backwards compatibility with older Android versions 🎉🙌. Supporting this requires no changes to your application. If you’re using a custom emoji solution, make sure to check out PlatformTextStyle(emojiSupportMatch).
In addition, we’ve addressed one of the main pain points of using TextField. In some scenarios, a text field inside a scrollable Column or LazyColumn would be obscured by the on-screen keyboard after being focused. We re-worked core parts of scroll and focus logic, and added key APIs like PinnableContainer to fix this bug.
Finally, we added a lot of new customization options to Text and its TextStyle:
Marquee text using outline with shapes stamped on it using the drawStyle API. |
We’re grateful for all of the bug reports and feature requests submitted to our issue tracker - they help us to improve Compose and build the APIs you need. Continue providing your feedback, and help us make Compose better!
Wondering what’s next? Check out our updated roadmap to see the features we’re currently thinking about and working on. We can’t wait to see what you build next!