ArkUI-布局(三)

2024-08-29 04:12
文章标签 布局 arkui

本文主要是介绍ArkUI-布局(三),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

ArkUI-布局

  • 列表
    • 布局与约束
      • 设置主轴方向
      • 设置交叉轴布局
        • lanes
        • alignListItem
    • 自定义列表样式
      • 设置内容间距
      • 添加分隔线
      • 添加滚动条
    • 支持分组列表
    • 添加粘性标题
    • 控制滚动位置
    • 响应滚动位置
    • 响应列表项侧滑
    • 给列表项添加标记
    • 下拉刷新与上拉加载
    • 长列表的处理
  • 网格
    • 设置排列方式
      • 设置行列数量与占比
      • 设置子组件所占行列数
      • 设置行列间距

列表

List组件的子组件为ListItemGroup或者ListItem,List组件支持使用条件渲染、循环渲染、懒加载等渲染控制方式生成子组件。

在这里插入图片描述

布局与约束

List除了提供水平与垂直的单列列表以外,还可以实现多列列表的功能。
Grid和WaterFlow也可以实现单列、多列布局,如果布局每列等宽,且不需要跨行跨列布局,相比Grid和WaterFlow,则更推荐使用List。
在这里插入图片描述
在这里插入图片描述

设置主轴方向

通过List的listDirection方法可以设置主轴方向。默认为Axis.Vertical。

List() {// ...
}
.listDirection(Axis.Horizontal)

设置交叉轴布局

List组件的交叉轴布局可以通过lanesalignListItem方法进行设置。

lanes

lanes属性用于确定交叉轴排列的列表项数量。

lanes属性通常用于在不同尺寸的设备上自适应构建不同行数或者列数的列表。lanes属性的取值是number|LengthConstrain,number类型表示该List为几列列表,而LengthConstrain则不太一样,设置的是List子组件的最小宽度和最大宽度。

List() {// ...
}
.lanes(2)
@Entry
@Component
struct EgLanes {@State egLanes: LengthConstrain = { minLength: 200, maxLength: 300 }build() {List() {// ...}.lanes(this.egLanes)}
}

上边代码中,List组件的lanes值为{minLength:200,maxLength:300}

  • 当List组件的宽度为300时,由于minLength为200,此时列表为一列。
  • 当List组件的宽度为400时,符合minLength的两倍,则此时列表为两列。
alignListItem

alignListItem用于设置子组件在交叉轴方向的对齐方式。

List() {// ...
}
.alignListItem(ListItemAlign.Center)

自定义列表样式

设置内容间距

在初始化列表的时候,可以通过space参数,在列表项之间添加间距。

List({ space: 10 }) {// ...
}

添加分隔线

List提供了divider属性用于给列表项之间添加分隔线。
在driver属性中,strokeWidth用于控制分隔线的粗细,color用于设置分隔线的颜色。startMarginendMargin用于设置分隔线起始端和末端的距离。

List() {// ...}.divider({ strokeWidth:1,color:'#ffe9f0f0',startMargin:10,endMargin:0 })

添加滚动条

在使用List组件时,可通过scrollBar属性控制列表滚动条的显示。

List() {// ...
}
.scrollBar(BarState.Auto)

支持分组列表

在List组件中使用ListItemGrounp对项目进行分组,可以创建二维列表。
在List组件中可以使用一个或者多个ListItemGrounp组件,ListItemGrounp的宽度默认充满List组件。
在初始化ListItemGrounp时,可以通过header参数设置列表分组的头部组件。

@Entry
@Component
struct ContactsList {@Builder itemHead(text: string) {// 列表分组的头部组件,对应联系人分组A、B等位置的组件Text(text).fontSize(20).backgroundColor('#fff1f3f5').width('100%').padding(5)}build() {List() {ListItemGroup({ header: this.itemHead('A') }) {// 循环渲染分组A的ListItem}ListItemGroup({ header: this.itemHead('B') }) {// 循环渲染分组B的ListItem}}}
}

添加粘性标题

List组件的sticky属性配合ListItemGrounp组件使用,用于设置ListItemGrounp中的头部组件是否呈现吸顶效果或者尾部组件是否呈现吸顶效果。

通过给List组件设置sticky属性为StickyStyle.Header,即可实现列表的粘性标题效果。如果需要支持吸底效果,可以通过footer参数初始化ListItemGroup的底部组件,并将sticky属性设置为StickyStyle.Footer。

import { util } from '@kit.ArkTS'
class Contact {key: string = util.generateRandomUUID(true);name: string;icon: Resource;constructor(name: string, icon: Resource) {this.name = name;this.icon = icon;}
}
class ContactsGroup {title: string = ''contacts: Array<object> | null = nullkey: string = ""
}
export let contactsGroups: object[] = [{title: 'A',contacts: [new Contact('艾佳', $r('app.media.iconA')),new Contact('安安', $r('app.media.iconB')),new Contact('Angela', $r('app.media.iconC')),],key: util.generateRandomUUID(true)} as ContactsGroup,{title: 'B',contacts: [new Contact('白叶', $r('app.media.iconD')),new Contact('伯明', $r('app.media.iconE')),],key: util.generateRandomUUID(true)} as ContactsGroup,// ...
]
@Entry
@Component
struct ContactsList {// 定义分组联系人数据集合contactsGroups数组@Builder itemHead(text: string) {// 列表分组的头部组件,对应联系人分组A、B等位置的组件Text(text).fontSize(20).backgroundColor('#fff1f3f5').width('100%').padding(5)}build() {List() {// 循环渲染ListItemGroup,contactsGroups为多个分组联系人contacts和标题title的数据集合ForEach(contactsGroups, (itemGroup: ContactsGroup) => {ListItemGroup({ header: this.itemHead(itemGroup.title) }) {// 循环渲染ListItemif (itemGroup.contacts) {ForEach(itemGroup.contacts, (item: Contact) => {ListItem() {// ...}}, (item: Contact) => JSON.stringify(item))}}}, (itemGroup: ContactsGroup) => JSON.stringify(itemGroup))}.sticky(StickyStyle.Header)  // 设置吸顶,实现粘性标题效果}
}

请添加图片描述

控制滚动位置

List组件初始化时,可以通过scroller参数绑定一个Scroller对象,进行列表的滚动控制。

private listScroller: Scroller = new Scroller();Stack({ alignContent: Alignment.Bottom }) {// 将listScroller用于初始化List组件的scroller参数,完成listScroller与列表的绑定。List({ space: 20, scroller: this.listScroller }) {// ...}Button() {// ...}.onClick(() => {// 点击按钮时,指定跳转位置,返回列表顶部this.listScroller.scrollToIndex(0)})
}

响应滚动位置

List可以通过onScrollIndex事件来监听当前滚动位置,根据滚动位置去做一系列的处理。

计算索引值时,ListItemGroup作为一个整体占一个索引值,不计算ListItemGroup内部ListItem的索引值。

const alphabets = ['#', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K','L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
@Entry
@Component
struct ContactsList {@State selectedIndex: number = 0;private listScroller: Scroller = new Scroller();build() {Stack({ alignContent: Alignment.End }) {List({ scroller: this.listScroller }) {}.onScrollIndex((firstIndex: number) => {// 根据列表滚动到的索引值,重新计算对应联系人索引栏的位置this.selectedIndex})// 字母表索引组件AlphabetIndexer({ arrayValue: alphabets, selected: 0 }).selected(this.selectedIndex)}}
}

响应列表项侧滑

ListItem的swipeAction属性可用于实现列表项的左右滑动功能。

  1. 实现滑出组件的构建。
    @Builder itemEnd(index: number) {// 构建尾端滑出组件Button({ type: ButtonType.Circle }) {Image($r('app.media.ic_public_delete_filled')).width(20).height(20)}.onClick(() => {// this.messages为列表数据源,可根据实际场景构造。点击后从数据源删除指定数据项。this.messages.splice(index, 1);})
    }
    
  2. 绑定swipeAction属性到ListItem上。
    swipeAction属性方法初始化时的必填参数是SwipeActionOptions,SwipeActionOptions中start表示设置列表右滑时滑出的组件,end参数表示设置列表左滑时滑出的组件。
    // 构建List时,通过ForEach基于数据源this.messages循环渲染ListItem。
    ListItem() {// ...
    }
    .swipeAction({end: {// index为该ListItem在List中的索引值。builder: () => { this.itemEnd(index) },}
    }) // 设置侧滑属性.
    

给列表项添加标记

在ListItem中使用Badge组件可以给列表项添加标记功能。**Badge是可以附加在单个组件上用于信息标记的容器组件。**所以当希望某个组件上有标记时,需要将Badge组件,作为该组件的父容器使用。

在Badge组件中,countposition参数用于设置需要展示的消息数量和提示点显示位置,style参数设置标记的样式。

ListItem() {Badge({count: 1,position: BadgePosition.RightTop,style: { badgeSize: 16, badgeColor: '#FA2A2D' }}) {// Image组件实现消息联系人头像// ...}
}

下拉刷新与上拉加载

List的下拉刷新和上拉加载可以通过监听List的触摸事件来实现。

由于List中只支持ListItem和ListItemGrounp子组件,所以下拉刷新和上拉加载的布局文件,无法直接添加到List组件中,我们需要在List组件中添加一个单独的ListItem组件,作为List组件的唯一子组件,在ListItem中,再依次添加下拉刷新的头布局,循环渲染列表的真正的ListItem,然后添加上拉加载的组件。

@Builder ListLayout() {List() {ListItem() {RefreshLayout({refreshLayoutClass: new CustomRefreshLoadLayoutClass(this.newsModel.isVisiblePullDown, this.newsModel.pullDownRefreshImage,this.newsModel.pullDownRefreshText, this.newsModel.pullDownRefreshHeight)})}ForEach(this.newsModel.newsData, (item: NewsData) => {ListItem() {NewsItem({ newsData: item })}...}, (item: NewsData, index?: number) => JSON.stringify(item) + index)ListItem() {if (this.newsModel.hasMore) {LoadMoreLayout({loadMoreLayoutClass: new CustomRefreshLoadLayoutClass(this.newsModel.isVisiblePullUpLoad, this.newsModel.pullUpLoadImage,this.newsModel.pullUpLoadText, this.newsModel.pullUpLoadHeight)})} else {NoMoreLayout()}}}...
}

监听onTouch事件,根据滑动方向距离等因素,确定需要显示的布局。

长列表的处理

当列表项较长时,使用forEach循环渲染的方式,会一次性加载所有的列表元素,对性能开销较大。
可以使用数据懒加载的方式,即LayForEach实现按需迭代加载数据,提升用户体验。

在List组件中,提供了cachedCount方法用来设置列表缓存数量,该数量表示会在List当前显示的ListItem前后各缓存一定数量的ListItem,超出该数量的会被销毁,该设置项只在LazyForEach中生效

网格

ArkUI提供了Grid容器组件和子组件GridItem,用于构建网格布局。Grid用于设置网格布局相关参数,GridItem定义子组件相关特征。Grid组件支持使用条件渲染、循环渲染、懒加载等方式生成子组件。

在这里插入图片描述
网格布局是一种二维布局。Grid组件支持自定义行列数和每行每列尺寸占比、设置子组件横跨几行或者几列,同时提供了垂直和水平布局能力。当网格容器组件尺寸发生变化时,所有子组件以及间距会等比例调整,从而实现网格布局的自适应能力。根据Grid的这些布局能力,可以构建出不同样式的网格布局,如下图所示。

在这里插入图片描述
如果Grid组件设置了宽高属性,则其尺寸为设置值。如果没有设置宽高属性,Grid组件的尺寸默认适应其父组件的尺寸。

Grid组件根据行列数量与占比属性的设置,可以分为三种布局情况:

  • 行、列数量与占比同时设置:Grid只展示固定行列数的元素,其余元素不展示,且Grid不可滚动。(推荐使用该种布局方式)

  • 只设置行、列数量与占比中的一个:元素按照设置的方向进行排布,超出的元素可通过滚动的方式展示。

  • 行列数量与占比都不设置:元素在布局方向上排布,其行列数由布局方向、单个网格的宽高等多个属性共同决定。超出行列容纳范围的元素不展示,且Grid不可滚动。

设置排列方式

设置行列数量与占比

Grid组件提供了rowTemplatecolumnsTemplate属性用于设置网格布局行列数量和尺寸占比

rowsTemplate和columnsTemplate属性值是一个由多个空格和’数字+fr’间隔拼接的字符串,fr的个数即网格布局的行或列数,fr前面的数值大小,用于计算该行或列在网格布局宽度上的占比,最终决定该行或列宽度。

Grid() {...
}
.rowsTemplate('1fr 1fr 1fr')
.columnsTemplate('1fr 2fr 1fr')

在这里插入图片描述

设置子组件所占行列数

在Grid组件中,可以通过创建Grid时传入layoutOptions参数来实现跨多行或者多列的场景。

其中irregularIndexesonGetIrregularSizeByIndex可对仅设置rowsTemplate或columnsTemplate的Grid使用。
onGetRectByIndex可对同时设置rowsTemplate和columnsTemplate的Grid使用。

以onGetRectByIndex举例,可以根据index设置对应的跨行列布局,返回数据为[rowStart,columnStart,rowSpan,columnSpan]。其中rowStart和columnStart属性表示指定当前元素的起始index和起始列index,rowSpan和columnSpan表示指定当前元素所占用的行和列的数量。

layoutOptions: GridLayoutOptions = {regularSize: [1, 1],onGetRectByIndex: (index: number) => {if (index == key1) { // key1是“0”按键对应的indexreturn [5, 0, 1, 2]} else if (index == key2) { // key2是“=”按键对应的indexreturn [4, 3, 2, 1]}// ...// 这里需要根据具体布局返回其他item的位置}
}Grid(undefined, this.layoutOptions) {// ...
}
.columnsTemplate('1fr 1fr 1fr 1fr')
.rowsTemplate('2fr 1fr 1fr 1fr 1fr 1fr')

在这里插入图片描述

设置行列间距

Grid中,通过rowsGapcolumnsGap可以设置网格布局的行列间距。

Grid() {...
}
.columnsGap(10)
.rowsGap(15)

这篇关于ArkUI-布局(三)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1116802

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

lvgl8.3.6 控件垂直布局 label控件在image控件的下方显示

在使用 LVGL 8.3.6 创建一个垂直布局,其中 label 控件位于 image 控件下方,你可以使用 lv_obj_set_flex_flow 来设置布局为垂直,并确保 label 控件在 image 控件后添加。这里是如何步骤性地实现它的一个基本示例: 创建父容器:首先创建一个容器对象,该对象将作为布局的基础。设置容器为垂直布局:使用 lv_obj_set_flex_flow 设置容器

Apache Tiles 布局管理器

陈科肇 =========== 1.简介 一个免费的开源模板框架现代Java应用程序。  基于该复合图案它是建立以简化的用户界面的开发。 对于复杂的网站,它仍然最简单,最优雅的方式来一起工作的任何MVC技术。 Tiles允许作者定义页面片段可被组装成在运行一个完整的网页。  这些片段,或Tiles,可以用于为了降低公共页面元素的重复,简单地包括或嵌入在其它瓦片,制定了一系列可重复使用

【CSS in Depth 2 精译_023】第四章概述 + 4.1 Flexbox 布局的基本原理

当前内容所在位置(可进入专栏查看其他译好的章节内容) 第一章 层叠、优先级与继承(已完结) 1.1 层叠1.2 继承1.3 特殊值1.4 简写属性1.5 CSS 渐进式增强技术1.6 本章小结 第二章 相对单位(已完结) 2.1 相对单位的威力2.2 em 与 rem2.3 告别像素思维2.4 视口的相对单位2.5 无单位的数值与行高2.6 自定义属性2.7 本章小结 第三章 文档流与盒模型(已

ConstraintLayout布局里的一个属性app:layout_constraintDimensionRatio

ConstraintLayout 这是一个约束布局,可以尽可能的减少布局的嵌套。有一个属性特别好用,可以用来动态限制宽或者高app:layout_constraintDimensionRatio 关于app:layout_constraintDimensionRatio参数 app:layout_constraintDimensionRatio=“h,1:1” 表示高度height是动态变化

html记账本改写:数据重新布局,更好用了,没有localStorage保存版本

<!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><title>htm记账本</title><style>table {user-select: none;/* width: 100%; */border-collapse: collapse;}table,th,td {border: 1px solid bla

Qt-常用控件(3)-多元素控件、容器类控件和布局管理器

1. 多元素控件 Qt 中提供的多元素控件有: QListWidgetQListViewQTableWidgetQTableViewQTreeWidgetQTreeView xxWidget 和 xxView 之间的区别,以 QTableWidget 和 QTableView 为例. QTableView 是基于 MVC 设计的控件.QTableView 自身不持有数据,使用 QTab

【CSS】flex布局 - 左边超过打点, 右边完整展示

场景:宽度一定的情况下右边自适应,左边被挤压。 需要的效果如下: flex 的三个参数分别对应:flex-grow、flex-shrink、flex-basis。 flex-grow:定义项目的放大比例,默认为0。即如果存在剩余空间,也不放大。flex-shrink:定义项目的缩小比例,默认为1。即如果空间不足,该项目将缩小。flex-basis:定义在分配多余空间之前,项目占据的主轴空间。

”CSS 网格“二维布局系统(补充)——WEB开发系列32

CSS 网格布局是一种二维布局系统,用于网页设计。通过使用网格,你可以将内容以行和列的形式进行排列。此外,网格布局还能够简便地实现一些复杂的布局结构。 一、什么是网格布局? CSS网格布局是一种二维布局系统,它允许我们创建复杂的网页布局,既可以处理行也可以处理列。与传统的布局方法不同,网格布局将网页分成多个可控的区域,这些区域可以任意排列、对齐和调整大小。网格布局使得创建灵活且响应

鸿蒙开发入门day06-ArkUI简介

(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,还请三连支持一波哇ヾ(@^∇^@)ノ) 目录 ArkUI简介 基本概念 两种开发范式 不同应用类型支持的开发范式 UI开发(ArkTS声明式开发范式)概述 特点 整体架构 开发布局 布局结构 布局元素的组成 布局位置 对子元素的约束 ArkUI简介 ArkUI(方舟UI框架)为应用