《探索 Jetpack Compose:构建现代化 Android UI 的利器》
Jetpack Compose 是谷歌推出的现代化 UI 框架,用于简化 Android 应用开发中的 UI 构建。它使用声明式编程方式,允许开发者以简洁直观的方式创建动态和响应式的 UI。本文将从基础概念到进阶用法,带你全面了解 Compose 的核心功能和使用技巧。
基本组件使用
1. Text 组件
Text 组件用于在界面上显示文本。其使用非常简单,只需在可组合函数中调用 Text 并传入要显示的文本内容即可
import androidx.compose.foundation.layout.Column
import androidx.compose.material.Text
import androidx.compose.runtime.Composable@Composable
fun SimpleTextUI() {Column {Text("这是 Compose 中的一段文本")}
}
这里创建了一个名为 SimpleTextUI 的可组合函数,内部使用 Column 组件垂直排列子组件,并在其中添加了一个 Text 组件来显示指定文本。
2. Button 组件
Button 组件用于创建可点击的按钮。通常与点击事件处理结合使用
import androidx.compose.foundation.layout.Column
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember@Composable
fun ButtonUI() {val clickCount = remember { mutableStateOf(0) }Column {Button(onClick = { clickCount.value++ }) {Text("点击我")}Text("按钮已被点击 ${clickCount.value} 次")}
}
在这个例子中,通过 remember 和 mutableStateOf 来创建并记住一个可观察的点击次数状态。每次点击按钮时,点击次数会增加,并在下方的 Text 组件中实时显示更新后的点击次数
3. 布局组件 Column 和 Row
Column 用于垂直排列子组件,Row 用于水平排列子组件。它们是构建复杂 UI 布局的基础。例如,创建一个简单的登录界面布局
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.material.TextField
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.Composable@Composable
fun LoginUI() {Column {TextField(value = "", onValueChange = {})TextField(value = "", onValueChange = {})Row {Button(onClick = {}) {Text("登录")}Button(onClick = {}) {Text("注册")}}}
}
在 LoginUI 函数中,首先使用 Column 垂直排列两个 TextField 组件用于输入用户名和密码,然后使用 Row 水平排列登录和注册按钮
4. 状态管理
在 Compose 中,状态管理是构建动态 UI 的关键。常用的方式是结合 remember 和 mutableStateOf。例如,实现一个简单的计数器应用
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp@Composable
fun CounterApp() {val count = remember { mutableStateOf(0) }Column(modifier = Modifier.fillMaxWidth(),horizontalAlignment = Alignment.CenterHorizontally,verticalArrangement = Arrangement.Center) {Text(text = "计数: ${count.value}")Spacer(modifier = Modifier.height(16.dp))Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.Center) {Button(onClick = { count.value = count.value - 1 }) {Text(text = "减少")}Spacer(modifier = Modifier.width(16.dp))Button(onClick = { count.value = count.value + 1 }) {Text(text = "增加")}}}
}
这里通过 remember {mutableStateOf (0) } 创建了一个可记忆的计数器状态 count。当点击增加或减少按钮时,count.value 会相应改变,从而触发包含 Text 组件的 Column 组件重组,更新界面显示的计数
5. 主题和样式
Compose 提供了强大的主题系统来统一应用的外观。首先可以定义自己的主题颜色等属性
import androidx.compose.material.MaterialTheme
import androidx.compose.material.lightColors
import androidx.compose.runtime.Composableval MyColors = lightColors(primary = Color.Blue,secondary = Color.Green
)@Composable
fun MyAppTheme(content: @Composable () -> Unit) {MaterialTheme(colors = MyColors,content = content)
}
然后在其他组件中应用这个主题:
import androidx.compose.foundation.layout.Column
import androidx.compose.material.Text
import androidx.compose.runtime.Composable@Composable
fun ThemedText() {MyAppTheme {Column {Text("这段文本在自定义主题中", color = MaterialTheme.colors.primary)}}
}
这样就可以使文本的颜色根据自定义主题中的主颜色来显示,实现了整个应用 UI 风格的统一和定制
6. 与其他组件集成 与 ViewModel 集成
在遵循 MVVM 架构的 Android 应用中,Compose 可以与 ViewModel 无缝协作。例如,假设有一个 UserViewModel 用于获取和管理用户信息
class UserViewModel : ViewModel() {val user = MutableLiveData<User>()// 假设这里有方法来获取用户信息,如从网络或者数据库fun fetchUser() {//...}
}
在 Compose 中使用如下:
import androidx.compose.foundation.layout.Column
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.compose.viewModel@Composable
fun UserInfoUI() {val viewModel: UserViewModel = viewModel()viewModel.fetchUser()val user = viewModel.user.valueColumn {if (user!= null) {Text("用户名: ${user.name}")Text("用户年龄: ${user.age}")}}
}
通过 viewModel 函数获取 UserViewModel 的实例,调用 fetchUser 方法获取用户信息,并在 UI 中显示用户的姓名和年龄。
7. 与导航(Navigation)集成
Compose 可以与 Android 的导航组件集成,实现不同屏幕之间的导航。例如,定义两个 Compose 屏幕 ScreenA 和 ScreenB 并设置导航:
import androidx.compose.foundation.layout.Column
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.navigation.NavController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController@Composable
fun ScreenA(navController: NavController) {Column {Text("这是屏幕 A")Button(onClick = { navController.navigate("screenB") }) {Text("前往屏幕 B")}}
}@Composable
fun ScreenB() {Column {Text("这是屏幕 B")}
}@Composable
fun NavigationApp() {val navController = rememberNavController()NavHost(navController = navController,startDestination = "screenA") {composable("screenA") {ScreenA(navController)}composable("screenB") {ScreenB()}}
}
这里 NavigationApp 函数是导航应用的入口。通过 rememberNavController 创建导航控制器,NavHost 定义导航宿主,composable 函数定义不同屏幕及其对应的路径。在 ScreenA 中点击按钮可通过导航控制器导航到 ScreenB
相关文章:
《探索 Jetpack Compose:构建现代化 Android UI 的利器》
Jetpack Compose 是谷歌推出的现代化 UI 框架,用于简化 Android 应用开发中的 UI 构建。它使用声明式编程方式,允许开发者以简洁直观的方式创建动态和响应式的 UI。本文将从基础概念到进阶用法,带你全面了解 Compose 的核心功能和使用技巧。 …...
cocos creator 的 widget组件的使用及踩坑
以下的内容基于cocos creator 3.8版本,如有错误,恳请指出。 👉官方文档的指引 应用:以上官方指引有非常清晰的使用方式,接下来说明一些注意事项: 1、与canvas搭配的使用,解决多分别率适配问题。…...
Baumer工业相机的EMVA1288 数据报告简介
项目场景: Baumer工业相机堡盟VCX系列和VLX系列为堡盟全系列相机中的主流常用相机和高端相机,性能强大、坚固可靠,易于集成,常用与一般行业的检测定位识别使用。 对应的高端相机系列具有极为丰富的强大技术功能,可轻…...
Docker 安装 中文版 GitLab
Docker 安装系列 安装GitLab、解决服务器内存不足问题、使用域名/IP地址访问项目 1、拉取 [rootTseng ~]# docker pull twang2218/gitlab-ce-zh:latest latest: Pulling from twang2218/gitlab-ce-zh 8ee29e426c26: Pull complete 6e83b260b73b: Pull complete e26b65fd11…...
uni-app 个人课程表页面
uni-app 个人课程表页面 插件参考地址 大部分代码都是参考了上述代码,只对代码做出了优化 1. 页面模板 在 schedule.vue 文件中,编写页面结构: <template><view><u-navbar title"个人中心"><view class&q…...
FPGA工作原理、架构及底层资源
FPGA工作原理、架构及底层资源 文章目录 FPGA工作原理、架构及底层资源前言一、FPGA工作原理二、FPGA架构及底层资源 1.FPGA架构2.FPGA底层资源 2.1可编程输入/输出单元简称(IOB)2.2可配置逻辑块2.3丰富的布线资源2.4数字时钟管理模块(DCM)2.5嵌入式块 …...
【OpenCV】平滑图像
二维卷积(图像滤波) 与一维信号一样,图像也可以通过各种低通滤波器(LPF)、高通滤波器(HPF)等进行过滤。LPF 有助于消除噪音、模糊图像等。HPF 滤波器有助于在图像中找到边缘。 opencv 提供了函数 **cv.filter2D()**&…...
LeetCode300. 最长递增子序列(2024冬季每日一题 30)
给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的 子序列。 示例 1&…...
vue H5如何实现copy功能
vue H5如何实现copy功能 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><link rel"stylesheet" href"https://unpkg.com/vant2.12/lib/index.css" /><title></title><st…...
Golang使用etcd构建分布式锁案例
在本教程中,我们将学习如何使用Go和etcd构建分布式锁系统。分布式锁系统对于管理对分布式系统中共享资源的并发访问至关重要。它有助于维护一致性,防止竞争条件,并确保在任何给定时间只有一个进程独占访问资源。 我们将使用Go作为编程语言&am…...
Windows 和 Ubuntu 双系统安装
复现论文的时候,个别包只有Linux版本,并且源码编译比较麻烦,所以干脆直接安装一个双系统(WinUbuntu),方便复现论文。 参考视频链接:Windows 和 Ubuntu 双系统的安装和卸载 0.所需工具 4G以上U…...
多媒体文件解复用(Demuxing)过程
多媒体文件的解复用(Demuxing)过程指的是从一个多媒体容器文件(如 MP4、MKV、AVI 等)中提取不同类型的多媒体数据流(例如视频流、音频流、字幕流等)的过程。 容器文件本身并不包含实际的视频或音频数据&…...
从 Zuul 迁移到 Spring Cloud Gateway:一步步实现服务网关的升级
从 Zuul 迁移到 Spring Cloud Gateway:一步步实现服务网关的升级 迁移前的准备工作迁移步骤详解第一步:查看源码第二步:启动类迁移第三步:引入 Gateway 依赖第四步 编写bootstrap.yaml第五步:替换路由配置第六步&#…...
qt之插件编译
QtXlsxWriter sudo apt install qtbase5-private-dev git clone https://github.com/dbzhang800/QtXlsxWriter.git cd QtXlsxWriter/ qmake make -j6 sudo make install #将生成的lib 及 include copy至项目路径的lib 及include里项目配置: QT xlsxbluetoo…...
pandas一行拆成多行
import pandas as pd df pd.DataFrame({Country:[China,US,Japan,EU,UK/Australia, UK/Netherland],Number:[100, 150, 120, 90, 30, 2],Value: [1, 2, 3, 4, 5, 6],label: list(abcdef)})# 法一 推荐 df2df.drop(Country, axis1).join(df[Country].str.split(/, expandTrue).…...
今天调了个转速的小BUG
同事说转速表有个bug,转速停止后,继电器没有恢复到初始状态。若停止之前是报警,继电器吸合,则停止后继电器还是吸合。我心想不会啊,这软件都弄了好几年了,一直也没出现过状况。 经过与调试同事的沟通&#…...
第三节、电机定速转动【51单片机-TB6600驱动器-步进电机教程】
摘要:本节介绍用定时器定时的方式,精准控制脉冲时间,从而控制步进电机速度 一、计算过程 1.1 电机每一步的角速度等于走这一步所花费的时间,走一步角度等于步距角,走一步的时间等于一个脉冲的时间 w s t e p t … ……...
从一个Bug谈前端响应拦截器的应用
一、问题场景 今天在开发商品管理系统时,遇到了一个有趣的问题:当添加重复的商品编号时,页面同时弹出了两条 "商品编号已存在" 错误提示: 这个问题暴露了前端错误处理机制的混乱,让我们从这个问题出发&…...
JS进阶DAY4|节点操作
嘿👋 今天我们要一起深入探索JavaScript中的DOM操作,这是前端开发中不可或缺的技能。🌟 准备好了吗?让我们一起跳进DOM的海洋,看看怎么用代码操控网页的结构吧! 目录 1. 增加节点 1.1 使用 appendChild 方…...
【Web】2023安洵杯第六届网络安全挑战赛 WP
目录 Whats my name easy_unserialize signal Swagger docs 赛题链接:GitHub - D0g3-Lab/i-SOON_CTF_2023: 2023 第六届安洵杯 题目环境/源码 Whats my name 第一段正则用于匹配以 include 结尾的字符串,并且在 include 之前,可以有任…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...
