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.hqwc.cn/news/638127.html

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

相关文章

Can‘t log out of macbook account 【macbook 账户无法退出】

参考&#xff1a; https://iboysoft.com/news/cant-sign-out-of-icloud-mac.html

【数据结构-树和二叉树-森林-哈夫曼树】

目录 1 树1.1 树的描述&#xff08;基本术语&#xff09; 2 二叉树&#xff08;树的度最大为2&#xff09;2.1 注意事项-五种基本形态2.2 二叉树的抽象数据类型定义 3 二叉树的性质3.1 两种特殊形式的二叉树-重点会计算3.2 题目练习&#xff1a; 4 二叉树的存储结构4.1 顺序存储…

【融合ChatGPT等AI模型】Python-GEE遥感云大数据分析、管理与可视化及多领域应用

随着航空、航天、近地空间遥感平台的持续发展&#xff0c;遥感技术近年来取得显著进步。遥感数据的空间、时间、光谱分辨率及数据量均大幅提升&#xff0c;呈现出大数据特征。这为相关研究带来了新机遇&#xff0c;但同时也带来巨大挑战。传统的工作站和服务器已无法满足大区域…

汇编语言(详解)

汇编语言安装指南 第一步&#xff1a;在github上下载汇编语言的安装包 网址&#xff1a;GitHub - HaiPenglai/bilibili_assembly: B站-汇编语言-pdf、代码、环境等资料B站-汇编语言-pdf、代码、环境等资料. Contribute to HaiPenglai/bilibili_assembly development by creat…

人工智能入门(一):基于Pytorch的手写数字识别模型

前言&#xff1a; 因为还在上学&#xff0c;时间不太够用&#xff0c;很多内容写到后面心有余力不足&#xff0c;未来有时间我会慢慢补充。人工智能的知识涉猎范围广又杂乱无章&#xff0c;啃书或上课学到的知识往往很早就过时了或者离实际的项目无关。所以&#xff0c;我很希…

【Redis】List 数据类型

文章目录 常用命令lpush & lpushxrpush & rpushxlrange & lpop & rpoplindex & linsertllen 阻塞版本的命令内部编码 列表类型是⽤来存储多个有序的字符串&#xff0c;⼀个列表最多可以存储 2^32 - 1 个元素&#xff0c;允许有重复的元素。 列表在两端都可…

YOLOv9改进策略 | Conv篇 | 利用YOLO-MS的MSBlock二次创新RepNCSPELAN4(全网独家创新)

一、本文介绍 本文给大家带来的改进机制是利用YOLO-MS提出的一种针对于实时目标检测的MSBlock模块(其其实不能算是Conv但是其应该是一整个模块)&#xff0c;我们将其用于RepNCSPELAN中组合出一种新的结构&#xff0c;来替换我们网络中的模块可以达到一种轻量化的作用&#xff…

TVbox三端助手MAC+Windows+手机版带接口

Vbox这个目前大热的电视播放器&#xff0c;由于是空壳&#xff0c;于是接口成为非常核心的一环&#xff0c;很多网友制作的接口会进行加密&#xff0c;以防被人复制使用。 最近发现有人对此做了个专门解密的工具&#xff0c;解不解密的不重要的&#xff0c;分享迷倒是觉得这工…

Python 全栈安全(二)

原文&#xff1a;annas-archive.org/md5/712ab41a4ed6036d0e8214d788514d6b 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 第二部分&#xff1a;认证与授权 本书的第二部分是最具商业价值的部分。我这样说是因为它充满了大多数系统需要具备的实用工作流示例&#xf…

Web3钱包和身份验证:安全和去中心化的新标准

引言 在数字化的今天&#xff0c;我们正处于一个互联网技术迅速发展的时代。Web3作为一个革命性的概念&#xff0c;正在逐渐改变我们对互联网的看法和使用习惯。在这一变革中&#xff0c;Web3钱包和身份验证成为了核心组成部分&#xff0c;它们不仅为我们提供了安全和去中心化…

哈尔滨等保测评综述

​ 定级是网络安全等级保护的首要环节和关键环节&#xff0c;可以梳理各行业、各部门、各单位的等级保护对象类型、重要程度和数量等基本信息&#xff0c;确定分级保护的重点。定级不准&#xff0c;系统备案、建设、整改、等级测评等后续工作都会失去意义&#xff0c;等级…

[Spring Cloud] (4)搭建Vue2与网关、微服务通信并配置跨域

文章目录 前言gatway网关跨域配置取消微服务跨域配置 创建vue2项目准备一个原始vue2项目安装vue-router创建路由vue.config.js配置修改App.vue修改 添加接口访问安装axios创建request.js创建index.js创建InfoApi.js main.jssecurityUtils.js 前端登录界面登录消息提示框 最终效…