Compose - 基本使用

一、概念

1.1 Compose优势

  • 由一个个可以组合的Composable函数拼成界面,方便维护和复用。
  • 布局模型不允许多次测量,提升了性能。
  • Compose可以和View互操作(相互包含对方)。

1.2 声明式UI

APP展示的数据绝大多数不是静态数据而是会实时更新,传统的命令式UI写法更新界面繁琐且容易同步错误。Compose会对界面用到的数据自动进行订阅(属性委托),当数据变化时界面会自动更新(同为数据和界面关联,databinding只能更新组件的值,Compose可以控制组件切换显示)。

|-------|----------------------------------------------------------------------------------------|
| 声明式UI | 只需要把界面写出来,不需要再手动写代码去刷新界面。重新生成整个屏幕界面成本高昂,Compose生成界面后,数据变动只执行必要的重组(局部刷新)。 |
| 命令式UI | xml写的界面,当数据变了就需要Java/Kotlin手动(命令指挥)刷新,即 findViewById( ) 遍历树拿到控件,再 setText( ) 设置数据改变节点。 |

二、使用

2.1 添加依赖

查看官方最新版本

兼容性对应关系

BoM物料清单:随着依赖的库越来越多,为了保证不同库不同版本之间能正常配合,引入依赖时具体的库不指定版本,而是由BoM管理。

最低版本:Kotlin ≥ 1.5.10、Android ≥ 5.0(API21)、AndroidStudio ≥ Arctic Fox 2020.3.1。

Groovy 复制代码
android {
    buildFeatures {
        compose true    //启用Compose功能
    }
    composeOptions {
        //见上方链接,此处定义的Kotlin编译器扩展版本需要对应兼容的Kotlin版本
        kotlinCompilerExtensionVersion = "1.4.2"
    }
}
Groovy 复制代码
dependencies {
    //Compose
    def composeBom = platform('androidx.compose:compose-bom:2023.01.00')
    implementation composeBom
    androidTestImplementation composeBom
    //主题
    implementation 'androidx.compose.material3:material3'
    //预览
    implementation 'androidx.compose.ui:ui-tooling-preview'
    debugImplementation 'androidx.compose.ui:ui-tooling'
    //UI测试
    androidTestImplementation 'androidx.compose.ui:ui-test-junit4'
    debugImplementation 'androidx.compose.ui:ui-test-manifest'
    //可选搭配
    implementation 'androidx.activity:activity-compose:1.7.0'   //Activity
    implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1'   //ViewModel
    implementation 'androidx.compose.runtime:runtime-livedata'  //LiveData
    implementation 'androidx.constraintlayout:constraintlayout-compose:1.0.1'   //ConstraintLayout
    implementation 'io.coil-kt:coil-compose:2.3.0' //Coil
    implementation 'androidx.navigation:navigation-compose:2.5.3'   //Navigation
    //    implementation "com.google.accompanist:accompanist-appcompat-theme:0.28.0"  //AppCompatTheme
}

2.2 Activity调用

需要继承的是ComponentActivity,使用 setContent { } 替换 setContentView( )。

Kotlin 复制代码
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {    // 设置显示内容,用来替换setContentView
            Show("Hello World!")
        }
    }
}

三、预览效果 @Preview

使用该注解的组合函数可以在AndroidStudio右上角直接预览效果和点击交互,也能直接部署该预览在真机或模拟器上查看效果和点击交互。AS按出prev能快速打出模板代码。

  • 只能修饰无参可组合函数:可以用无参函数包裹有参函数传个值给它来预览。

|------------------|--------------------------------------------------------|
| neme | 设置的该名称会在布局预览中显示。 |
| showBackground | 预览默认是不显示背景色的,设为true才显示。 |
| backgroundColor | 设置背景颜色。 |
| showDecoration | 是否显示Statusbar和Toolbar,true为显示。 |
| group | 为该Preview设置group名字,可以在UI中以group为单位显示。 |
| fontScale | 可以在预览中对字体放大,范围是从0.01。 |
| showSystemUi | 设为 true 显示系统界面(状态栏,屏幕按键)。 |
| widthDp heightDp | 预览区域的大小(单位为dp),和 showSystemUI 互斥。 |
| device | 预览机型(Devices.DESKTOP、Devices.PIXEL_4、Devices.NEXUS_6)。 |
| apiLevel | 预览不同版本的效果 |

Kotlin 复制代码
@Preview
@Composable
fun WrapperShow() {
    Show("Word")    //包裹一层再传个值
}

@Composable
fun Show(str: String) {
    Text(text = "Hello ${str}!")
}

3.1 对屏幕级组合函数使用预览失败

原因:系统无法正确实例化 ViewModel 因为它依赖于运行中的 Android 系统,而预览系统只有UI相关代码。

解决:抽离出一个只依赖于状态类的组合函数。

Kotlin 复制代码
@Composable
fun DemoScreen(
    viewModel: DemoViewModel = viewModel(),
){
    DemoContent(viewModel.demoState)
}

@Composable
private fun DemoContent(
    demoState:DemoState
){
    /* ... */
}

@Composable
@Preview
private fun PreviewDemoContent(){
    DemoContent(remember{DemoState()})
}

3.2 引用了Android运行时才能获取的类预览失败

原因:像 Application 类在预览系统中是不存在的。

解决:通过 LocalInspectionMode.current 来判断当前是否运行于预览系统中,true就使用固定字符串。

Kotlin 复制代码
@Composable
fun MyTest(){
    Text(
        text=if(LocalInspectionMode.current) "预览中" else MyClass.getDesc()
    )
}
相关推荐
大白要努力!1 小时前
android 使用SQLiteOpenHelper 如何优化数据库的性能
android·数据库·oracle
Estar.Lee1 小时前
时间操作[取当前北京时间]免费API接口教程
android·网络·后端·网络协议·tcp/ip
Winston Wood1 小时前
Perfetto学习大全
android·性能优化·perfetto
Dnelic-4 小时前
【单元测试】【Android】JUnit 4 和 JUnit 5 的差异记录
android·junit·单元测试·android studio·自学笔记
Eastsea.Chen6 小时前
MTK Android12 user版本MtkLogger
android·framework
长亭外的少年14 小时前
Kotlin 编译失败问题及解决方案:从守护进程到 Gradle 配置
android·开发语言·kotlin
建群新人小猿16 小时前
会员等级经验问题
android·开发语言·前端·javascript·php
1024小神17 小时前
tauri2.0版本开发苹果ios和安卓android应用,环境搭建和最后编译为apk
android·ios·tauri
兰琛17 小时前
20241121 android中树结构列表(使用recyclerView实现)
android·gitee
Y多了个想法18 小时前
RK3568 android11 适配敦泰触摸屏 FocalTech-ft5526
android·rk3568·触摸屏·tp·敦泰·focaltech·ft5526