一、Compose 介绍
google 在 07月28日 发布了compose 1.0 正式版,代表着其api结构已经趋于稳定,作为一个合格(天天划水)的android developer,也是时候开始了解它了。
以下内容引用自官网内容 Jetpack Compose 是一个适用于 Android 的新式声明性界面工具包。Compose 提供声明性 API,让您可在不以命令方式改变前端视图的情况下呈现应用界面,从而使编写和维护应用界面变得更加容易。
二、Compose 创建
1.新建应用
- 下载安装 Android Studio Arctic Fox,以便于在
Jetpack Compose 进行开发时获得最佳体验 - 创建应用
New Project 选择 Empty Compose Activity ,然后Next ,在填写好相关信息后Finish 进入应用主界面,等待构建完成。 - 在手机/模拟器上运行你的第一个
Compose
至此,compose 创建完成,工具下载及应用构建建议科学上网。
三、查看初始 Compose 应用结构
一个新建的Compose 应用内包含了一个MainActivity.kt ,以及ui.theme 包内颜色、主题等配置文件
1. MainActivity
1.1. 父类
MainActivity 继承自 ComponentActivity ,ComponentActivity 又继承自 Activity ,说明View 还是通过setContentView() 加载。
1.2. onCreate() 方法
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Compose_oneTheme {
// A surface container using the 'background' color from the theme
Surface(color = MaterialTheme.colors.background) {
Greeting()
}
}
}
}
方法内 setContent{} 就比较陌生了,通过源码可以看到setContent() 是ComponentActivity 的一个拓展方法,其中的content 参数需要传入一个由@Composable 注解的函数,值得注意的是@Composable 并非传统意义上的注解处理器,Compose 在 Kotlin 编译器的类型检测与代码生成阶段依赖 Kotlin 编译器插件工作,所以无需注解处理器即可使用 Compose 。
@Composable 的作用更像一个关键字,比如 suspend ,@Composable 与其工作方式相同:它可以改变函数类型。重点是,当使用 @Composable 注解一个函数类型时,会导致它类型的改变:未被注解的相同函数类型与注解后的类型互不兼容。源码如下
public fun ComponentActivity.setContent(
parent: CompositionContext? = null,
content: @Composable () -> Unit
) {
val existingComposeView = window.decorView
.findViewById<ViewGroup>(android.R.id.content)
.getChildAt(0) as? ComposeView
if (existingComposeView != null) with(existingComposeView) {
setParentCompositionContext(parent)
setContent(content)
} else ComposeView(this).apply {
// Set content and parent **before** setContentView
// to have ComposeView create the composition on attach
setParentCompositionContext(parent)
setContent(content)
// Set the view tree owners before setting the content view so that the inflation process
// and attach listeners will see them already present
setOwners()
setContentView(this, DefaultActivityContentLayoutParams)
}
}
可以发现,在setContent 内部,程序会去寻找Activity 的根布局,若未找到则创建一个,然后将由@Conposable 注解函数内的声明式布局创建。
1.3. Greeting() 方法
@Composable
fun Greeting() {
Text(text = "Hello,Jetpack Compose!")
}
该方法由@Composable 注解(最终需要传入到setContent 方法中的都需要注解,不论多少层),其内容则是要创建的视图内容的具体声明描述了。
1.4. DefaultPreview() 方法
@Preview(showBackground = true )
@Composable
fun DefaultPreview() {
Compose_oneTheme {
Greeting()
}
}
值得注意的是 DefaultPreview() 除了添加了@Composable 注解外,还添加了@Preview , @Preview 注解的方法可以在不运行App的情况下就可以确认布局的情况。 如下图所示
@Preview 的注解中比较常用的参数如下:
name: String : 为该Preview命名,该名字会在布局预览中显示。showBackground: Boolean : 是否显示背景,true为显示。backgroundColor: Long : 设置背景的颜色。showDecoration: Boolean : 是否显示Statusbar和Toolbar,true为显示。group: String : 为该Preview设置group名字,可以在UI中以group为单位显示。fontScale: Float : 可以在预览中对字体放大,范围是从0.01。- widthDp: Int: 在Compose中渲染的最大宽度,单位为dp。heightDp: Int : 在Compose中渲染的最大高度,单位为dp。
注意:强烈建议您不要向生产函数(即使其不带参数)添加 @Preview 注释,而是编写一个封装函数并在其中添加 @Preview 注释。 这便是 DefaultPreview 存在的意义,详见 developer.android.google.cn/jetpack/com…
2. ui.theme 包
包内包含了Color.kt 、Shape.kt 、Type.kt 、Theme.kt ,分别是颜色、形状、类型、主题的描述文件,可以理解为代替了传统android 项目内res 内的xml 配置文件;在后面的文章中会专门讲到。
四、在现有应用中使用 Compose
1. 添加依赖
buildscript {
? ? ...
? ? dependencies {
? ? ? ? classpath "com.android.tools.build:gradle:7.0.0"
? ? ? ? ...
? ? }
}
- 将
Kotlin 升级至 1.5.21 - 配置
Gradle
需要将应用的最低 API 级别设置为 21 或更高级别,并在应用的?build.gradle ?文件中启用 Jetpack Compose,如下所示。另外还要设置 Kotlin 编译器插件的版本。
android {
? ? defaultConfig {
? ? ? ? ...
? ? ? ? minSdkVersion 21
? ? }
? ? buildFeatures {
? ? ? ? // Enables Jetpack Compose for this module
? ? ? ? compose true
? ? }
? ? ...
? ? // Set both the Java and Kotlin compilers to target Java 8.
? ? compileOptions {
? ? ? ? sourceCompatibility JavaVersion.VERSION_1_8
? ? ? ? targetCompatibility JavaVersion.VERSION_1_8
? ? }
? ? kotlinOptions {
? ? ? ? jvmTarget = "1.8"
? ? }
? ? composeOptions {
? ? ? ? kotlinCompilerExtensionVersion '1.0.1'
kotlinCompilerVersion '1.5.21'
? ? }
}
dependencies {
? ? // Integration with activities
? ? implementation 'androidx.activity:activity-compose:1.3.1'
? ? // Compose Material Design
? ? implementation 'androidx.compose.material:material:1.0.1'
? ? // Animations
? ? implementation 'androidx.compose.animation:animation:1.0.1'
? ? // Tooling support (Previews, etc.)
? ? implementation 'androidx.compose.ui:ui-tooling:1.0.1'
? ? // Integration with ViewModels
? ? implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:1.0.0-alpha07'
? ? // UI Tests
? ? androidTestImplementation 'androidx.compose.ui:ui-test-junit4:1.0.1'
}
2. 在XML中使用Compopse
在xml 中可以将 ComposeView 作为一个普通的view 来使用,然后在代码内通过setContent 方法注入compose
<...>
? ? <!-- Other content -->
? ? <androidx.compose.ui.platform.ComposeView
? ? ? ? android:id="@+id/greeting"
? ? ? ? android:layout_width="match_parent"
? ? ? ? android:layout_height="wrap_content"/>
</...>
class MyActivity : AppCompatActivity() {
? ? override fun onCreate(savedInstanceState: Bundle?) {
? ? ? ? super.onCreate(savedInstanceState)
? ? ? ? // ...
? ? ? ? val greeting = findViewById<ComposeView>(R.id.greeting)
? ? ? ? greeting.setContent {
? ? ? ? ? ? MdcTheme { // or AppCompatTheme
? ? ? ? ? ? ? ? Greeting()
? ? ? ? ? ? }
? ? ? ? }
? ? }
}
@Composable
private fun Greeting() {
? ? Text(
? ? ? ? text = stringResource(R.string.greeting),
? ? ? ? style = MaterialTheme.typography.h5,
? ? ? ? modifier = Modifier
? ? ? ? ? ? .fillMaxWidth()
? ? ? ? ? ? .padding(horizontal = dimensionResource(R.dimen.margin_small))
? ? ? ? ? ? .wrapContentWidth(Alignment.CenterHorizontally)
? ? )
}
3. 在Activity/Fragment...中使用Compopse
可参考新建compose 应用内的实现方式,直接使用setContent 方法。
五、最后
好记性不如烂笔头,初识 Jetpack Compose 系列是我自己的学习笔记,在加深知识巩固的同时,也可以锻炼一下写作技能。文章中的内容仅作参考,如有问题请留言指正。
?为了方便大家更好的学习Kotlin,我特地将下面的文档整合到Github中,希望能帮助到感兴趣的读者。
项目地址:Github
|