鸿蒙应用开发从入门到实战(十七):ArkUI组件List&列表布局

大家好,我是潘Sir,持续分享IT技术,帮你少走弯路。《鸿蒙应用开发从入门到项目实战》系列文章持续更新中,陆续更新AI+编程、企业级项目实战等原创内容、欢迎关注!

ArkUI提供了丰富的系统组件,用于制作鸿蒙原生应用APP的UI,本文通过简单案例演示如何使用List组件实现列表布局。

一、List布局优化商品列表

上一小节里的商品列表,随着数据增多,当超出界面后,无法滚动查看。List列表布局就可以解决这个问题。

List列表是一种复杂容器,具备下列特点:

  • 列表项ListItem数量过多超出屏幕后,会自动提供滚动功能

  • 列表项ListItem既可以纵向排列,也可以横向排列

再pages/layout下新建list目录,新建ProductList.ets文件,将上一小节里的代码文件ProductListPage.ets文件里的内容拷贝过来进行修改。

将ForEach部分的内容放到List组件里即可

typescript 复制代码
class Item1 { // 复制过来后,即使再不同的文件中,也会提示同名
  name: string //小写
  image: ResourceStr
  price: number
  discount: number

  constructor(name: string, image: ResourceStr, price: number, discount: number = 0) {
    this.name = name
    this.image = image
    this.price = price
    this.discount = discount
  }
}

@Entry
@Component
struct ProductList {
  // 商品数据
  private items: Array<Item1> = [
    new Item1('华为Mate60', $r('app.media.mate60'), 6999, 500),
    new Item1('MateBookProX', $r('app.media.mate60'), 13999),
    new Item1('WatchGT4', $r('app.media.mate60'), 1438),
    new Item1('FreeBuds Pro3', $r('app.media.mate60'), 1499),
    new Item1('FreeBuds Pro3', $r('app.media.mate60'), 199),
    new Item1('Mate X5', $r('app.media.mate60'), 12999)
  ]

  build() {
    Column({ space: 8 }) {
      // 标题
      Row() {
        Text('商品列表')
          .fontSize(30)
          .fontWeight(FontWeight.Bold)
      }
      .width('100%')
      // .height(30) //控制高度
      .margin({ bottom: 20 })

      // 商品列表
      List({ space: 8 }) {
        ForEach(
          this.items,
          (item: Item1) => {
            ListItem() {  //ListItem子元素必须用根元素包裹
              Row({ space: 10 }) {
                Image(item.image)
                  .width(100)
                Column({ space: 4 }) {
                  if (item.discount) {
                    Text(item.name)
                      .fontSize(20)
                      .fontWeight(FontWeight.Bold)
                    Text('原价:¥' + item.price)
                      .fontColor('#CCC')
                      .fontSize(14)
                      .decoration({ type: TextDecorationType.LineThrough })
                    Text('折扣价:¥' + (item.price - item.discount))
                      .fontColor('#F36')
                      .fontSize(18)
                    Text('补贴:¥' + item.discount)
                      .fontColor('#F36')
                      .fontSize(18)
                  } else {
                    Text(item.name)
                      .fontSize(20)
                      .fontWeight(FontWeight.Bold)
                    Text('¥' + item.price)
                      .fontColor('#F36')
                      .fontSize(18)
                  }
                }
                .height('100%')
                .alignItems(HorizontalAlign.Start)
              }
              .width('100%')
              .backgroundColor('#FFF')
              .borderRadius(20)
              .height(120)
              .padding(10)
            }
          }
        )
      }
      .width('100%')
      // .layoutWeight(1)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#EFEFEF')
    .padding(20)
  }
}

这样,就可以通过拖动呈现超过屏幕区的内容。

二、列表布局详解

2.1 概述

List 是一个功能强大的容器组件,使用List可以轻松高效地显示结构化、可滚动的列表信息,例如通讯录、新闻列表等等。

List 容器的子组件为ListItem 或者ListItemGroup ,其中,ListItem 表示单个列表项,ListItemGroup 用于列表数据的分组展示,其子组件也是ListItem,具体用法如下

typescript 复制代码
List() {
  // 列表项
  ListItem() {......}
  ListItem() {......}
  ListItem() {......}
  ListItem() {......}
  ListItem() {......}
  ListItem() {......}
  ListItem() {......}
  ListItem() {......}
  ListItem() {......}
  ListItem() {......}
  ListItem() {......}
  ListItem() {......}
}

效果

typescript 复制代码
List() {
  // 列表组
  ListItemGroup(){
    //列表项
    ListItem(){......}
    ListItem(){......}
  }

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

效果

2.2 参数

List 组件的参数定义如下,下面逐一介绍每个参数

typescript 复制代码
List(value?:{space?: number | string, scroller?: Scroller})

2.2.1 列表项间距

space参数用于设置列表项的间距,如下图所示

2.2.2 列表滚动控制器

scroller参数用于绑定列表滚动控制器(Scroller ),Scroller可以控制列表的滚动,例如令列表返回顶部

示例:

拷贝icon-top.png到resources/base/media目录

pages /layout/list新建ScrollerPage.ets

typescript 复制代码
@Entry
@Component
struct ScrollerPage {
  data: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
  scroller: Scroller = new Scroller();

  build() {
    Stack({ alignContent: Alignment.BottomEnd }) {
      List({ space: 20, scroller: this.scroller }) {
        ForEach(this.data, (item) => {
          ListItem() {
            Text(item.toString())
              .itemTextStyle()
          }
        })
      }.listStyle()
      .height('100%')
      .width('100%')

      Button({ type: ButtonType.Circle }) {
        Image($r('app.media.icon_top'))
          .width(40)
          .height(40)
      }
      .width(60)
      .height(60)
      .backgroundColor(Color.Orange)
      .offset({ x: -20, y: -100 })
      .onClick(() => {
        this.scroller.scrollToIndex(0)
      })
    }
  }
}

@Extend(Text) function itemTextStyle() {
  .height(80)
  .width('100%')
  .textAlign(TextAlign.Center)
  .fontColor(Color.White)
  .fontSize(40)
  .fontWeight(FontWeight.Bold)
  .backgroundColor('#008a00')
  .borderRadius(10)
}

@Extend(List) function listStyle() {
  .backgroundColor(Color.White)
  .padding(20)
}

2.3 常用属性

2.3.1 主轴方向

使用listDirection()方法可以设置列表的主轴方向(即列表的排列和滚动方向),其参数类型为枚举类型Axis,可选的枚举值如下

2.3.2 交叉轴对齐方式

使用alignListItem()方法可以设置子组件在交叉轴方向的对齐方式,其参数类型为枚举类型ListItemAlign,可选的枚举值有

示例代码

pages /layout/list新建AlignPage.ets

typescript 复制代码
@Entry
@Component
struct AlignPage {
  data: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]

  build() {

    List({ space: 20 }) {
      ForEach(this.data, (item) => {
        ListItem() {
          Text(item.toString())
            .height(80)
            .width(320)
            .itemTextStyle1()
        }
      })
    }.listStyle1()
    .height('100%')
    .width('100%')
    .alignListItem(ListItemAlign.Center)

  }
}

@Extend(Text) function itemTextStyle1() {  //同一个命名空间下不能重复,否则会报错
  .textAlign(TextAlign.Center)
  .fontColor(Color.White)
  .fontSize(40)
  .fontWeight(FontWeight.Bold)
  .backgroundColor('#008a00')
  .borderRadius(10)
}

@Extend(List) function listStyle1() {
  .backgroundColor(Color.White)
  .padding({ top: 20, bottom: 20 })
}

2.3.3 元素分割线

使用divider()属性可设置列表元素分割线样式,该方法的参数定义如下

typescript 复制代码
divider(value: {strokeWidth: Length, color?: ResourceColor, startMargin?: Length, endMargin?: Length})

各参数的含义如下

参数 含义
strokeWidth 分割线线宽
color 分割线颜色
startMargin 分割线起始端到列表侧边距离(如下图所示)
endMargin 分割线末端到列表侧边距离(如下图所示)

示例代码

pages /layout/list新建DividerPage.ets

typescript 复制代码
@Entry
@Component
struct DividerPage {
  data: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]

  build() {

    List({ space: 20 }) {
      ForEach(this.data, (item) => {
        ListItem() {
          Text(item.toString())
            .height(80)
            .width(320)
            .itemTextStyle2()
        }
      })
    }
    .listStyle2()
    .height('100%')
    .width('100%')
    .alignListItem(ListItemAlign.Center)
    .divider({
      strokeWidth: 1,
      color: Color.Orange,
      startMargin: 30,
      endMargin: 30
    })

  }
}

@Extend(Text) function itemTextStyle2() {
  .textAlign(TextAlign.Center)
  .fontColor(Color.White)
  .fontSize(40)
  .fontWeight(FontWeight.Bold)
  .backgroundColor('#008a00')
  .borderRadius(10)
}

@Extend(List) function listStyle2() {
  .backgroundColor(Color.White)
  .padding({ top: 20, bottom: 20 })
}

2.3.4 滚动条样式

使用scrollBar()方法可以设置滚动条状态,该方法的参数类型为枚举类型BarState,可选的枚举值如下

名称 描述
BarState.Off 不显示
BarState.On 常驻显示
BarState.Auto 按需显示(触摸时显示,2s后消失)

示例代码

pages /layout/list新建ScrollBarPage.ets

typescript 复制代码
@Entry
@Component
struct ScrollBarPage {
  data: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]

  build() {

    List({ space: 20 }) {
      ForEach(this.data, (item) => {
        ListItem() {
          Text(item.toString())
            .height(80)
            .width(320)
            .itemTextStyle3()
        }
      })
    }.listStyle3()
    .height('100%')
    .width('100%')
    .alignListItem(ListItemAlign.Center)
    .scrollBar(BarState.Auto)

  }
}

@Extend(Text) function itemTextStyle3() {
  .textAlign(TextAlign.Center)
  .fontColor(Color.White)
  .fontSize(40)
  .fontWeight(FontWeight.Bold)
  .backgroundColor('#008a00')
  .borderRadius(10)
}

@Extend(List) function listStyle3() {
  .backgroundColor(Color.White)
  .padding({ top: 20, bottom: 20 })
}

《鸿蒙应用开发从入门到项目实战》系列文章持续更新中,陆续更新AI+编程、企业级项目实战等原创内容,防止迷路,欢迎关注!

相关推荐
bst@微胖子5 小时前
鸿蒙实现滴滴出行项目之侧边抽屉栏以及权限以及搜索定位功能
android·华为·harmonyos
爱笑的眼睛1120 小时前
深入浅出 HarmonyOS 应用开发:ArkTS 语法精要与实践
华为·harmonyos
爱笑的眼睛1121 小时前
HarmonyOS应用开发深度解析:ArkTS语法精要与UI组件实践
华为·harmonyos
Kisang.1 天前
【HarmonyOS】消息通知
华为·harmonyos
安卓开发者1 天前
鸿蒙NEXT网络通信实战:使用HTTP协议进行网络请求
网络·http·harmonyos
爱笑的眼睛111 天前
HarmonyOS ArkTS深度解析:构建高性能声明式UI应用
华为·harmonyos
TiZizzz1 天前
HarmonyOS应用开发 - strip编译配置优先级
华为·harmonyos
徐归阳1 天前
DevEco Studio安装
编辑器·harmonyos
小白学鸿蒙2 天前
OpenHarmony(开源鸿蒙)小白入门教程
harmonyos·鸿蒙·鸿蒙系统