鸿蒙开发DE中滚动组件合集

231 阅读7分钟

一.List

  • List容器在内部内容超过屏幕大小时,可以自动提供滚动功能

  • 基本语法:
List(){
  ListItem(){内容}
  ListItemGroup(){
  ListItem(){}
  }
  ....
}

🔴注意点:List容器中只能包含ListItem或ListItemGroup;ListItemGroup内部只能包含ListItem

  • 常用属性

    ①listDirection() ->设置List内部子组件排列方式(默认垂直排列)

    ②lanes(参数1,参数2)->参数1设置交叉轴方向列数,参数2设置交叉轴列间距。

    ③scrollBar()->设置滚动条样式。

    ④divider({})->设置分割线样式。

更多可参考List-容器组件-ArkTS组件-ArkUI(方舟UI框架)-应用框架 - 华为HarmonyOS开发者 (huawei.com)

  • 拓展

ListItemGroup()作用:给List组件内子组件分组展示的。

基本语法:

List(){
 ListItemGroup(){
   ListItem(){}
   ...
 }
 ListItemGroup(){
   ListItem(){}
   ....
 }
 ...
}

ListItemGroup()的常用参数:

参数名参数类型描述
headerCustomBuilder设置ListItemGroup的头部组件
footerCustomBuilder设置ListItemGroup的尾部组件
spacenumber / string设置ListItemGroup内ListItem之间的间距

通讯录案例:

  • 效果图:

通讯录.gif

  • 参考代码:
interface ContactContent {
 initial: string
 nameList: string[]
}

@Entry
@Component
struct Index {
 contacts: ContactContent[] = [
   { initial: 'A', nameList: ['阿猫', '阿狗', '阿虎', '阿龙', '阿鹰', '阿狼', '阿豹', '阿狮', '阿象', '阿鲸'] },
   { initial: 'B', nameList: ['白兔', '白鸽', '白鹤', '白鹭', '白狐', '白狼', '白虎', '白鹿', '白蛇', '白马'] },
   { initial: 'C', nameList: ['春花', '春风', '春雨', '春草', '春柳', '春燕', '春莺', '春蝶', '春蓝', '春绿'] },
   { initial: 'D', nameList: ['冬雪', '冬梅', '冬松', '冬竹', '冬云', '冬霜', '冬月', '冬夜', '冬青', '冬红'] },
   { initial: 'E', nameList: ['饿狼', '饿虎', '饿鹰', '饿豹', '饿熊', '饿蛇', '饿鱼', '饿虾', '饿蟹', '饿蚌'] },
   { initial: 'F', nameList: ['飞鸟', '飞鱼', '飞虫', '飞蜂', '飞蝶', '飞蛾', '飞蝉', '飞蝗', '飞鼠', '飞猫'] },
   { initial: 'G', nameList: ['孤狼', '孤鹰', '孤虎', '孤豹', '孤蛇', '孤鲨', '孤鲸', '孤鹿', '孤雁', '孤鸿'] },
   { initial: 'H', nameList: ['海鸥', '海龟', '海豚', '海星', '海马', '海葵', '海参', '海胆', '海螺', '海贝'] },
   { initial: 'I', nameList: ['火焰', '火球', '火箭', '火山', '火车', '火柴', '火把', '火鸟'] },
   { initial: 'J', nameList: ['金鱼', '金狮', '金刚', '金鹿', '金蛇', '金鹰', '金豹', '金虎', '金狐', '金猫'] },
   { initial: 'K', nameList: ['孔雀', '恐龙', '开心', '开怀', '开朗', '开拓', '开口', '开花', '开眼', '开天'] },
   { initial: 'L', nameList: ['老虎', '老鹰', '老鼠', '老狼', '老狗', '老猫', '老熊', '老鹿', '老龟', '老蛇'] },
   { initial: 'M', nameList: ['玫瑰', '牡丹', '梅花', '茉莉', '木兰', '棉花', '蜜蜂', '蚂蚁', '马蜂', '蟒蛇'] },
   { initial: 'N', nameList: ['南山', '南极', '南海', '南京', '南阳', '南风', '南瓜', '南竹', '南花', '南鸟'] },
   {
     initial: 'O',
     nameList: ['熊猫', '欧鹭', '欧洲', '欧阳', '欧文', '欧若拉', '欧米茄', '欧罗巴', '欧菲莉亚', '欧瑞斯']
   },
   { initial: 'P', nameList: ['苹果', '葡萄', '琵琶', '枇杷', '菩提', '瓢虫', '瓢泼', '飘零', '飘渺', '飘飘然'] },
   { initial: 'Q', nameList: ['七喜', '强风', '奇迹', '乾坤', '奇才', '晴天', '青竹', '秋水', '轻舞', '清泉'] },
   { initial: 'R', nameList: ['瑞雪', '瑞兽', '瑞光', '瑞云', '瑞彩', '瑞气', '瑞香', '瑞草', '瑞莲', '瑞竹'] },
   { initial: 'S', nameList: ['三羊', '三狗', '三猫', '三鱼', '三角', '三鹿', '三鹰', '三蛇', '三狐', '三豹'] },
   { initial: 'T', nameList: ['太阳', '天空', '田园', '太极', '太湖', '天鹅', '太空', '天使', '坦克', '甜橙'] },
   { initial: 'U', nameList: ['乌鸦', '乌鹊', '乌鱼', '乌龟', '乌云', '乌梅', '乌木', '乌金', '乌黑', '乌青'] },
   { initial: 'V', nameList: ['五虎', '五狼', '五鹰', '五豹', '五熊', '五蛇', '五鲨', '五鲸', '五鹿', '五马'] },
   { initial: 'W', nameList: ['悟空', '微笑', '温暖', '无畏', '温柔', '舞蹈', '问心', '悟道', '未来', '文学'] },
   { initial: 'X', nameList: ['西风', '西洋', '西子', '西施', '西岳', '西湖', '西柚', '西竹', '西花', '西鸟'] },
   { initial: 'Y', nameList: ['夜猫', '夜鹰', '夜莺', '夜空', '夜色', '夜月', '夜影', '夜翼', '夜狐', '夜狼'] },
   { initial: 'Z', nameList: ['珍珠', '紫薇', '紫霞', '紫竹', '紫云', '紫燕', '紫鸢', '紫藤', '紫荆', '紫罗兰'] },
 ]

 @Builder
 head(title: string) {
   Text(title)
     .width('100%')
     .backgroundColor('#f2f4f5')
     .height(30)
 }    //ListItemGroup头部内容

 randonColor() {
   let cols1 = Math.floor(Math.random() * 256)    //定义3个随机数
   let cols2 = Math.floor(Math.random() * 256)
   let cols3 = Math.floor(Math.random() * 256)
   return `rgba(${cols1},${cols2},${cols3},0.8)`  //随机颜色
 }

 build() {
   Column() {
     Stack({ alignContent: Alignment.End }) {
       Text('通讯录')
         .width('100%')
         .textAlign(TextAlign.Center)
         .fontSize(20)
       Image($r('app.media.ic_public_add'))
         .width(20)
     }     //通讯录
     .width('100%')
     .padding(15)
     .backgroundColor('#fff1f3f5')

     List() {
       ListItem() {
         Row() {
           Image($r('app.media.ic_public_search'))
             .width(20)
             .fillColor(Color.Gray)
           Text('搜索')
             .fontColor(Color.Gray)
         }
         .backgroundColor(Color.White)
         .width('100%')
         .height(40)
         .borderRadius(5)
         .justifyContent(FlexAlign.Center)
       }                              //搜索栏
       .padding(10)
       .width('100%')
       .backgroundColor('#fff1f3f5')

       ForEach(this.contacts, (item: ContactContent) => {                  //遍历Contacts对象数组,item为ContactContent对象类型
         ListItemGroup({ header: this.head(item.initial), space: 10 }) {    //头部内容为Builder自定义函数给的值为item对象内的initial类型的值
           ForEach(item.nameList, (name: string) => {                    //遍历item对象数组内的nameList数组,赋值给name
             ListItem() {
               Row({ space: 10 }) {
                 Image($r('app.media.ic_public_lianxiren'))
                   .width(40)
                   .fillColor(this.randonColor())  //因为每次循环都得重复执行此代码,所以每次生成颜色不一样
                 Text(name)
                   .fontSize(18)
               }

             }
           })
         }
         .divider({ strokeWidth: 2 })
       })
     }
     .sticky(StickyStyle.Header) //粘性标题

   }
   .height('100%')
   .width('100%')
 }
}

二.Scroll

当子组件的布局尺寸超过Scroll的尺寸时,内容可以滚动。

当页面内容由多个区域组成,并且可以滚动时,推荐使用 Scroll

  • 基本语法:

Scroll是个容器组件,所以语法跟Column、Row之类语法一样,Scroll(){子组件1,子组件2...}

  • 常用属性:
名称类型作用
scrollableScrollDirection设置滚动方向(只有内部子组件超出父组件宽或者高时,才会滚动)
scrollBarBarState设置滚动条状态
scrollBarColorstring/number/Color设置滚动条颜色
scrollBarWidthstring/number设置滚动条的宽度
edgeEffectvalue:EdgeEffect设置滚动边缘滑动效果(无,阴影,弹簧)
  • 代码控制滚动及获取滚动偏移量

主要方法:

1.scrollEdge->滚动到边缘

2.currentOffset->获取当前偏移量

3.onWillScroll事件->滚动事件回调, 返回滚动时水平、竖直方向偏移量。

  • 案例

效果图:

1.gif

参考代码:

@Entry
@Component
struct offset1 {
  kzq=new Scroller()                          //给Scroller组件创建一个控制器
  @State offsety:number = 0                   //定义状态变量
  build() {
    Column(){

      Scroll(this.kzq){             //将控制器绑定Scroll容器
        Column(){
            Column(){
              Image($r('app.media.ic_xiaomi_scroll_01'))
                .width('100%')
              Image($r('app.media.ic_xiaomi_scroll_02'))
                .width('100%')
              Image($r('app.media.ic_xiaomi_scroll_03'))
                .width('100%')
            }

        }

      }
      .scrollBar(BarState.Off)           //滚动条隐藏
      .edgeEffect(EdgeEffect.Fade)    //设置滚动边缘阴影效果
      .onWillScroll((y)=>{                //获取偏移量
        y=this.kzq.currentOffset().yOffset  //将控制器y轴偏移量实时赋值给y
        this.offsety=y                    //将y的值赋值给状态变量
      })
      // .height('100%') 不设置时,内部组件最大到屏幕100%。如果内部组件高度超出100%屏幕则自动滚动
      // ScrollBar({
      //   scroller:this.kzq,
      //   direction:ScrollBarDirection.Horizontal,
      //   state:BarState.On
      // })
      // let y:number=this.kzq.currentOffset().yOffset
      if ( this.offsety>200){             //判断y轴偏移量大于200时显示图标
        Image($r('app.media.ic_jd_rocket'))
          .width(40)
          .borderRadius(20)
          .padding(5)
          .onClick(()=>{
            this.kzq.scrollEdge(Edge.Top)       //点击事件回到顶部
          })
          .position({x:300,y:650})
          .backgroundColor(Color.White)
      }

    }
  }
}

三.Taps

当页面内容较多时,可以通过Taps组件进行分类展示。

  • 基本语法:

Tabs(参数){

TabContent(){}...

}

🔴注:Tabs组件内只能有TabContent,TabContent内可以写任意组件内容。

  • Tabs常用参数

1.vertical->调整导航为水平或垂直

2.barPosition->调整导航位置在开头或结尾

3.scrollable->界面是否允许滑动切换

4.animationDuration->设置动画时间

5.barMode->设置导航栏固定或滚动

  • TabContent重要属性

🟢自定义tabBar

作用:设置TabBar上显示内容。接受类型string/CustomBuilder

如:

页面切换.gif

参考代码:

@Entry
@Component
struct barbuilder {
  @State num: number = 0

  @Builder
  barbuilder(title: string, img: string, img1: string, num: number) {
    if (num == 3) {
      Badge({ count: 7, position: BadgePosition.RightTop, style: {} }) {
        Column({ space: 2 }) {
          Image(this.num == num ? $r(img1) : $r(img))
            .width(25)
          Text(title)
            .fontSize(13)
            .foregroundColor(this.num == num ? Color.Red : Color.Black)
        }

        // .onClick(()=>{
        //   this.badgenum=this.badgenum+1
        // })

      }
    } else if (num == 2) {
      Badge({ value: '上新', position: BadgePosition.RightTop, style: {} }) {
        Column({ space: 2 }) {
          Image($r(img))
            .width(40)
          Text(title)
            .fontSize(13)
        }
      }
    } else {
      Column({ space: 2 }) {
        Image(this.num == num ? $r(img1) : $r(img))
          .width(25)
        Text(title)
          .fontSize(13)
          .foregroundColor(this.num == num ? Color.Red : Color.Black)
      }

      // .onClick(()=>{
      //   AlertDialog.show({
      //     message:'ok'
      //   })
      // })
    }
  }

  build() {
    Column() {
      Tabs() {
        TabContent() {
          Text('首页')
            .fontSize(50)
        }
        .tabBar(this.barbuilder('首页', 'app.media.ic_tabbar_icon_0', 'app.media.ic_tabbar_icon_0_selected', 0))

        TabContent() {
          Text('逛')
            .fontSize(50)
        }
        .tabBar(this.barbuilder('逛', 'app.media.ic_tabbar_icon_1', 'app.media.ic_tabbar_icon_1_selected', 1))

        TabContent() {
        }
        .tabBar(this.barbuilder('', 'app.media.ic_share_sina', 'app.media.ic_share_sina', 2))

        TabContent() {
          Text('购物车')
            .fontSize(50)
        }
        .tabBar(this.barbuilder('购物车', 'app.media.ic_tabbar_icon_2', 'app.media.ic_tabbar_icon_2_selected', 3))

        TabContent() {
          Text('我的')
            .fontSize(50)
        }
        .tabBar(this.barbuilder('我的', 'app.media.ic_tabbar_icon_3', 'app.media.ic_tabbar_icon_3_selected', 4))
      }
      .barPosition(BarPosition.End)
      .onChange((index) => {
        this.num = index
      })

      // .onTabBarClick((index) => {
      //   console.log('tabBarClick-index:', index)
      // })

    }
    .height('100%')
    .width('100%')
  }
}

四.Swiper组件的功能

  • Swiper组件提供了滑动轮播显示的能力。当内部设置了多个子组件后可以对这些子组件进行轮播显示。

例如:

image.png

  • 设置尺寸

    ①直接设置Swiper容器尺寸(子组件会自动拉伸铺满容器内部(优先级高))

    ②设置内部子组件的尺寸(会给Swiper容器撑开)

      Swiper() {
        // 轮播内容 
        // (设置尺寸,撑开swiper)
      }
      // 设置尺寸(内容拉伸、优先级高)
      .width('100%')
      .height(100)
    
  • 常用属性
属性名类型说明
loopboolean是否开启循环。设置为true时表示开启循环,在LazyForEach懒循环加载模式下,加载的组件数量建议大于5个。默认值:true
autoPlayboolean子组件是否自动播放。默认值:false。说明:loop为false时,自动轮播到最后一页时停止轮播。手势切换后不是最后一页时继续播放。
intervalnumber使用自动播放时播放的时间间隔,单位为毫秒。默认值:3000
verticalboolean是否为纵向滑动。默认值:false

更多属性参考文档Swiper-容器组件-ArkTS组件-ArkUI(方舟UI框架)-应用框架 - 华为HarmonyOS开发者 (huawei.com)

  • 绑定按钮控制轮播图上一页下一页

    代码演示 :

@Entry
@Component
struct xmyp {
  controller =new SwiperController()   //new一个Swiper的控制器
  build() {
    Column(){
      Swiper(this.controller){             //给Swiper组件绑定上控制器
        Image('/images/ic_swiper_xmyp01.jpeg')
        Image('/images/ic_swiper_xmyp02.jpeg')
        Image('/images/ic_swiper_xmyp03.jpeg')
        Image('/images/ic_swiper_xmyp04.jpeg')
      }
      .height(160)
      .width('100%')
      .autoPlay(true)
      .indicator(Indicator.dot()
        .selectedItemWidth(30)
        .selectedItemHeight(4)
        .itemWidth(10)
        .itemHeight(4)
        .selectedColor(Color.White)
        .color(Color.Black))
      Button('上一页')                     //给按钮添加上点击事件
        .onClick(()=>{{
          this.controller.showNext()
        }})
      Button('下一页')
        .onClick(()=>{
          this.controller.showNext()
        })
    }
    }
}

效果图:

image.png

五.Grid组件的功能

  • 网格布局

功能:布局是很多行和列组成的,可能需要合并或者滚动就可以使用Grid组件

①如果给行列设定固定的几行几列(不滚动)

②合并行或者列 (不滚动)

生成以下效果:

image.png

代码演示:

@Entry
@Component
struct five {
@Builder GriditemBuilder(text:string){
  GridItem(){
    Text(text)
  }
  .backgroundColor(Color.Pink)
}
  build() {
    Column(){
      Grid(){
        this.GriditemBuilder('1')
        this.GriditemBuilder('2')
        this.GriditemBuilder('3')
        this.GriditemBuilder('4')
        this.GriditemBuilder('5')
        this.GriditemBuilder('6')
        this.GriditemBuilder('7')
        this.GriditemBuilder('8')
        this.GriditemBuilder('9')
      }
      .width('100%')
      .height(300)
      .columnsTemplate('1fr 2fr 3fr')
      .rowsTemplate('1fr 2fr 3fr')
      .rowsGap(10)
      .columnsGap(10)
      .padding(10)
    }
    .height('100%')
    .width('100%')
  }
}
注意点:行列的单位是fr

合并效果:

image.png

代码演示:

@Entry
@Component
struct six {
  // 生成 12 个元素的数组
  nums: number[] = Array.from({ length: 12 })

  build() {
    Grid() {
      ForEach(this.nums, (item: number, index: number) => {  //遍历长度为12的数组
       if (index==2){                     //当索引为2时第三列和第四列合并
         GridItem() {
           Text((index+1).toString())       //index+1是因为数组遍历时索引是从0开始
             .fontColor(Color.White)
             .fontSize(30)
         }
         .backgroundColor('#9dc3e6')
         .columnStart(0)
         .columnEnd(1)
       }else      
       if (index==3){                 //索引为3时 第二行和第三行合并
         GridItem() {
           Text((index+1).toString())
             .fontColor(Color.White)
             .fontSize(30)
         }
         .backgroundColor('#9dc3e6')
         .rowStart(0)
         .rowEnd(1)
       }else
       if (index==7){                    //索引为7时第二,三,四行合并
         GridItem() {
           Text((index+1).toString())
             .fontColor(Color.White)
             .fontSize(30)
         }
         .backgroundColor('#9dc3e6')
         .columnStart(0)
         .columnEnd(2)
       }else {
         GridItem() {  
           Text((index + 1).toString())
             .fontColor(Color.White)
             .fontSize(30)
         }
         .backgroundColor('#9dc3e6')
       }



      })
    }
    .columnsTemplate('1fr 1fr 1fr 1fr')
    .rowsTemplate('1fr 1fr 1fr')
    .width('100%')
    .height(260)
    .rowsGap(10)
    .columnsGap(10)
    .padding(10)
  }
}
注意点:合并行列用的是(colunmnStart/columnEnd)(rowStart/rowEnd) 两组属性需要配合使用不可单独使用
  • 代码控制滚动条

核心步骤:

  1. 创建 Scroller 对象
  2. 设置给 Grid
  3. 调用 Scroller 对象的 scrollPage 方法、
// 创建 Scroller 对象
scroller: Scroller = new Scroller()

// 设置给 Grid
 Grid(this.scroller) {
   // ...
 }

// 通过代码控制
this.scroller.scrollPage({
  next:true // 下一页
  next:false // 上一页
})

  • 代码控制滚动条滚动

步骤

  1. 创建 Scroller 对象
  2. 设置给 Grid
  3. 调用 Scroller 对象的 scrollPage 方法

代码:

interface NavItem {
  title: string
  icon: ResourceStr
}

@Entry
@Component
struct Day01_07_Grid03 {
  @State message: string = '滚动';
  scroller: Scroller = new Scroller()
  navList: NavItem[] = [
    { title: '上新精选', icon: $r('app.media.ic_xiaomi_nav_01') },
    { title: '智能家电', icon: $r('app.media.ic_xiaomi_nav_02') },
    { title: '小米众筹', icon: $r('app.media.ic_xiaomi_nav_03') },
    { title: '有品会员', icon: $r('app.media.ic_xiaomi_nav_04') },
    { title: '有品秒杀', icon: $r('app.media.ic_xiaomi_nav_05') },
    { title: '原产地', icon: $r('app.media.ic_xiaomi_nav_06') },
    { title: '生活优选', icon: $r('app.media.ic_xiaomi_nav_07') },
    { title: '手机', icon: $r('app.media.ic_xiaomi_nav_08') },
    { title: '小米自营', icon: $r('app.media.ic_xiaomi_nav_09') },
    { title: '茅台酒饮', icon: $r('app.media.ic_xiaomi_nav_10') },
    { title: '鞋服饰品', icon: $r('app.media.ic_xiaomi_nav_11') },
    { title: '家纺餐厨', icon: $r('app.media.ic_xiaomi_nav_12') },
    { title: '食品生鲜', icon: $r('app.media.ic_xiaomi_nav_13') },
    { title: '好惠买', icon: $r('app.media.ic_xiaomi_nav_14') },
    { title: '家具家装', icon: $r('app.media.ic_xiaomi_nav_15') },
    { title: '健康养生', icon: $r('app.media.ic_xiaomi_nav_16') },
    { title: '有品海购', icon: $r('app.media.ic_xiaomi_nav_17') },
    { title: '个护清洁', icon: $r('app.media.ic_xiaomi_nav_18') },
    { title: '户外运动', icon: $r('app.media.ic_xiaomi_nav_19') },
    { title: '3C数码', icon: $r('app.media.ic_xiaomi_nav_20') }
  ]

  build() {
    Column() {
      Text(this.message)
        .fontSize(50)
      Grid(this.scroller){              //绑定控制器
        ForEach(this.navList,(item:NavItem,index:number)=>{
          GridItem(){
            Column(){
              Image(item.icon)
                .width('80%')
              Text(item.title)
                .fontSize(12)
            }
            .height('100%')
            // .backgroundColor(Color.Pink)
          }
          .width('20%')


        })
      }
      .width('100%')
      .height(170)
      .rowsTemplate('1fr 1fr')
      // .rowsGap(3)
      // .columnsGap(3)

      Row(){
        Button('上一页')
          .width(100)
          .onClick(() => {
            this.scroller.scrollPage({
              next: false
            })
          })
        Button('下一页')
          .onClick(() => {
            this.scroller.scrollPage({
              next: true
            })
          })
      }
    }
    .width('100%')
    .height('100%')
    .padding(10)
    .backgroundColor('#f5f5f5')
  }
}

效果图:

image.png

  • 自定义滚动条
  1. 和 Grid 共用同一个 Scroller
  2. 创建 ScrollBar 组件并设置属性
// 和 Grid 共用同一个 Scroller
scroller: Scroller = new Scroller()

// 和 Grid 共用同一个 Scroller
Grid(this.scroller){
  // 略
}

// 和 Grid 共用同一个 Scroller
// 创建 ScrollBar 组件并设置属性
ScrollBar({
  scroller: this.scroller,
  direction: ScrollBarDirection.Horizontal // 方向
}) {
  // 滚动内容 设置外观即可
  Text()
}
// 设置外观
  • 小米有品综合案例

效果图:

小米综合案例.gif

代码演示:

@Builder
function yp() {
  Row() {
    Row({ space: 15 }) {
      Image($r('app.media.ic_xiaomi_logo'))
        .width(50)
      Row({ space: 8 }) {
        Image($r('app.media.ic_xiaomi_search'))
          .width(20)
        Text('电视')
          .fontSize(17)
          .fontColor('rgba(0,0,0,0.4)')
      }
      .width(200)
      .height(40)
      .borderRadius(20)
      .padding(8)
      .border({ width: 1.5, color: '#a27a3e' })
    }

    Badge({ count: 99, position: BadgePosition.RightTop, style: {} }) {
      Image($r('app.media.ic_xiaomi_ring'))
        .width(40)
    }
    .margin({ right: 10 })
  }
  .justifyContent(FlexAlign.SpaceBetween)
  .width('100%')
}   //全局Builder一个容器及其子组件(包括属性)简化代码界面 -->需要加上function

interface NavItem {
  title: string
  icon: ResourceStr
}      //定义一个对象接口

@Entry
@Component
struct xiaomi {
  @Builder
  swiper(num: number) {
    Image($r(`app.media.ic_swiper_xmyp0${num}`))
      .width('100%')
      .padding(5)
      .borderRadius(15)
  }   //局部Builder一个image及其属性-->不需要加function

  navList: NavItem[] = [
    { title: '上新精选', icon: $r('app.media.ic_xiaomi_nav_01') },
    { title: '智能家电', icon: $r('app.media.ic_xiaomi_nav_02') },
    { title: '小米众筹', icon: $r('app.media.ic_xiaomi_nav_03') },
    { title: '有品会员', icon: $r('app.media.ic_xiaomi_nav_04') },
    { title: '有品秒杀', icon: $r('app.media.ic_xiaomi_nav_05') },
    { title: '原产地', icon: $r('app.media.ic_xiaomi_nav_06') },
    { title: '生活优选', icon: $r('app.media.ic_xiaomi_nav_07') },
    { title: '手机', icon: $r('app.media.ic_xiaomi_nav_08') },
    { title: '小米自营', icon: $r('app.media.ic_xiaomi_nav_09') },
    { title: '茅台酒饮', icon: $r('app.media.ic_xiaomi_nav_10') },
    { title: '鞋服饰品', icon: $r('app.media.ic_xiaomi_nav_11') },
    { title: '家纺餐厨', icon: $r('app.media.ic_xiaomi_nav_12') },
    { title: '食品生鲜', icon: $r('app.media.ic_xiaomi_nav_13') },
    { title: '好惠买', icon: $r('app.media.ic_xiaomi_nav_14') },
    { title: '家具家装', icon: $r('app.media.ic_xiaomi_nav_15') },
    { title: '健康养生', icon: $r('app.media.ic_xiaomi_nav_16') },
    { title: '有品海购', icon: $r('app.media.ic_xiaomi_nav_17') },
    { title: '个护清洁', icon: $r('app.media.ic_xiaomi_nav_18') },
    { title: '户外运动', icon: $r('app.media.ic_xiaomi_nav_19') },
    { title: '3C数码', icon: $r('app.media.ic_xiaomi_nav_20') }
  ]  //定义一个对象接口为NavItem的对象数组
  sgb: Scroller = new Scroller()    //定义一个滚动条控制器

  build() {
    Column({ space: 10 }) {
      yp()           //调用全局Builder  yp
      Swiper() {
        this.swiper(1)      //调用局部Builder swiper
        this.swiper(2)
        this.swiper(3)
        this.swiper(4)
      }
      .autoPlay(true)        //轮播图自动播放
      .indicator(
        Indicator.dot()
          .selectedItemWidth(20)
          .selectedColor(Color.White)
          .color('rgba(0,0,0,0.5)')
          .itemWidth(10))          //定义Swiper的滚动条样式

      Grid(this.sgb) {         //网格布局 绑定控制器sgb
        ForEach(this.navList, (item: NavItem, index: number) => { //遍历数组navList
          GridItem() {
            Column() {
              Image(item.icon)
                .width('80%')
              Text(item.title)
            }
          }             
          .width('20%')
        })
      }
      .height(160)
      .rowsTemplate('1fr 1fr')   //两行显示
      .scrollBar(BarState.Off)

      ScrollBar({
        scroller: this.sgb,                          //自定义滚动条跟Grid的滚动条绑定
        direction: ScrollBarDirection.Horizontal,      //水平滚动
        state: BarState.On                              //滚动条一直显示
      }) {
        Column() {
        }
        .backgroundColor(Color.Orange)
        .width(15)
        .height(5)
        .borderRadius(3)
      }
      .backgroundColor(Color.Gray)
      .width(30)
      .borderRadius(3)
      .position({
        x:165,
        y:377
      })

      Image($r('app.media.ic_xiaomi_floor'))
        .width('100%')
    }
    .height('100%')
    .width('100%')
  }
}

六.Waterflow

  • 瀑布流容器

    由行列分割单元格组成,根据容器自身的排列规则,将不同子元素自上而下紧密布局。基本用法类似Grid组件。(可用.layoutDirection(FlexDirection.Row)来改变方向)

  • 案例:

需求:生成随机颜色;不同高度的色块自上而下排列

效果图:

随机颜色版瀑布流.gif

参考代码:

@Entry
@Component
struct Index {
  @Builder flowitem(){
    FlowItem(){
      Column(){}.backgroundColor(`rgba(${Math.floor(Math.random()*256)},${Math.floor(Math.random()*256)},${Math.floor(Math.random()*256)},1)`).width('100%').height(`${Math.floor(Math.random()*300+50)}`).borderRadius(10)
    }
    FlowItem(){
      Column(){}.backgroundColor(`rgba(${Math.floor(Math.random()*256)},${Math.floor(Math.random()*256)},${Math.floor(Math.random()*256)},1)`).width('100%').height(`${Math.floor(Math.random()*200+50)}`).borderRadius(10)
    }
  }

  sz:string[] = Array.from({length:30}) //生成一个有30个元素的空数组

  @Builder foot(){
    Text('是否继续加载?')
      .fontSize(20)
      .fontColor(Color.Orange)
  }

  sc=new Scroller()
  build() {
    Column(){
      Button('点击回到顶部')
        .onClick(()=>{
          this.sc.scrollEdge(Edge.Top)
        })
      WaterFlow({footer:this.foot,scroller:this.sc}){
        ForEach(this.sz,()=>{
          this.flowitem()
        })



      }
      .columnsTemplate('1fr 1fr')
      .columnsGap(10)
      .rowsGap(10)
      .edgeEffect(EdgeEffect.Fade) //Spring弹簧效果,Fade阴影效果
      .layoutWeight(1)


    }
    .height('100%')
    .width('100%')
  }
}

以上均为个人总结,如有不足请指出❤️。