dede手机医院网站模板下载,糖果果屋网站建设规划书,浙江建设厅网站,wordpress 10万pv目录
1、概述
2、布局与约束
3、设置排列方式
3.1设置行列数量与占比
3.2、设置子组件所占行列数
3.3、设置主轴方向 3.4、在网格布局中显示数据
3.5、设置行列间距
4、构建可滚动的网格布局
5、实现简单的日历功能
6、性能优化 1、概述 网格布局是由“行”和“列”分…目录
1、概述
2、布局与约束
3、设置排列方式
3.1设置行列数量与占比
3.2、设置子组件所占行列数
3.3、设置主轴方向 3.4、在网格布局中显示数据
3.5、设置行列间距
4、构建可滚动的网格布局
5、实现简单的日历功能
6、性能优化 1、概述 网格布局是由“行”和“列”分割的单元格所组成通过指定“项目”所在的单元格做出各种各样的布局。网格布局具有较强的页面均分能力子组件占比控制能力是一种重要自适应布局其使用场景有九宫格图片展示、日历、计算器等。 ArkUI提供了Grid容器组件和子组件GridItem用于构建网格布局。Grid用于设置网格布局相关参数GridItem定义子组件相关特征。Grid组件支持使用条件渲染、循环渲染、懒加载等渲染控制方式生成子组件。
2、布局与约束 Grid组件为网格容器其中容器内每一个条目对应一个GridItem组件如下图所示。
图1 Grid与GridItem组件关系 说明 Grid的子组件必须是GridItem组件。 网格布局是一种二维布局。Grid组件支持自定义行列数和每行每列尺寸占比、设置子组件横跨几行或者几列同时提供了垂直和水平布局能力。当网格容器组件尺寸发生变化时所有子组件以及间距会等比例调整从而实现网格布局的自适应能力。根据Grid的这些布局能力可以构建出不同样式的网格布局如下图所示。
图2 网格布局 如果Grid组件设置了宽高属性则其尺寸为设置值。如果没有设置宽高属性Grid组件的尺寸默认适应其父组件的尺寸。
Grid组件根据行列数量与占比属性的设置可以分为三种布局情况
行、列数量与占比同时设置Grid只展示固定行列数的元素其余元素不展示且Grid不可滚动。推荐使用该种布局方式只设置行、列数量与占比中的一个元素按照设置的方向进行排布超出的元素可通过滚动的方式展示。行列数量与占比都不设置元素在布局方向上排布其行列数由布局方向、单个网格的宽高等多个属性共同决定。超出行列容纳范围的元素不展示且Grid不可滚动。
3、设置排列方式 3.1设置行列数量与占比 通过设置行列数量与尺寸占比可以确定网格布局的整体排列方式。Grid组件提供了rowsTemplate和columnsTemplate属性用于设置网格布局行列数量与尺寸占比。 rowsTemplate和columnsTemplate属性值是一个由多个空格和数字fr间隔拼接的字符串fr的个数即网格布局的行或列数fr前面的数值大小用于计算该行或列在网格布局宽度上的占比最终决定该行或列的宽度。
图3 行列数量占比示例 如上图所示构建的是一个三行三列的的网格布局其在垂直方向上分为三等份每行占一份在水平方向上分为四等份第一列占一份第二列占两份第三列占一份。 只要将rowsTemplate的值为1fr 1fr 1fr同时将columnsTemplate的值为1fr 2fr 1fr即可实现上述网格布局。
Entry
Component
struct GridLayoutPage1 {State message: string Hello Worldbuild() {Row() {Column() {Grid() {GridItem() {Text(1).gridTextStyle(#1067c8ff)}GridItem() {Text(2).gridTextStyle(#2067c8ff)}GridItem() {Text(3).gridTextStyle(#3067c8ff)}GridItem() {Text(4).gridTextStyle(#4067c8ff)}GridItem() {Text(5).gridTextStyle(#5067c8ff)}GridItem() {Text(6).gridTextStyle(#6067c8ff)}GridItem() {Text(7).gridTextStyle(#7067c8ff)}GridItem() {Text(8).gridTextStyle(#8067c8ff)}GridItem() {Text(9).gridTextStyle(#9067c8ff)}}.rowsTemplate(1fr 1fr 1fr).columnsTemplate(1fr 2fr 1fr)}.width(100%)}.height(40%)}
}Extend(Text) function gridTextStyle(value: ResourceColor) {.backgroundColor(value).width(100%).height(100%).fontSize(22).textAlign(TextAlign.Center)
} 效果如下 3.2、设置子组件所占行列数 除了大小相同的等比例网格布局由不同大小的网格组成不均匀分布的网格布局场景在实际应用中十分常见如下图所示。在Grid组件中通过设置GridItem的rowStart、rowEnd、columnStart和columnEnd可以实现如图所示的单个网格横跨多行或多列的场景。
图4 不均匀网格布局 例如计算器的按键布局就是常见的不均匀网格布局场景。如下图计算器中的按键“0”和“”按键“0”横跨第一、二两列按键“”横跨第五、六两行。使用Grid构建的网格布局其行列标号从1开始依次编号。
图5 计算器 在单个网格单元中rowStart和rowEnd属性表示指定当前元素起始行号和终点行号columnStart和columnEnd属性表示指定当前元素的起始列号和终点列号。 所以“0”按键横跨第一列和第二列只要将“0”对应GridItem的columnStart和columnEnd设为1和2将“”对应GridItem的的rowStart和rowEnd设为5和6即可。 “”按键横跨第五行和第六行只要将将“”对应GridItem的的rowStart和rowEnd设为5和6即可。
Entry
Component
struct CalculatorLayoutPage {State message: string Hello Worldbuild() {Row() {Column() {Grid() {GridItem() {Text(0).gridTextStyle2(#1067c8ff).textAlign(TextAlign.End).padding(2)}.rowStart(0).rowEnd(1).columnStart(0).columnEnd(3)GridItem() {Text(CE).gridTextStyle2(#2067c8ff)}GridItem() {Text(C).gridTextStyle2(#3067c8ff)}GridItem() {Text(/).gridTextStyle2(#4067c8ff)}GridItem() {Text(X).gridTextStyle2(#5067c8ff)}GridItem() {Text(7).gridTextStyle2(#6067c8ff)}GridItem() {Text(8).gridTextStyle2(#7067c8ff)}GridItem() {Text(9).gridTextStyle2(#8067c8ff)}GridItem() {Text(-).gridTextStyle2(#9067c8ff)}GridItem() {Text(4).gridTextStyle2(#A067c8ff)}GridItem() {Text(5).gridTextStyle2(#B067c8ff)}GridItem() {Text(6).gridTextStyle2(#C067c8ff)}GridItem() {Text().gridTextStyle2(#D067c8ff)}GridItem() {Text(1).gridTextStyle2(#E067c8ff)}GridItem() {Text(2).gridTextStyle2(#F067c8ff)}GridItem() {Text(3).gridTextStyle2(#F167c8ff)}GridItem() {Text().gridTextStyle2(#F267c8ff)}.rowStart(5).rowEnd(6).columnStart(3).columnEnd(3)GridItem() {Text(0).gridTextStyle2(#F367c8ff)}.columnStart(0).columnEnd(1)GridItem() {Text(.).gridTextStyle2(#F467c8ff)}}.margin(12).rowsGap(12).columnsGap(8).rowsTemplate(1fr 1fr 1fr 1fr 1fr 1fr 1fr).columnsTemplate(1fr 1fr 1fr 1fr)}.width(100%)}.height(80%)}
}Extend(Text) function gridTextStyle2(value: ResourceColor) {.backgroundColor(value).width(100%).height(100%).fontSize(40).textAlign(TextAlign.Center).borderRadius(5)
} 效果如下 3.3、设置主轴方向 使用Grid构建网格布局时若没有设置行列数量与占比可以通过layoutDirection可以设置网格布局的主轴方向决定子组件的排列方式。此时可以结合minCount和maxCount属性来约束主轴方向上的网格数量。
图6 主轴方向示意图 当前layoutDirection设置为Row时先从左到右排列排满一行再排一下一行。当前layoutDirection设置为Column时先从上到下排列排满一列再排一下一列如上图所示。此时将maxCount属性设为3表示主轴方向上最大显示的网格单元数量为3。
Entry
Component
struct GridLayoutPage2 {State array: Arraystring [1, 2, 3, 4, 5, 6, 7, 8, 9]build() {Row() {Column() {Grid() {ForEach(this.array, (item: string, index) {GridItem() {Text(item).gridTextStyle_page2(#67c8ff)}}, item item)}.rowsGap(12).columnsGap(8).margin(4).maxCount(3).minCount(3).layoutDirection(GridDirection.Column)}.width(100%)}.height(40%)}
}Extend(Text) function gridTextStyle_page2(value: ResourceColor) {.backgroundColor(value).width(30%).height(30%).fontSize(22).textAlign(TextAlign.Center)
} 效果如下 说明 1. layoutDirection属性仅在不设置rowsTemplate和columnsTemplate时生效此时元素在layoutDirection方向上排列。 2. 仅设置rowsTemplate时Grid主轴为水平方向交叉轴为垂直方向。 2. 仅设置columnsTemplate时Grid主轴为垂直方向交叉轴为水平方向。 3.4、在网格布局中显示数据 网格布局采用二维布局的方式组织其内部元素如下图所示。
图7 通用办公服务 Grid组件可以通过二维布局的方式显示一组GridItem子组件。
Entry
Component
struct GridLayoutPage3 {State message: string Hello Worldbuild() {Row() {Column() {Grid() {GridItem() {Text(会议)}.backgroundColor(#1067c8ff)GridItem() {Text(签到)}.backgroundColor(#3067c8ff)GridItem() {Text(培训)}.backgroundColor(#5067c8ff)GridItem() {Text(打印)}.backgroundColor(#7067c8ff)}.rowsTemplate(1fr 1fr).columnsTemplate(1fr 1fr)}.width(100%).height(40%)}.height(100%).alignItems(VerticalAlign.Top)}
} 对于内容结构相似的多个GridItem通常更推荐使用循环渲染ForEach语句中嵌套GridItem的形式来减少重复代码。
Entry
Component
struct GridLayoutPage3 {State message: Bean[] [{ title: 会议, color: #1067c8ff },{ title: 签到, color: #3067c8ff },{ title: 培训, color: #5067c8ff },{ title: 打印, color: #7067c8ff }]build() {Row() {Column() {Grid() {ForEach(this.message, (item: Bean) {GridItem() {Text(item.title).backgroundColor(item.color).width(100%).height(100%).textAlign(TextAlign.Center)}}, item JSON.stringify(item))}.rowsTemplate(1fr 1fr).columnsTemplate(1fr 1fr)}.width(100%).height(40%)}.height(100%).alignItems(VerticalAlign.Top)}
}class Bean {title: stringcolor: ResourceColor
} 效果同上。
3.5、设置行列间距 在两个网格单元之间的网格横向间距称为行间距网格纵向间距称为列间距如下图所示。
图8 网格的行列间距 通过Grid的rowsGap和columnsGap可以设置网格布局的行列间距。
Entry
Component
struct GridLayoutPage3 {State message: Bean[] [{ title: 会议, color: #1067c8ff },{ title: 签到, color: #3067c8ff },{ title: 培训, color: #5067c8ff },{ title: 打印, color: #7067c8ff }]build() {Row() {Column() {Grid() {ForEach(this.message, (item: Bean) {GridItem() {Text(item.title).backgroundColor(item.color).width(100%).height(100%).textAlign(TextAlign.Center)}}, item JSON.stringify(item))}.rowsTemplate(1fr 1fr).columnsTemplate(1fr 1fr).rowsGap(10).columnsGap(10).margin(10)}.width(100%).height(40%).backgroundColor(#eee)}.height(100%).alignItems(VerticalAlign.Top)}
}class Bean {title: stringcolor: ResourceColor
} 效果如下 4、构建可滚动的网格布局 可滚动的网格布局常用在文件管理、购物或视频列表等页面中如下图所示。在设置Grid的行列数量与占比时如果仅设置行、列数量与占比中的一个即仅设置rowsTemplate或仅设置columnsTemplate属性网格单元按照设置的方向排列超出Grid显示区域后Grid拥有可滚动能力。
图9 横向可滚动网格布局 如果设置的是columnsTemplateGrid的滚动方向为垂直方向如果设置的是rowsTemplateGrid的滚动方向为水平方向。 如上图所示的横向可滚动网格布局只要设置rowsTemplate属性的值且不设置columnsTemplate属性当内容超出Grid组件宽度时Grid可横向滚动进行内容展示。
Entry
Component
struct GridScrollLayoutPage {State services: Arraystring [直播, 进口, 国外, 乡里, 本地, A, B, C, D, E, F, G, H, I]color: ResourceColor[] [Color.Blue, Color.Green, Color.Orange, Color.Pink, Color.Yellow]build() {Column({ space: 5 }) {Grid() {ForEach(this.services, (service: string, index) {GridItem() {Text(service).backgroundColor(this.color[index % this.color.length]).fontColor(Color.White).width(72).height(72).fontSize(24).borderRadius(8).textAlign(TextAlign.Center).borderRadius(36)}.width(25%)}, service service)}.rowsTemplate(1fr 1fr) // 只设置rowsTemplate属性当内容超出Grid区域时可水平滚动。.rowsGap(15).columnsGap(12).height(25%)}.borderColor(Color.Pink).borderWidth(1).borderRadius(8).margin(8).backgroundColor(#1067c8ff)}
}
5、实现简单的日历功能
import hilog from ohos.hilog;Entry
Component
struct CalendarLayoutPage {private scroller: Scroller new Scroller()private headLabel: string[] [一, 二, 三, 四, 五, 六, 日]private curDate: Date;State curDateStr: string State dateArray: number[] []aboutToAppear() {let date new Date();this.curDate date;this.changeMonthData()}changeMonthData() {let monthLength this.getMonthLength(this.curDate);this.dateArray []for (let index 0; index monthLength; index) {this.dateArray.push(index 1)}this.curDateStr ${this.curDate.getFullYear()}-${this.curDate.getMonth() 1}}private nextMonth() {this.curDate.setMonth(this.curDate.getMonth() 1)}private prevMonth() {this.curDate.setMonth(this.curDate.getMonth() - 1)}private getMonthLength(date: Date): number {let copyDate new Date(date.getFullYear(), date.getMonth() 1, 0)return copyDate.getDate()}build() {Row() {Column() {Text(this.curDateStr).backgroundColor(Color.Pink).fontColor(Color.White).height(48).padding({ left: 24, right: 24 }).borderRadius(24)Row({ space: 8 }) {ForEach(this.headLabel, (item) {Text(item).fontSize(14).layoutWeight(1).textAlign(TextAlign.Center).height(40%).borderRadius(26).backgroundColor(#67c8ff)}, item JSON.stringify(item))}.height(52).backgroundColor(#999).margin({top: 24})Grid() {ForEach(this.dateArray, (item) {GridItem() {Button(item ).width(52).height(52).borderWidth(1).borderColor(#67c8ff)}}, item JSON.stringify(item))}.columnsTemplate(1fr 1fr 1fr 1fr 1fr 1fr 1fr).columnsGap(5).rowsGap(5).margin({ top: 12 }).height(40%)Row({ space: 20 }) {Button(上一页).onClick(() {this.prevMonth()this.changeMonthData()// this.scroller.scrollPage({// next: false// })})Button(下一页).onClick(() {this.nextMonth()this.changeMonthData()// this.scroller.scrollPage({// next: true// })})}}.width(100%).backgroundColor(#eee).borderRadius(24)}.height(100%).alignItems(VerticalAlign.Top).margin({top: 48, left: 12, right: 12})}
} 通过 State dateArray来刷新UI当点击前一页的时候当前月份减少1然后改变dateArray的数据触发UI更新点击下一页同理。效果如下 6、性能优化 与长列表的处理类似循环渲染适用于数据量较小的布局场景当构建具有大量网格项的可滚动网格布局时推荐使用数据懒加载方式实现按需迭代加载数据从而提升列表性能。 关于按需加载优化的具体实现可参考数据懒加载章节中的示例。 当使用懒加载方式渲染网格时为了更好的滚动体验减少滑动时出现白块Grid组件中也可通过cachedCount属性设置GridItem的预加载数量只在懒加载LazyForEach中生效。 设置预加载数量后会在Grid显示区域前后各缓存cachedCount*列数个GridItem超出显示和缓存范围的GridItem会被释放。 Grid() {LazyForEach(this.dataSource, item {GridItem() {...}})
}
.cachedCount(3) 说明 cachedCount的增加会增大UI的CPU、内存开销。使用时需要根据实际情况综合性能和用户体验进行调整。