鸿蒙进阶篇-网格布局 Grid/GridItem(二)
hello大家好,这里是鸿蒙开天组,今天让我们来继续学习鸿蒙进阶篇-网格布局 Grid/GridItem,上一篇博文我们已经学习了固定行列、合并行列和设置滚动,这一篇我们将继续学习Grid的用法,实现翻页滚动、自定义滚动条样式,并实现一个小案例。
1.翻页滚动
到这里就需要用到控制器对象了,核心步骤如下:
- 创建 Scroller 对象(控制器对象)
- 设置给 Grid
- 调用 Scroller 对象的 scrollPage 方法
// 1.创建 Scroller 对象(new 关键字,调用Scroller函数,返回一个Scroller的对象)
scroller: Scroller = new Scroller()
// 2.设置给 Grid:这个属性可选,所以之前不设置也不会报错
Grid(this.scroller) {
// ...
}
// 3.调用 Scroller 对象的 scrollPage 方法即可实现滚动
this.scroller.scrollPage({
next:true // 下一页
next:false // 上一页
})
属于一看就会的代码,于是实现一个翻页滚动效果,当然也可以左右滑动啦:
实现代码如下:
@Entry
@Component
struct test_Grid {
// 控制器对象,不是状态属性,不需要添加任何修饰符
scroller: Scroller = new Scroller()
build() {
Column() {
Text('控制器-实现翻页滚动')
.fontSize(20)
.fontWeight(900)
.padding(10)
Grid(this.scroller) {
ForEach(Array.from({ length: 200 }), (item: number, index: number) => {
GridItem() {
Text(index + 1 + '').fontColor(Color.Orange)
}
.backgroundColor(Color.Green)
.width('25%')
})
}
.padding(10)
.height(450)
.rowsGap(10)
.columnsGap(10)
.rowsTemplate('1fr 1fr 1fr 1fr')
Row() {
Button('上一页')
.width(100)
.onClick(() => {
// 上一页
this.scroller.scrollPage({ next: false })
})
Button('下一页')
.width(100)
.onClick(() => {
// 下一页
this.scroller.scrollPage({ next: true })
})
}
.width('100%')
.justifyContent(FlexAlign.SpaceAround)
}
}
}
2.自定义滚动条
滚动条组件ScrollBar,用于配合可滚动组件使用,如List、Grid、Scroll,如果默认的滚动条外观无法满足需求,我们还可以自定义滚动条:
第一步:首先通过 Grid 的 scrollBar 属性关闭滚动条
属性名 | 类型 | 说明 |
scrollBar | BarState | 设置滚动条状态。 默认值:BarState.auto BarState.off 关闭 BarState.on 常驻 BarState.auto 按需显示 |
第二步:使用ScrollBar组件自定义滚动条
参数名 | 参数类型 | 必填 | 参数描述 |
scroller | Scroller | 是 | 可滚动组件的控制器。用于与可滚动组件进行绑定。 |
direction | ScrollBarDirection | 否 | 滚动条的方向,控制可滚动组件对应方向的滚动。 默认值:ScrollBarDirection.Vertical |
state | BarState | 否 | 滚动条状态。 |
样例关键代码如下:
// 创建控制器对象
scroller: Scroller = new Scroller()
// 设置给 Grid 组件
Grid(this.scroller){
// 略
}
// 设置给 ScrollBar 组件
// 和 Grid 设置的是同一个
ScrollBar({
scroller: this.scroller,
direction: ScrollBarDirection.Horizontal // 方向
}) {
// 滚动内容 设置外观即可
Text()
}
// 设置外观
在上面代码的基础上,先来一个看着丑但足够显眼的滚动条:
代码如下:
@Entry
@Component
struct test_Grid {
// 控制器对象,不是状态属性,不需要添加任何修饰符
scroller: Scroller = new Scroller()
build() {
Column() {
Text('控制器-实现翻页滚动')
.fontSize(20)
.fontWeight(900)
.padding(10)
Grid(this.scroller) {
ForEach(Array.from({ length: 200 }), (item: number, index: number) => {
GridItem() {
Text(index + 1 + '').fontColor(Color.Orange)
}
.backgroundColor(Color.Green)
.width('25%')
})
}
.padding(10)
.height(450)
.rowsGap(10)
.columnsGap(10)
.rowsTemplate('1fr 1fr 1fr 1fr')
.scrollBar(BarState.Off)
// 自定义滚动条
ScrollBar({
scroller: this.scroller, // 和 Grid 同一个控制器对象
direction: ScrollBarDirection.Horizontal,
}) {
Text()
.width(40)
.height(20)
.backgroundColor(Color.Orange)
}
.width(200)
.height(20)
.backgroundColor(Color.Red)
Row() {
Button('上一页')
.width(100)
.onClick(() => {
// 上一页
this.scroller.scrollPage({ next: false })
})
Button('下一页')
.width(100)
.onClick(() => {
// 下一页
this.scroller.scrollPage({ next: true })
})
}
.width('100%')
.justifyContent(FlexAlign.SpaceAround)
}
}
}
3.小案例
最后,使用刚刚学习的自定义滚动条来完成滚动导航的滚动条:
嘿!一个丝滑又漂亮的滚动条就出来啦,注意咱们这里主要是做的滚动条,具体图标填充,可以自行使用其他图片测试哦!
代码如下:
interface XMNavItem {
title: string
icon: ResourceStr // 联合属性 Resource | string
}
@Entry
@Component
struct test_Grid {
// 数据 只需要渲染,所以没有使用@State 修饰
navList: XMNavItem[] = [
{ title: '上新精选', icon: $r('app.media.foreground') },
{ title: '智能家电', icon: $r('app.media.background') },
{ title: '小米众筹', icon: $r('app.media.startIcon') },
{ title: '有品会员', icon: $r('app.media.startIcon') },
{ title: '有品秒杀', icon: $r('app.media.app_icon') },
{ title: '原产地', icon: $r('app.media.foreground') },
{ title: '生活优选', icon: $r('app.media.background') },
{ title: '6G手机', icon: $r('app.media.startIcon') },
{ title: '小米自营', icon: $r('app.media.startIcon') },
{ title: '茅台酒饮', icon: $r('app.media.app_icon') },
{ title: '鞋服饰品', icon: $r('app.media.app_icon') },
{ title: '家纺餐厨', icon: $r('app.media.app_icon') },
{ title: '食品生鲜', icon: $r('app.media.app_icon') },
{ title: '好惠买', icon: $r('app.media.app_icon') },
{ title: '家具家装', icon: $r('app.media.app_icon') },
{ title: '健康养生', icon: $r('app.media.app_icon') },
{ title: '有品海购', icon: $r('app.media.app_icon') },
{ title: '个护清洁', icon: $r('app.media.app_icon') },
{ title: '户外运动', icon: $r('app.media.app_icon') },
{ title: '3C数码', icon: $r('app.media.app_icon') }
]
// 创建控制器对象
scroller: Scroller = new Scroller()
build() {
Column() {
Text('小米有品')
.fontSize(20)
.fontWeight(900)
.padding(10)
Grid(this.scroller) {
ForEach(this.navList, (item: XMNavItem) => {
GridItem() {
Column() {
Image(item.icon)
.width('80%')
Text(item.title)
.fontSize(12)
}
.height('100%')
}
.width('20%')
})
}
.rowsTemplate('1fr 1fr')
.height(160)
.width('100%')
.backgroundColor(Color.White)
.borderRadius(5)
.padding({ bottom: 10 })
.scrollBar(BarState.Off) // 关闭滚动条
// 自定义滚动条
ScrollBar({
scroller: this.scroller,
direction: ScrollBarDirection.Horizontal, // 横向滚动
state: BarState.On // 持续显示
}) {
Text()
.height(5)
.width(20)
.backgroundColor(Color.Orange)
.borderRadius(3)
}
.width(50)
.height(5)
.backgroundColor('#e5e5e5')
.borderRadius(3)
.offset({ y: -10 })
}
.width('100%')
.height('100%')
.padding(10)
.backgroundColor('#f5f5f5')
}
}
4.事后更新
好啦好啦,我知道大家可能对于最终的效果展示有点不满意,毕竟不够好看嘛,那就把图片给大家换一下,最终结果如下:
至于这么多图片,是不是要一个一个去下?其实不需要的,直接到以下链接,一个Ctrl+S就全部有了,然后选中前面20个丢进media文件夹里,完事:
英雄头像
最终代码:
interface XMNavItem {
title: string
icon: ResourceStr // 联合属性 Resource | string
}
@Entry
@Component
struct test_Grid {
// 数据 只需要渲染,所以没有使用@State 修饰
navList: XMNavItem[] = [
{ title: '上新精选', icon: $r('app.media.105') },
{ title: '智能家电', icon: $r('app.media.106') },
{ title: '小米众筹', icon: $r('app.media.107') },
{ title: '有品会员', icon: $r('app.media.108') },
{ title: '有品秒杀', icon: $r('app.media.109') },
{ title: '原产地', icon: $r('app.media.110') },
{ title: '生活优选', icon: $r('app.media.111') },
{ title: '6G手机', icon: $r('app.media.112') },
{ title: '小米自营', icon: $r('app.media.113') },
{ title: '茅台酒饮', icon: $r('app.media.114') },
{ title: '鞋服饰品', icon: $r('app.media.115') },
{ title: '家纺餐厨', icon: $r('app.media.115') },
{ title: '食品生鲜', icon: $r('app.media.116') },
{ title: '好惠买', icon: $r('app.media.117') },
{ title: '家具家装', icon: $r('app.media.118') },
{ title: '健康养生', icon: $r('app.media.119') },
{ title: '有品海购', icon: $r('app.media.120') },
{ title: '个护清洁', icon: $r('app.media.121') },
{ title: '户外运动', icon: $r('app.media.123') },
{ title: '3C数码', icon: $r('app.media.124') }
]
// 创建控制器对象
scroller: Scroller = new Scroller()
build() {
Column() {
Text('小米有品')
.fontSize(20)
.fontWeight(900)
.padding(10)
Grid(this.scroller) {
ForEach(this.navList, (item: XMNavItem) => {
GridItem() {
Column() {
Image(item.icon)
.width('80%')
Text(item.title)
.fontSize(12)
}
.height('100%')
}
.width('20%')
})
}
.rowsTemplate('1fr 1fr')
.height(160)
.width('100%')
.backgroundColor(Color.White)
.borderRadius(5)
.padding({ bottom: 10 })
.scrollBar(BarState.Off) // 关闭滚动条
// 自定义滚动条
ScrollBar({
scroller: this.scroller,
direction: ScrollBarDirection.Horizontal, // 横向滚动
state: BarState.On // 持续显示
}) {
Text()
.height(5)
.width(20)
.backgroundColor(Color.Orange)
.borderRadius(3)
}
.width(50)
.height(5)
.backgroundColor('#e5e5e5')
.borderRadius(3)
.offset({ y: -10 })
}
.width('100%')
.height('100%')
.padding(10)
.backgroundColor('#f5f5f5')
}
}
好了,今天的分享到这里为止,感谢阅读,欢迎点赞收藏支持鼓励下!