Jetpack-Compose 学习笔记(一)—— Compose 初探(上)

简介: Jetpack-Compose 学习笔记(一)—— Compose 初探(上)

这是我参与8月更文挑战的第1天,活动详情查看:8月更文挑战

历时两年,Android 团队推出了全新的原生 Android 界面 UI 库——Compose。当然,Compose 也是属于 Jetpack 工具库中的一部分,官方宣称可以简化并加快 Android 上的界面开发,可以用更少的代码去快速打造生动而精彩的应用。1.0 版本就在上个月底刚刚发布,而且可以在生产环境中使用!不管咋样,先上手看一看!


1. 上手成本如何?


个人感觉,还行,有一定的学习成本。前提条件,对 Kotlin 语言熟悉,因为 Compose 都是用 Kotlin 语言开发实现的,对其他的 Jetpack 库熟悉就更好了。

Compose 可以和现有的工程项目进行互操作。比如,我们可以将 Compose UI 放到现有布局的 View 中,也可以将 View 放到 Compose UI 中。

作为 Jetpack 工具库的一部分,Compose 当然也可以十分方便地与 LiveDada、ViewModel、Paging 等工具一起整合,从而提高编码效率。

Compose 也提供了 Material Design 组件和主题的实现,同时还有简明的动画 API 可以让应用更加灵动,体验更好。


2. 官方广告概述


Google 毕竟憋了两年,怎么说也得有两把刷子的。Compose 是 Google 新推出的适用于 Android 的新式声明性界面工具包。个人理解的声明性的意思是:UI 的控件只需要我们一开始的时候声明创建出来,绑定了数据就可以了,后续的更新可以全部交给 Compose 处理。

Google 是考虑到现在的应用展示的绝大多数不是静态数据,更多的是会实时更新的。而现有的 xml 界面,更新比较复杂繁琐,很容易出现同步错误。并且软件维护的复杂性还会随着需要更新的视图数量而增长,为了解决这一问题,Google 才想完全舍弃原有的用 xml 写视图的方案,重新开发出 Compose 这一整套的解决方案。

Compose 首先会生成整个屏幕,然后仅仅执行必要的更改。它是将 State 状态转化成 UI 界面,并且会智能地跳过那些数据没有发生改变的控件,重新生成已经发生改变的控件,这一过程称之为重组(recomposition)。此外,Compose 布局模型不允许多次测量,最多进行两次测量就可算出各组件的尺寸。


3. 环境搭建


对 IDE 版本有要求,需要下载最新版的 Android Studio —— Android Studio Arctic Fox,目前是 2020 3.1 版本。这个版本在“新建项目”中支持选择 Compose 模板,并且有即时预览 Compose 界面等功能。

一般情况下,对于这种新的技术,我们都会先在主项目中的非核心功能进行实践,慢慢摸索,等到坑踩得差不多了,才会考虑将之前老的工程代码用新的方法重构。所以,Compose 也支持添加到现有的项目中进行使用。


3.1 配置 Kotlin 和 Gradle


需要确保项目中使用的 Kotlin 版本在 1.5.10 及以上。

还需要将应用的最低 API 级别设置为 21 或更高,即 Android 5.0 版本及以上。另外还需将 app 目录下的 gradle 文件中启用 Jetpack Compose,并设置 Kotlin 编译器插件的版本。

android {
    defaultConfig {
        ...
        minSdkVersion 21    // SDK 版本最低为 21
    }
    buildFeatures {
        // Enables Jetpack Compose for this module
        compose true    // 开启 Compose
    }
    ...
    // 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.0-rc02'
    }
}


3.2 添加工具包依赖项


官方文档上需要添加的依赖如下:

dependencies {
    implementation 'androidx.compose.ui:ui:1.0.0-rc02'
    // Tooling support (Previews, etc.)
    implementation 'androidx.compose.ui:ui-tooling:1.0.0-rc02'
    // Foundation (Border, Background, Box, Image, Scroll, shapes, animations, etc.)
    implementation 'androidx.compose.foundation:foundation:1.0.0-rc02'
    // Material Design
    implementation 'androidx.compose.material:material:1.0.0-rc02'
    // Material design icons
    implementation 'androidx.compose.material:material-icons-core:1.0.0-rc02'
    implementation 'androidx.compose.material:material-icons-extended:1.0.0-rc02'
    // Integration with activities
    implementation 'androidx.activity:activity-compose:1.3.0-rc02'
    // Integration with ViewModels
    implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:1.0.0-alpha07'
    // Integration with observables
    implementation 'androidx.compose.runtime:runtime-livedata:1.0.0-rc02'
    implementation 'androidx.compose.runtime:runtime-rxjava2:1.0.0-rc02'
    // UI Tests
    androidTestImplementation 'androidx.compose.ui:ui-test-junit4:1.0.0-rc02'
}

其实如果只是想上手看看效果,没必要添加 Integration with activities、ViewModels、observables 这些库。


4. 简单上手


Compose 核心内容就是可组合的函数,如同它的英文名称一样,将 UI 拆解成一个个可组合在一起的 Composable 函数,方便维护与复用。但是,可组合函数只能在其他的可组合函数的范围内调用。要使函数成为可组合函数,只需在该函数上方添加 @Composable 注解即可。其实可以直接把被 @Composable 注解的函数看成是一个 View。

@Composable 注解可告诉 Compose 编译器:此函数旨在将数据转换为界面。并且生成界面的 Compose 函数不需要返回任何内容,因为它们描述的是所需的屏幕状态,而不是构造界面的组件。

还有一个很强大的功能是,Compose 是支持在 IDE 中预览可组合函数的,只需要在 Composable 函数上再添加一个 @Preview 注解就可以了,限制条件是 @Preview 注解只能修饰一个无参的函数,所以,如果你要预览,就得保证你预览的函数无参,或者再用一个无参函数包起来:

// code 1
@Composable
fun Greeting(name: String) {
    Text(text = "Hello $name!")
}
@Preview
@Composable
fun WrapperView() {
    Greeting("hahahaha")
}

就这样子,你就可以在 IDE 中看到预览的效果了,甚至都没有执行入口! Compose 的 Hello World 代码也比较简单,只需要在 setContent 方法里添加需要展示的 Composable 函数即可:

// code 2
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {    // 设置显示内容,相当于 setContentView
            Greeting("Hello World!")
        }
    }
}


4.1 Compose 布局初探


如果写过 Flutter,那么你会发现,Compose 的布局与 Flutter 类似。Column 可以将元素从上到下进行排列,类似于 LinearLayout 布局的 oritation 设置为 vertical。Row 就是将元素从左到右进行排列,类似于 LinearLayout 布局的 oritation 设置为 horizonal。还有 Box 堆叠布局,类似于 FrameLayout 布局,这里不再展开。下面是 Column 布局的一个简单例子,代码显示的效果如代码下方的图片所示:

// code 3
@Composable
fun NewStory() {
    Column(
        // 许多对象都有这个 Modifier 属性,这个属性非常重要,这里是设置了 padding
        modifier = Modifier.padding(16.dp)
    ) {
        Image(
            painter = painterResource(id = R.drawable.header),
            contentDescription = null
        )
        Text("今天天气好")
        Text(text = "郑州")
        Text(text = "July 2021")
    }
}

image.png

这里要说下 contentDescription 属性,官方教学文档的原文是:

Note: You also need to provide a contentDescription for the image. The description is used for accessibility. However, in a case like this where the image is purely decorative, it's appropriate to set the description to null, as we do here.

意思是:我们需要为 image 提供一个 contentDescription 属性。这个属性用于可访问性(=。=?)。然鹅,如果这个 image 纯粹只是装饰作用,那么也可以像我们在这里设置的一样,设为 null。

懵逼脸。然后去源码看看这个到底是个啥?

*@param contentDescription text used by accessibility services to describe what this image *represents. This should always be provided unless this image is used for decorative purposes, *and does not represent a meaningful action that a user can take. This text should be *localized, such as by using [androidx.compose.ui.res.stringResource] or similar

意思是:" 这个属性是可访问性服务用于描述此图片代表的是什么。这个属性的信息应该都要提供,除非此图只是用于装饰的目的,或者并没有表示用户有特殊意义的操作。此外,属性的信息文本应该存放在本地资源中,如 res 目录下的 string 或类似的地方。"

额。。。还是有点懵,去网上看了下 ImageView 中的 contentDescription 属性,好像是为了方便视力有障碍的人群所设置的。反正绝大多数情况下可以忽略,如有实际用途,欢迎交流讨论。

此外,Compose 的布局还有很灵活的,还记得在 LinearLayout 布局中可以设置 weight 来控制填充父布局吗?在 Compose 也有类似的用法,直接上代码吧~

// code 4
@Composable
fun MyScreenContent(names: List<String> = listOf("Android","there")) {
    Column(modifier = Modifier.fillMaxHeight()) {    // 类似于 match_parent
        Column(modifier = Modifier.weight(1f)) {    // 占满父布局剩余的高度空间
            for (name in names) {
                Text(text = name)
                Divider(color = Color.Black)
            }
        }
        Button(onClick = { }) {
            Text(text = "这是第二个 Button")
        }
    }
}


这个布局就是可以将 Button 放在父布局的底部位置,然后父布局剩余空间都会被内层的 Column 布局占满。

当然,Compose 可以轻松地遵循 Material Design 原则,因为可以直接在任何 Composable 函数外部用 MaterialTheme {} 包裹起来,这就可以使用 MaterialTheme 的属性了。包括字体样式、色值等。这里代码都比较简单,不再赘述。代码示例:gitee.com/xiuzhizhu/C…

目录
相关文章
|
5月前
|
存储 缓存 Android开发
安卓Jetpack Compose+Kotlin, 使用ExoPlayer播放多个【远程url】音频,搭配Okhttp库进行下载和缓存,播放完随机播放下一首
这是一个Kotlin项目,使用Jetpack Compose和ExoPlayer框架开发Android应用,功能是播放远程URL音频列表。应用会检查本地缓存,如果文件存在且大小与远程文件一致则使用缓存,否则下载文件并播放。播放完成后或遇到异常,会随机播放下一首音频,并在播放前随机设置播放速度(0.9到1.2倍速)。代码包括ViewModel,负责音频管理和播放逻辑,以及UI层,包含播放和停止按钮。
|
5月前
|
存储 数据库 Android开发
安卓Jetpack Compose+Kotlin,支持从本地添加音频文件到播放列表,支持删除,使用ExoPlayer播放音乐
为了在UI界面添加用于添加和删除本地音乐文件的按钮,以及相关的播放功能,你需要实现以下几个步骤: 1. **集成用户选择本地音乐**:允许用户从设备中选择音乐文件。 2. **创建UI按钮**:在界面中创建添加和删除按钮。 3. **数据库功能**:使用Room数据库来存储音频文件信息。 4. **更新ViewModel**:处理添加、删除和播放音频文件的逻辑。 5. **UI实现**:在UI层支持添加、删除音乐以及播放功能。
|
2月前
|
安全 Java Android开发
探索安卓应用开发的新趋势:Kotlin和Jetpack Compose
在安卓应用开发领域,随着技术的不断进步,新的编程语言和框架层出不穷。Kotlin作为一种现代的编程语言,因其简洁性和高效性正逐渐取代Java成为安卓开发的首选语言。同时,Jetpack Compose作为一个新的UI工具包,提供了一种声明式的UI设计方法,使得界面编写更加直观和灵活。本文将深入探讨Kotlin和Jetpack Compose的特点、优势以及如何结合使用它们来构建现代化的安卓应用。
62 4
|
4月前
|
存储 移动开发 Android开发
使用kotlin Jetpack Compose框架开发安卓app, webview中h5如何访问手机存储上传文件
在Kotlin和Jetpack Compose中,集成WebView以支持HTML5页面访问手机存储及上传音频文件涉及关键步骤:1) 添加`READ_EXTERNAL_STORAGE`和`WRITE_EXTERNAL_STORAGE`权限,考虑Android 11的分区存储;2) 配置WebView允许JavaScript和文件访问,启用`javaScriptEnabled`、`allowFileAccess`等设置;3) HTML5页面使用`<input type="file">`让用户选择文件,利用File API;
|
5月前
|
JavaScript Java Android开发
kotlin安卓在Jetpack Compose 框架下跨组件通讯EventBus
**EventBus** 是一个Android事件总线库,简化组件间通信。要使用它,首先在Gradle中添加依赖`implementation &#39;org.greenrobot:eventbus:3.3.1&#39;`。然后,可选地定义事件类如`MessageEvent`。在活动或Fragment的`onCreate`中注册订阅者,在`onDestroy`中反注册。通过`@Subscribe`注解方法处理事件,如`onMessageEvent`。发送事件使用`EventBus.getDefault().post()`。
|
5月前
|
安全 JavaScript 前端开发
kotlin开发安卓app,JetPack Compose框架,给webview新增一个按钮,点击刷新网页
在Kotlin中开发Android应用,使用Jetpack Compose框架时,可以通过添加一个按钮到TopAppBar来实现WebView页面的刷新功能。按钮位于右上角,点击后调用`webViewState?.reload()`来刷新网页内容。以下是代码摘要:
|
5月前
|
缓存 Android开发 Kotlin
【安卓app开发】kotlin Jetpack Compose框架 | 先用OKhttp下载远程音频文件再使用ExoPlayer播放
使用 Kotlin 的 Jetpack Compose 开发安卓应用时,可以结合 OkHttp 下载远程音频文件和 ExoPlayer 进行播放。在 `build.gradle` 添加相关依赖后,示例代码展示了如何下载音频并用 ExoPlayer 播放。代码包括添加依赖、下载文件、播放文件及简单的 Compose UI。注意,示例未包含完整错误处理和资源释放,实际应用需补充这些内容。
|
5月前
|
JavaScript 前端开发 Android开发
kotlin安卓在Jetpack Compose 框架下使用webview , 网页中的JavaScript代码如何与native交互
在Jetpack Compose中使用Kotlin创建Webview组件,设置JavaScript交互:`@Composable`函数`ComposableWebView`加载网页并启用JavaScript。通过`addJavascriptInterface`添加`WebAppInterface`类,允许JavaScript调用Android方法如播放音频。当页面加载完成时,执行`onWebViewReady`回调。
|
5月前
|
存储 Android开发 Kotlin
开发安卓app OKhttp下载后使用MediaPlayer播放
在Android Jetpack Compose应用程序中,要使用OkHttp下载远程音频文件并在本地播放,你需要完成以下几个步骤: 1. **添加依赖**:确保`build.gradle`文件包含OkHttp和Jetpack Compose的相关依赖。 2. **下载逻辑**:创建一个`suspend`函数,使用OkHttp发起网络请求下载音频文件到本地。 3. **播放逻辑**:利用`MediaPlayer`管理音频播放状态。 4. **Compose UI**:构建用户界面,包含下载和播放音频的按钮。
|
5月前
|
存储 Android开发
安卓app,MediaPlayer播放本地音频 | 按钮控制播放和停止
在Jetpack Compose中,不直接操作原生Android组件如`Button`和`MediaPlayer`,而是使用Compose UI构建器定义界面并结合ViewModel管理音频播放逻辑。以下示例展示如何播放本地音频并用按钮控制播放/停止:创建一个`AudioPlayerViewModel`管理`MediaPlayer`实例和播放状态,然后在Compose UI中使用`Button`根据`isPlaying`状态控制播放。记得在`MainActivity`设置Compose UI,并处理相关依赖和权限。