资讯详情

【Android】Compose 布局基础

📅 2026/10/28 9:28:55 | 华诺云谱 👁 阅读
【Android】Compose 布局基础
一. 构建基础布局什么是界面UI?应用的界面 (UI) 就是您在屏幕上所看到的内容文本、图片、按钮和许多其他类型的元素及其在屏幕上的布局方式。它既是应用向用户显示内容的方式也是用户与应用展开互动的载体1.1. Jetpack Compose介绍什么是Jetpack ComposeJetpack Compose 是用于构建 Android 界面的新款工具包。Compose 使用更少的代码、强大的工具和直观的 Kotlin 功能可以帮助您简化并加快 Android 界面开发。借助 Compose您可以通过定义一组函数来构建界面这些函数称为可组合函数它们会接受数据并描述界面元素。1.1.1. 可组合函数在 Compose 中可组合函数是界面的基本构建块。可组合函数描述界面中的某一部分。不会返回任何内容。接受一些输入并生成屏幕上显示的内容。ComposablefunGreeting(name:String){Text(textHello$name!)}可组合函数带有Composable注解。所有可组合函数都必须带有此注解。此注解可告知Compose编译器此函数用于将数据转换为界面。请注意编译器是一种特殊的程序它会接受您编写的代码逐行查看然后将其转换成计算机可以理解的指令机器语言。关于可组合函数的几点说明Jetpack Compose 是围绕可组合函数构建的。这些函数可让您以程序化方式定义应用的界面只需描述应用界面的外观而不必关注界面的构建过程。如需创建可组合函数只需将 Composable 注解添加到函数名称中即可可组合函数可以接受一些实参用来让应用逻辑描述或修改界面。在本例中界面元素接受一个 String以便在问候用户时称呼姓名。1.1.2. 注释注解是用于在代码中附加额外信息的方式。此类信息可以帮助 Jetpack Compose 编译器等工具和其他开发者理解应用的代码。若要应用注解只需在您要注解的声明开头为其名称注解添加字符作为前缀即可。您可以为包括属性、函数和类在内的不同代码元素添加注解。下图是一个带有注解的函数示例以下代码段中包含一些带有注解的属性示例。在后续开发中您将用到这些属性。// Example code, do not copy it overJsonvalimgSrcUrl:StringVolatileprivatevarINSTANCE:AppDatabase?null1.1.3. 带形参/不带形参的注解注解可以接受形参。形参可以为处理它们的工具提供额外信息。以下是带形参和不带形参的 Preview 注解的一些示例不带形参的注解带形参的注解带有预览标题的注解您可以向注解传递多个实参如下所示## 1.2. 更改字体大小可缩放像素可缩放像素 (SP)是字体大小的度量单位。Android 应用中的界面元素使用两种不同的度量单位一种是您稍后将为布局使用的密度无关像素 (DP)另一种就是可缩放像素 (SP)。默认情况下SP 单位与 DP 单位大小相同但前者的大小会根据用户在手机设置下的首选文本大小进行调整。在MainActivity.kt文件中滚动到GreetingText()函数中的Text()可组合项。向Text()函数传递fontSize实参作为第二个具名实参并将其值设为100.sp。ComposablefunGreetingText(message:String,modifier:ModifierModifier){// 设置字体大小和行高Text(message,fontSize100.sp,lineHeight116.sp)}效果我们还可以再添加一个文本ComposablefunGreetingText(message:String,from:String,modifier:ModifierModifier){Text(from,fontSize36.sp)Text(message,fontSize100.sp,lineHeight116.sp)}Preview(showBackgroundtrue)ComposablefunBirthdayCardPreview(){GreetingText(messageHappy Birthday Sam!,From Emma)}一个可组合函数可能会描述多个界面元素。不过如果您未提供有关如何排列这些元素的指导Compose 可能会以您不喜欢的方式排列它们。例如上面的代码生成了两个相互重叠的文本元素因为您没有提供有关如何排列这两个可组合项的指导。1.3. 文本的排列方式行/列界面层次结构基于包含机制意即一个组件可以包含一个或多个组件有时会用“父级”和“子级”这两个词来表述。这种说法是指父界面元素包含子界面元素而子界面元素还可以继续包含子界面元素。在此部分中您将了解可用作父界面元素的Column、Row 和 Box 可组合项。Compose中的3 个基本标准布局元素是Column、Row 和 Box可组合项。后面会介绍BoxColumn、Row 和 Box 都是接受可组合内容作为参数的可组合函数因此您可以在这些布局元素内放置项目。例如Row 可组合项中的各个子元素彼此相邻地水平放置成一行。ComposablefunGreetingText(message:String,from:String,modifier:ModifierModifier){Row{Text(from,fontSize36.sp)Text(message,fontSize36.sp,lineHeight36.sp)}}将内容排成一列ComposablefunGreetingText(message:String,from:String,modifier:ModifierModifier){Column{Text(from,fontSize36.sp)Text(message,fontSize36.sp,lineHeight36.sp)}}1.4. 尾随lambda语法请注意在上一个代码段中Row 可组合函数中使用的是花括号而不是圆括号。这称为尾随 Lambda 语法。稍后会详细介绍 lambda 和尾随 lambda 语法。现在您只需要熟悉这个常用的 Compose 语法。当最后一个形参是函数时Kotlin 提供了一种特殊语法来将函数作为形参传递给函数将函数作为形参传递时您可以使用尾随 lambda 语法。您可以将函数放在圆括号外部的大括号中而不是放在圆括号内。这是 Compose 中的一种常见且推荐的做法因此您需要熟悉代码的格式。例如Row() 可组合函数中的最后一个形参是 content 形参它是一个描述子界面元素的函数。假设您想要创建一个包含三个文本元素的行。以下代码行得通但如果为尾随 lambda 使用具名形参则非常麻烦Row(content{Text(Some text)Text(Some more text)Text(Last text)})由于 content 形参是函数签名中的最后一个形参并且您要将其值作为 lambda 表达式传递因此您可以移除 content 形参和括号如下所示Row{Text(Some text)Text(Some more text)Text(Last text)}1.5 将内容居中如需在屏幕中心对齐问候语请添加一个名为verticalArrangement的形参并将其设置为Arrangement.Center。ComposablefunGreetingText(message:String,from:String,modifier:ModifierModifier){Column(verticalArrangementArrangement.Center,modifiermodifier){Text(from,fontSize36.sp,modifierModifier.padding(16.dp)// Compose 提供 align 修饰符来单独控制子级可组合项的位置使其不受父布局强制执行的对齐布局规则的约束。这里是单独制定该text的排列方式.align(alignmentAlignment.End))Text(message,fontSize36.sp,lineHeight36.sp,textAlignTextAlign.Center)}}1.6. 添加图片若要在应用中显示图片需要有一个显示位置。就像使用 Text 可组合项显示文本一样可以使用 Image 可组合项来显示图片。通过添加可组合函数来添加图片在MainActivity.kt文件中在GreetingText()函数后面添加一个GreetingImage()可组合函数。向GreetingImage()函数传递两个String形参一个名为 message用于添加生日祝福语另一个名为 from用于添加签名。每个可组合函数都应接受一个可选的Modifier形参。修饰符用于控制界面元素在其父布局中的放置、显示或行为方式。在 GreetingImage() 可组合函数中添加另一个形参。ComposablefunGreetingImage(message:String,from:String,modifier:ModifierModifier){}1.6.1 Jetpack Compose中的资源资源是指代码使用的附加文件和静态内容例如位图、界面字符串、动画说明等。您应该始终将应用资源如图片和字符串与代码分隔开以便能够独立地维护这些资源。在运行时Android 会根据当前配置使用合适的资源。例如您可能想根据屏幕尺寸提供不同的界面布局或根据语言设置提供不同的字符串资源分组您应始终将每种类型的资源放在项目的res/目录下的相应子目录中。例如以下是一个简单项目的文件层次结构MyProject/src/MyActivity.kt res/drawable/graphic.png mipmap/icon.png values/strings.xml在此示例中res/目录中包含存储在不同子目录中的所有资源其中包括存储图片资源的 drawable/ 目录、存储启动器图标的 mipmap/目录和存储字符串资源的 values/目录。访问资源Jetpack Compose 可以访问您的Android 项目中定义的资源。可以使用在项目的R 类中生成的资源 ID 访问资源。R 类是Android自动生成的类其中包含了项目中所有资源的 ID。在大多数情况下资源 ID 与文件名相同。例如可以使用以下代码访问上面的文件层次结构中的图片R.drawable.graphic1.6.2 显示图片在GreetingImage()函数中声明val属性并将其命名为image。通过传入androidtest资源来调用painterResource()函数。将返回值分配给image变量。valimagepainterResource(R.drawable.androidtest)// painterResource() 函数会加载可绘制图片资源并将资源 ID在本例中为 R.drawable.androidparty作为实参调用painterResource()函数后添加Image可组合函数然后传入image作为painter的具名实参。ComposablefunGreetingImage(message:String,from:String,modifier:ModifierModifier){valimagepainterResource(R.drawable.androidtest)Image(painterimage)}报错如下解决方案Image(painterimage,// 将图片的 contentDescription 实参设为 null以便 TalkBack 跳过 Image 可组合函数。contentDescriptionnull// 无障碍描述)1.7. 添加盒子布局BoxBox 布局是 Compose 中的标准布局元素之一。使用 Box 布局可将元素堆叠在一起。Box 布局还可用于配置它所包含的元素的特定对齐方式。在GreetingImage()函数中添加围绕 Image 可组合项的 Box 可组合项如下所示然后 在GreetingImage函数中调用GreetingText函数ComposablefunGreetingImage(message:String,from:String,modifier:ModifierModifier){valimagepainterResource(R.drawable.androidtest)Box(modifier){Image(painterimage,contentDescriptionnull)GreetingText(message,from,Modifier.fillMaxSize().padding(8.dp))}}1.8. 调整图片大小Image(painterimage,contentDescriptionnull,// 设置图片的缩放方式contentScaleContentScale.Crop,// 使图片充满Box父盒子modifierModifier.fillMaxSize(),// 设置图片的透明度alpha0.5f)最终效果1.9 Spacer - 间距ComposablefunSpacerDemo(){Column(modifierModifier.padding(16.dp)){Text(标题,fontSize20.sp,fontWeightFontWeight.Bold)// 增加间距组件Spacer(modifierModifier.height(8.dp))// 标题和内容之间相距8.dpText(这是文字内容,fontSize14.sp,colorColor.Gray)}}Spacer: 是手动在两个元素之间插入间距更灵活spacedBy:spacedBy(8.dp)是在Column/Row参数中设置自动给所有子元素加间距。2.0 weight - 按比例分配ComposablefunWeightDemo(){Column(modifierModifier.fillMaxWidth().background(Color.Green)){Row(modifierModifier.fillMaxWidth().height(40.dp)){Box(modifierModifier.weight(1f).fillMaxSize().background(Color.Red))Box(modifierModifier.weight(1f).fillMaxSize().background(Color.Green))Box(modifierModifier.weight(1f).fillMaxSize().background(Color.Blue))}}}
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑