I O Compose vs. XML @Composable fun ComposeList(items: List<String>) { LazyColumn { items(items) { item -> ListItem(text = item) } } } @Composable fun ListItem(text: String) { // Render a single list item } Compose XML <ListView android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="match_parent" /> class MyAdapter(private val items: List<String>) : RecyclerView.Adapter<MyAdapter.ViewHolder>() { override fun onCreateViewHolder(parent: ViewGroup, viewType: .. class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { .. recyclerView.layoutManager = LinearLayoutManager(this) recyclerView.adapter = MyAdapter(items)
I O Jetpack Compose Histories 80๎ Compose Compiler 125๎ Compose UI & Runtime versions have been released. Jetpack Compose continues to evolve with steady performance enhancements.
I O Understanding Stability Stable vs. Unstable Stable data class User( val id: Int, val name: String, ) Unstable data class User( val id: Int, var name: String, )
I O Understanding Stability Stable vs. Unstable Stable data class User( val id: Int, val name: String, ) Unstable data class User( val id: Int, var name: String, ) data class User( val id: Int, val images: List<String>, )
I O Understanding Stability Stable vs. Unstable Stable data class User( val id: Int, val name: String, ) @Immutable data class User( val id: Int, val images: List<String>, ) Unstable data class User( val id: Int, var name: String, ) data class User( val id: Int, val images: List<String>, )
I O Stability Annotations ๎Immutable public data class User( public val id: String, public val nickname: String, public val profileImage: String, ) Stable
I O Stability Annotations ๎Immutable public data class User( public val id: String, public val nickname: String, public val profileImage: String, ) Stable Unstable public data class User( public val id: String, public val nickname: String, public val profileImages: List<String>, )
I O Stability Annotations ๎Immutable public data class User( public val id: String, public val nickname: String, public val profileImage: String, ) Stable Unstable public data class User( public val id: String, public val nickname: String, public val profileImages: List<String>, ) @Immutable public data class User( public val id: String, public val nickname: String, public val profileImages: List<String>, )
I O Stability Annotations ๎Stable ๎Stable interface State<out T> { val value: T } ๎Stable interface MutableState<T> : State<T> { override var value: T operator fun component1(): T operator fun component2(): ๎T) โ Unit }
I O Stability Annotations ๎Immutable vs. Stable ๎Immutable public data class User( public val id: String, public val nickname: String, public val profileImages: List<String>, ) ๎Immutable ๎Stable ๎Stable interface UiState<T ๎ Result<T>> { val value: T? val exception: Throwable? val hasSuccess: Boolean get() = exception == null }
I O Stabilize Composable Functions Immutable Collections internal var mutableUserList: MutableList<User> = mutableListOf() public val userList: List<User> = mutableUserList @Composable fun Profile(images: List<String>) { .. } Unstable
I O Stabilize Composable Functions Immutable Collections Compose Compiler: KnownStableConstructs.kt object KnownStableConstructs { val stableTypes = mapOf( // Guava "com.google.common.collect.ImmutableList" to 0b1, "com.google.common.collect.ImmutableSet" to 0b1, .. // Kotlinx immutable "kotlinx.collections.immutable.ImmutableCollection" to 0b1, "kotlinx.collections.immutable.ImmutableList" to 0b1, .. ) }
I O Stabilize Composable Functions Wrapper Class ๎Immutable data class ImmutableUserList( val user: List<User>, val expired: java.time.LocalDateTime, ) ๎Composable fun UserAvatars( stable modifier: Modifier, stable userList: ImmutableUserList, ) ๎Composable fun UserAvatars( stable modifier: Modifier, unstable user: List<User>, unstable expired: java.time.LocalDateTime, ) Non-Skippable Skippable
I O Stabilize Composable Functions Stability Configuration File kotlinOptions { freeCompilerArgs += listOf( "๎P", "plugin:androidx.compose.compiler.plugins.kotlin:stabilityConfigurationPath=" + "${project.absolutePath}/compose_compiler_config.conf" ) } compose_compiler_config.conf // Consider LocalDateTime stable java.time.LocalDateTime // Consider kotlin collections stable kotlin.collections.* // Consider my datalayer and all submodules stable com.datalayer.** // Consider my generic type stable based off it's first type parameter only com.example.GenericClass<*,_> // Consider our data models stable since we always use immutable classes com.google.samples.apps.nowinandroid.core.model.data.*