Compose 布局

文章目录

  • Compose 布局
    • Column
      • Column属性
      • 使用
    • Row
      • Row属性
      • 使用
    • Box
      • Box属性
      • 使用
    • ConstraintLayout
    • LazyColumn
      • LazyColumn属性
      • 使用
      • 使用多类型
      • 使用粘性标题
      • 回到顶部
    • LazyRow
      • LazyRow属性
      • 使用
    • LazyVerticalGrid
      • LazyVerticalGrid属性
      • 使用

Compose 布局

Column

Compose中的”垂直线性布局“。

Column属性

@Composable
inline fun Column(// 修饰符modifier: Modifier = Modifier,// 子元素的垂直排列方式// Arrangement.Top:子元素靠近顶部// Arrangement.Center:子元素靠近中间// Arrangement.Bottom:子元素靠近底部// Arrangement.SpaceEvenly:子元素均匀分布,中间间隔是均匀分布的// Arrangement.SpaceAround:子元素均匀分布,子元素前后间隔是相同的// Arrangement.SpaceBetween:前后无间隔,子元素均匀分布// Arrangement.spacedBy:指定子元素间隔verticalArrangement: Arrangement.Vertical = Arrangement.Top,// 子元素的水平对齐方式horizontalAlignment: Alignment.Horizontal = Alignment.Start,content: @Composable ColumnScope.() -> Unit
) 

使用

简单使用:

在这里插入图片描述

Column(modifier = Modifier.fillMaxSize(),verticalArrangement = Arrangement.Center,horizontalAlignment = Alignment.CenterHorizontally
) {Text("one", color = Color.Red)Text("two", color = Color.Green)Text("three", color = Color.Blue)
}

使用Arrangement.SpaceEvenly:

在这里插入图片描述

@Composable
fun MyText(text: String) {Box(modifier = Modifier.size(150.dp).background(Color.Gray),contentAlignment = Alignment.Center) {Text(text,fontSize = 30.sp)}
}@Composable
fun MyColumn() {Column(modifier = Modifier.fillMaxSize(),verticalArrangement = Arrangement.SpaceEvenly,horizontalAlignment = Alignment.CenterHorizontally) {MyText("one")MyText("two")MyText("three")}
}

使用Arrangement.SpaceAround:

在这里插入图片描述

@Composable
fun MyColumn() {Column(modifier = Modifier.fillMaxSize(),verticalArrangement = Arrangement.SpaceAround,horizontalAlignment = Alignment.CenterHorizontally) {MyText("one")MyText("two")MyText("three")}
}

使用Arrangement.SpaceBetween:

在这里插入图片描述

@Composable
fun MyColumn() {Column(modifier = Modifier.fillMaxSize(),verticalArrangement = Arrangement.SpaceBetween,horizontalAlignment = Alignment.CenterHorizontally) {MyText("one")MyText("two")MyText("three")}
}

使用Arrangement.spacedBy:

在这里插入图片描述

@Composable
fun MyColumn() {Column(modifier = Modifier.fillMaxSize(),verticalArrangement = Arrangement.spacedBy(20.dp),horizontalAlignment = Alignment.CenterHorizontally) {MyText("one")MyText("two")MyText("three")}
}

Row

Compose中的”水平线性布局“。

Row属性

@Composable
inline fun Row(// 修饰符modifier: Modifier = Modifier,// 子元素水平排列方式horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,// 子元素垂直对齐方式verticalAlignment: Alignment.Vertical = Alignment.Top,content: @Composable RowScope.() -> Unit
) 

使用

在这里插入图片描述

@Composable
fun MyRow() {Row(modifier = Modifier.fillMaxSize(),horizontalArrangement = Arrangement.SpaceAround,verticalAlignment = Alignment.CenterVertically) {MyText("one")MyText("two")MyText("three")}
}

Box

Compose中的”帧布局“。

Box属性

@Composable
inline fun Box(// 修饰符modifier: Modifier = Modifier,// 子元素对齐方式contentAlignment: Alignment = Alignment.TopStart,// 是否开启最小尺寸约束// 如果设置true,表示开启,则子元素会有最小尺寸约束propagateMinConstraints: Boolean = false,content: @Composable BoxScope.() -> Unit
)

使用

简单使用:

在这里插入图片描述

@Composable
fun MyBox() {Column(modifier = Modifier.fillMaxSize(),verticalArrangement = Arrangement.Center,horizontalAlignment = Alignment.CenterHorizontally) {Row {Box(contentAlignment = Alignment.TopStart,modifier = Modifier.size(50.dp).background(Color(0xFF, 0, 0, 0xFF))) {Text("1")}Box(contentAlignment = Alignment.TopCenter,modifier = Modifier.size(50.dp).background(Color(0xFF, 0, 0, 0x99))) {Text("2")}Box(contentAlignment = Alignment.TopEnd,modifier = Modifier.size(50.dp).background(Color(0xFF, 0, 0, 0x33))) {Text("3")}}Row {Box(contentAlignment = Alignment.CenterStart,modifier = Modifier.size(50.dp).background(Color(0, 0xFF, 0, 0xFF))) {Text("4")}Box(contentAlignment = Alignment.Center,modifier = Modifier.size(50.dp).background(Color(0, 0xFF, 0, 0x99))) {Text("5")}Box(contentAlignment = Alignment.CenterEnd,modifier = Modifier.size(50.dp).background(Color(0, 0xFF, 0, 0x33))) {Text("6")}}Row {Box(contentAlignment = Alignment.BottomStart,modifier = Modifier.size(50.dp).background(Color(0, 0, 0xFF, 0xFF))) {Text("7")}Box(contentAlignment = Alignment.BottomCenter,modifier = Modifier.size(50.dp).background(Color(0, 0, 0xFF, 0x99))) {Text("8")}Box(contentAlignment = Alignment.BottomEnd,modifier = Modifier.size(50.dp).background(Color(0, 0, 0xFF, 0x33))) {Text("9")}}}
}

使用propagateMinConstraints:

在这里插入图片描述

@Composable
fun MyBox() {Box(modifier = Modifier.padding(10.dp)) {Box(modifier = Modifier.size(50.dp).background(Color(0, 0, 0xFF)),propagateMinConstraints = true) {Box(modifier = Modifier.background(Color(0xFF, 0, 0)),) {Text("aaa")}}}
}

说明:因为第2个Box开启了propagateMinConstraints = true,因此第3个Box有了最小约束也就是50x50,因此会填充父容器。

ConstraintLayout

Compose中的”约束布局“。

添加依赖库:

implementation "androidx.constraintlayout:constraintlayout-compose:1.0.1"

使用:

  • createRefs():创建多个引用。
  • createRef():创建一个引用。
  • constrainAs:定义约束。
  • linkTo:约束关系。

在这里插入图片描述

ConstraintLayout(modifier = Modifier.fillMaxSize()) {val (one, two) = createRefs()  val three = createRef() DefaultText(text = "One", modifier = Modifier.constrainAs(one) {start.linkTo(parent.start)end.linkTo(parent.end)top.linkTo(parent.top, margin = 16.dp)})DefaultText(text = "Two", modifier = Modifier.constrainAs(two) {start.linkTo(parent.start)end.linkTo(parent.end)top.linkTo(one.bottom, margin = 16.dp)})DefaultText(text = "Three", modifier = Modifier.constrainAs(three) {start.linkTo(parent.start)end.linkTo(parent.end)bottom.linkTo(parent.bottom, margin = 16.dp)})
}

LazyColumn

Compose中的“垂直RecyclerView”。

LazyColumn属性

@Composable
fun LazyColumn(modifier: Modifier = Modifier, // 修饰符state: LazyListState = rememberLazyListState(), // 列表状态contentPadding: PaddingValues = PaddingValues(0.dp), // 内边距reverseLayout: Boolean = false, // 是否反转verticalArrangement: Arrangement.Vertical =if (!reverseLayout) Arrangement.Top else Arrangement.Bottom, // 垂直排列方式horizontalAlignment: Alignment.Horizontal = Alignment.Start, // 水平对齐方式flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(), // fling逻辑userScrollEnabled: Boolean = true, // 是否开启滚动content: LazyListScope.() -> Unit
)
@LazyScopeMarker
@JvmDefaultWithCompatibility
interface LazyListScope {// 添加一个项目fun item(key: Any? = null,contentType: Any? = null,content: @Composable LazyItemScope.() -> Unit) // 添加多个项目fun items(count: Int,key: ((index: Int) -> Any)? = null,contentType: (index: Int) -> Any? = { null },itemContent: @Composable LazyItemScope.(index: Int) -> Unit)// 添加粘性标题@ExperimentalFoundationApifun stickyHeader(key: Any? = null,contentType: Any? = null,content: @Composable LazyItemScope.() -> Unit)
}
// 通过List添加列表
inline fun <T> LazyListScope.items(items: List<T>,noinline key: ((item: T) -> Any)? = null,noinline contentType: (item: T) -> Any? = { null },crossinline itemContent: @Composable LazyItemScope.(item: T) -> Unit
) = items(count = items.size,key = if (key != null) { index: Int -> key(items[index]) } else null,contentType = { index: Int -> contentType(items[index]) }
) {itemContent(items[it])
}// 通过List添加列表,含索引值
inline fun <T> LazyListScope.itemsIndexed(items: List<T>,noinline key: ((index: Int, item: T) -> Any)? = null,crossinline contentType: (index: Int, item: T) -> Any? = { _, _ -> null },crossinline itemContent: @Composable LazyItemScope.(index: Int, item: T) -> Unit
) = items(count = items.size,key = if (key != null) { index: Int -> key(index, items[index]) } else null,contentType = { index -> contentType(index, items[index]) }
) {itemContent(it, items[it])
}// 通过数组添加列表
inline fun <T> LazyListScope.items(items: Array<T>,noinline key: ((item: T) -> Any)? = null,noinline contentType: (item: T) -> Any? = { null },crossinline itemContent: @Composable LazyItemScope.(item: T) -> Unit
) = items(count = items.size,key = if (key != null) { index: Int -> key(items[index]) } else null,contentType = { index: Int -> contentType(items[index]) }
) {itemContent(items[it])
}// 通过数组添加列表,含索引值
inline fun <T> LazyListScope.itemsIndexed(items: Array<T>,noinline key: ((index: Int, item: T) -> Any)? = null,crossinline contentType: (index: Int, item: T) -> Any? = { _, _ -> null },crossinline itemContent: @Composable LazyItemScope.(index: Int, item: T) -> Unit
) = items(count = items.size,key = if (key != null) { index: Int -> key(index, items[index]) } else null,contentType = { index -> contentType(index, items[index]) }
) {itemContent(it, items[it])
}

使用

使用items:

在这里插入图片描述

val dataList = arrayListOf<Int>()
for (index in 0..50) {dataList.add(index)
}LazyColumn(modifier = Modifier.fillMaxSize()) {items(dataList) { data ->Text("hello $data")}
}

使用itemsIndexed:

在这里插入图片描述

val dataList = arrayListOf<Int>()
for (index in 0..50) {dataList.add(index)
}LazyColumn(modifier = Modifier.fillMaxSize()) {itemsIndexed(dataList) { index, data ->Text("hello $index $data")}
}

使用多类型

在这里插入图片描述

val chatList = arrayListOf<Chat>()
chatList.apply {add(Chat("hello"))add(Chat("world", false))add(Chat("apple"))add(Chat("orange"))add(Chat("banana"))add(Chat("List", false))
}LazyColumn(modifier = Modifier.fillMaxSize().padding(5.dp)) {items(chatList) { item ->if (item.isLeft) {Column(modifier = Modifier.padding(end = 15.dp)) {Spacer(modifier = Modifier.height(5.dp))Text(item.content,modifier = Modifier.fillMaxWidth().height(25.dp).background(Color.Green))}} else {Column(modifier = Modifier.padding(start = 15.dp)) {Spacer(modifier = Modifier.height(5.dp))Text(item.content,modifier = Modifier.fillMaxWidth().height(25.dp).background(Color.Yellow))}}}
}

使用粘性标题

在这里插入图片描述

val dataList = arrayListOf<Int>()
for (i in 0..30) {dataList.add(i)
}LazyColumn(modifier = Modifier.fillMaxSize().padding(5.dp)
) {stickyHeader {Text("粘性标题一",modifier = Modifier.fillMaxWidth().background(Color.Red),textAlign = TextAlign.Center)}items(dataList) { data ->Text("数据:$data")}stickyHeader {Text("粘性标题二",modifier = Modifier.fillMaxWidth().background(Color.Green),textAlign = TextAlign.Center)}items(dataList) { data ->Text("数据:$data")}stickyHeader {Text("粘性标题三",modifier = Modifier.fillMaxWidth().background(Color.Blue),textAlign = TextAlign.Center)}items(dataList) { data ->Text("数据:$data")}
}

回到顶部

  • firstVisibleItemIndex:可见区域的第一个项的索引值。
  • animateScrollToItem:移动到指定坐标。

在这里插入图片描述

val dataList = arrayListOf<Int>()
for (i in 0..60) {dataList.add(i)
}val listState = rememberLazyListState()
val coroutineScope = rememberCoroutineScope()
val context = LocalContext.currentBox {LazyColumn(modifier = Modifier.fillMaxWidth().padding(5.dp), state = listState) {items(dataList) { data ->Text("数据:$data")}}Box(modifier = Modifier.matchParentSize(), contentAlignment = Alignment.BottomEnd) {Button(modifier = Modifier.wrapContentSize(), onClick = {coroutineScope.launch {listState.animateScrollToItem(0)}}) {Text("返回\n顶部")}}Box(modifier = Modifier.matchParentSize(), contentAlignment = Alignment.BottomCenter) {Button(modifier = Modifier.wrapContentSize(), onClick = {Toast.makeText(context, "firstVisibleItemIndex:${listState.firstVisibleItemIndex}", Toast.LENGTH_SHORT).show()}) {Text("firstVisibleItemIndex")}}
}

LazyRow

Compose中的“水平RecyclerView”。

LazyRow属性

fun LazyRow(modifier: Modifier = Modifier, // 修饰符state: LazyListState = rememberLazyListState(), // 列表状态contentPadding: PaddingValues = PaddingValues(0.dp), // 内边距reverseLayout: Boolean = false, // 是否反转horizontalArrangement: Arrangement.Horizontal =if (!reverseLayout) Arrangement.Start else Arrangement.End, // 水平排列方式verticalAlignment: Alignment.Vertical = Alignment.Top, // 垂直对齐方式flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(), // fling逻辑userScrollEnabled: Boolean = true, // 是否开启滚动content: LazyListScope.() -> Unit
) 

使用

在这里插入图片描述

val dataList = arrayListOf<Int>()
for (i in 0..60) {dataList.add(i)
}
LazyRow(modifier = Modifier.fillMaxWidth().padding(5.dp)
) {items(items = dataList, key = { index -> index }) { data ->Text("数据:$data", modifier = Modifier.padding(10.dp))}
}

LazyVerticalGrid

Compose中的“垂直网格布局”。

LazyVerticalGrid属性

@Composable
fun LazyVerticalGrid(columns: GridCells, // 单元格modifier: Modifier = Modifier, // 修饰符state: LazyGridState = rememberLazyGridState(), // 网格状态contentPadding: PaddingValues = PaddingValues(0.dp), // 内边距reverseLayout: Boolean = false, // 是否反转verticalArrangement: Arrangement.Vertical =if (!reverseLayout) Arrangement.Top else Arrangement.Bottom, // 垂直排列方式horizontalArrangement: Arrangement.Horizontal = Arrangement.Start, //水平对齐方式flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(), // fling逻辑userScrollEnabled: Boolean = true, // 是否开启滚动content: LazyGridScope.() -> Unit
)

使用

定义5列:

在这里插入图片描述

val photoList = arrayListOf<Int>()
for (i in 0..20) {photoList.add(R.drawable.ic_launcher_background)
}
LazyVerticalGrid(columns = GridCells.Fixed(5)) {items(photoList) { photo ->Image(painterResource(id = photo), null, Modifier.padding(5.dp))}
}

定义网格最小100dp:

在这里插入图片描述

LazyVerticalGrid(columns = GridCells.Adaptive(100.dp)) {items(photoList) { photo ->Image(painterResource(id = photo), null, Modifier.padding(5.dp))}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/1310.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

F-logic DataCube3 SQL注入漏洞复现(CVE-2024-31750)

0x01 产品简介 F-logic DataCube3是一款用于光伏发电系统的紧凑型终端测量系统。 0x02 漏洞概述 F-logic DataCube3 /admin/pr_monitor/getting_index_data.php 接口处存在SQL注入漏洞,未经身份验证的攻击者可通过该漏洞获取数据库敏感信息,深入利用可控制整个web服务器。 …

计算机图形学:直线生成算法—DDA

DDA&#xff08;Digital Differential Analyzer&#xff0c;数字差分分析器&#xff09;算法是一种基本的直线生成算法&#xff0c;通常用于计算机图形学中。它通过将直线划分为若干个等间隔的小线段&#xff0c;然后在每个小线段中选择一个像素点进行绘制&#xff0c;从而近似…

R-Tree:空间索引技术原理及实现详解

R-Tree&#xff1a;空间索引技术原理及实现详解 一、引言 在空间数据库中&#xff0c;如何高效地查询和处理空间数据一直是研究的热点。R-Tree作为一种重要的空间索引结构&#xff0c;在地理信息系统&#xff08;GIS&#xff09;、空间数据库管理系统等领域得到了广泛应用。本…

三十二章、Cesium从入门到精通;

一、打造第一个Cesium程序&#xff1b; 1、基础概念&#xff1b; 父子组件之间可以传递数据&#xff1a;props、回传事件&#xff1b; 使用Redux使用场景&#xff1a;兄弟&#xff1b; 2、代码样例&#xff1b; 11111111 二、Cesium基础设置&#xff1b; 三、讲解viewer…

产品原型图概念

产品原型图概念 产品原型图作用 如下图&#xff1a; 产品原型图的三种分类 线框图 通过【线段色块文字】描述产品页面。优点&#xff1a;制作快速。 缺点&#xff1a;传递信息容易遗漏。 应用&#xff1a;早期方案讨论&#xff0c;需要快速输出的场景&#xff0c;团队配合…

Java算法必备之快读

背景: 在一些算法题中,由于数据量过大,可能会出现卡输入输出时间的问题 原理: 在Java中,输入通常是使用Scanner,输出使用System.out,先说输入 Scanner in new Scanner(System.in);慢的原因有两方面: System.in在读取的时候是字节流进行读取,是一个字节一个字节读取的,在读取…

【工作杂记】groupBy排序-操作word

1.stream 流 groupBy 排序 stream流groupBy默认使用的HashMap&#xff0c;无序的&#xff0c;想要实现有序&#xff0c;需要手动指定接收的map类型 例子&#xff1a; Map<Date, List<OrderVo>> dataMap voList.stream().sorted(Comparator.comparing(OrderVo::ge…

华为OD-C卷-执行任务赚积分[100分]C++ 100%

题目描述 现有N个任务需要处理,同一时间只能处理一个任务,处理每个任务所需要的时间固定为1。 每个任务都有最晚处理时间限制和积分值,在最晚处理时间点之前处理完成任务才可获得对应的积分奖励。 可用于处理任务的时间有限,请问在有限的时间内,可获得的最多积分。 输…

Learn ComputeShader 01 First Computer Shader

使用Unity版本&#xff1a;2019.4.12f1 整体流程&#xff1a; 1添加一个quad object并添加一个无光照材质 2.相机投影模式设置为正交 3.调整quad使其完全显示在相机内 4.创建脚本并且使用计算着色器覆盖quad的纹理 5.创建一个compute shader 前三步完成以后结果应该是这…

网络基础先导

前言&#xff1a;最好在牢固前面几大件&#xff08;编程语言、数据结构、操作系统&#xff09;&#xff0c;并且您有一个服务器的基础上&#xff08;我使用的是腾讯云中配置最低的服务器&#xff09;再来学习本系列的网络知识。 1.网络发展简要 下面就是简单提及一些概念而已&…

多线程(64)如何设计一个高性能的订单处理系统

设计一个高性能的订单处理系统需要考虑多个方面&#xff0c;包括但不限于系统架构、数据一致性、可伸缩性、容错性以及性能优化。以下是设计这样一个系统的一些关键考虑因素和实现策略。 系统架构 微服务架构&#xff1a;将订单系统分解成独立的微服务&#xff0c;例如订单创建…

二叉树之AVL树

文章目录 1. AVL树的概念&#xff08;logN)1.1背景1.2规则 2.AVL树节点的定义3.AVL树的插入4. AVL树的旋转(重点&#xff09;4.1 新节点插入较高的右子树的右侧&#xff1a;左单璇&#xff1b;4.2 新节点插入较高左子树的左侧&#xff1a;右单璇&#xff1b;4.3&#xff08;双旋…

AJAX——ajax原理

1.XMLHttpRequest 定义&#xff1a;XMLHttpRequest&#xff08;XHR&#xff09;对象用于与服务器交互。通过XMLHttpRequest可以在不刷新页面的情况下请求特定URL&#xff0c;获取数据。这允许网页在不影响用户操作的情况下&#xff0c;更新页面的局部内容。XMLHttpRequest在AJA…

数据输入输出流(I/O)

文章目录 前言一、数据输入输出流是什么&#xff1f;二、使用方法 1.DataInputStream类2.DataOutoutStream类3.实操展示总结 前言 数据输入输出流也是将文件输入输出流打包后使用的对象。相比于文件输入输出流&#xff0c;数据输入输出流提供了简单易用的方法去操作不同类型的数…

【FreeRTOS】常用API接口

【FreeRTOS】常用API接口 为方便快速检索&#xff0c;这里只留下对应的接口名和功能注释&#xff0c;具体传参和使用方法拿函数名百度搜。 任务相关 xTaskCreate() //创建任务 vTaskDelete( NULL ); //删除任务&#xff0c;传入NULL为删除当前的任务 vTaskStartScheduler()&…

不需要在 HTML 中添加任何额外的标签,就能实现复杂的设计效果。

1. 基础知识 什么是伪元素选择器 伪元素选择器用来指定一个元素的特定部分或者在元素中创建虚拟内容。 最常见的伪元素选择器包括 ::before 和 ::after&#xff0c;它们分别用于在元素内容的前面和后面添加内容或样式。 伪元素选择器是为了增强对元素的控制&#xff0c;它们…

【微服务】spring读取配置文件多种方式深入详解

目录 一、前言 二、java配置文件介绍 2.1 java配置文件产生原因 2.2 项目使用配置文件好处 2.3 springboot项目配置文件的必要性 2.4 微服务架构下配置文件使用场景 三、java读取配置文件常用方法 3.1 使用Properties类读取配置文件 3.1.1 使用getResourceAsStream读取…

时序分析基础(6)——input delay时序分析

1 简介 FPGA对于外部的时钟以及数据的延时信息是不知道的&#xff0c;在低速时钟且时钟发射沿在数据正中心的时候&#xff0c;一般可以不做约束来直接使用。但是到了高速时钟或者双沿采样或者发射沿和数据对齐的情况下&#xff0c;这时候就需要告诉VIVADO外部的时钟与数据情况来…

python学习28:python中的集合set

python中的集合set 1.集合的定义 集合set是不支持重复元素的&#xff0c;而且是无序的 和列表、元组、字符串等定义基本相同&#xff1a; 列表使用&#xff1a;[]元组使用&#xff1a;()字符串使用:“”集合使用:{} 基本语法&#xff1a; """ 基本语法&#…

多轴机械臂/正逆解/轨迹规划/机器人运动学/Matlab/DH法 学习记录03——机械臂运动学逆解

系列文章目录 本科毕设正在做多轴机械臂相关的内容&#xff0c;这里是一个学习机械臂运动学课程的相关记录。 如有任何问题&#xff0c;可发邮件至layraliufoxmail.com问询。 1. 数学基础 2. 机械臂几何法与DH表示法 3. 机械臂运动学逆解 文章目录 系列文章目录一、引言1.手臂…