概述 Jetpack Compose 是一个用于构建原生 Android UI 的工具包,它基于声明式的编程模型,因此可以简单地描述 UI 的外观,而 Compose 则负责其余的工作。当状态发生改变时,UI 将自动更新。由于 Compose 基于 Kotlin 构建,因此可以与 Java 互操作,并且可以直接访问所有 Android 和 Jetpack API。它与现有的 UI 工具包也是完全兼容的,因此可以混合原来的 View 和现在新的 View,并且从一开始就使用 Material 和动画进行设计。
基础使用 可以直接创建一个支持 Compose 的工程,也可以在现有工程上添加依赖和配置使其支持 Compose 功能。使用正式版的 AS 时会提示: Jetpack Compose is a preview feature, and support for Compose is included only in Canary(金丝雀) versions of Android Studio.
该功能只是一个预览功能,需要在灰度版本里才能支持。
根项目构建脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 buildscript { repositories { maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' } } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } allprojects { repositories { maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' } } }
app模块构建脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 plugins { id 'com.android.application' id 'kotlin-android' } android { defaultConfig { minSdkVersion 21 } buildFeatures { compose true } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = '1.8' } } dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation 'androidx.core:core-ktx:1.3.2' implementation 'androidx.ui:ui-tooling:0.1.0-dev02' implementation 'androidx.ui:ui-layout:0.1.0-dev02' implementation 'androidx.ui:ui-material:0.1.0-dev02' }
HelloWorld
1 2 3 4 5 6 7 8 class MainActivity : AppCompatActivity () { override fun onCreate (savedInstanceState: Bundle ?) { super .onCreate(savedInstanceState) setContent { Text("Hello World!" ) } } }
Composable函数 Jetpack Compose 是围绕 composable 函数来构建的,这些函数使你可以通过描述应用程序的形状和数据依赖,以编程方式定义应用程序的UI,而不是着眼于 UI 的构建过程。要创建 composable 函数,只需要在函数名前面加上一个 @composable 注解即可,上面的 Text 就是一个 composable 函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 class MainActivity : AppCompatActivity () { override fun onCreate (savedInstanceState: Bundle ?) { super .onCreate(savedInstanceState) setContent { Greeting("World" ) } } } @Composable fun Greeting (name: String ) { Text(text = "Hello $name !" ) }
在编译过程中,Compose 会对于加了 @Composable 注解的函数做出不一样的编译逻辑,让这些函数可以在 App 运行时变成我们的界面,正确地显示。这与注解处理器不同,注解处理器会修改 Kotlin 代码,而编译器插件是直接修改字节码的输出逻辑。
@Composable 之所以要用注解而不是跟协程一样增加 suspend 关键字,是因为它是 Android 平台的特性而不是 Kotlin 语言层面的功能。
命令式和声明式UI 所谓声明式 UI,指的就是你只需要把界面给「声明」出来,而不需要手动更新。当我们将界面状态通过变量传递给 Compose 组件时,Compose 里的界面元素会对依赖的数据自动进行订阅,这样数据改变了,界面马上就跟着变。
DataBinding 并不能做到声明式 UI,它是一种数据绑定。
源码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 fun Activity.setContent (content: @Composable () () -> Unit ) : CompositionContext? { val composeView = window.decorView.findViewById<ViewGroup>(android.R.id.content) .getChildAt(0 ) as ? AndroidComposeView ?: AndroidComposeView(this ).also { setContentView(it) } val coroutineContext = Dispatchers.Main return Compose.composeInto(composeView.root, this ) { WrapWithAmbients(composeView, this , coroutineContext) { content() } } }