ArkUI Scroll:内容一长,别让页面硬撑

举报
蓝瘦的蜕变 发表于 2026/08/08 10:32:27 2026/08/08
【摘要】 今天我们用 Scroll 做一个长内容页面,重点看纵向滚动、横向滚动、滚动条和边缘效果。 Scroll 最适合解决一个朴素问题:内容比容器长。我们不需要把页面撑到失控,也不需要靠一堆嵌套绕过去。给 Scroll 一个明确高度,再让里面的内容自然排列就行。 第一块是纵向滚动。外层 Scroll 定高,内部 Column

ArkUI Scroll:内容一长,别让页面硬撑

今天我们用 Scroll 做一个长内容页面,重点看纵向滚动、横向滚动、滚动条和边缘效果。

Scroll 最适合解决一个朴素问题:内容比容器长。我们不需要把页面撑到失控,也不需要靠一堆嵌套绕过去。给 Scroll 一个明确高度,再让里面的内容自然排列就行。

第一块是纵向滚动。外层 Scroll 定高,内部 Column 放多段内容。scrollable(ScrollDirection.Vertical) 说明滚动方向,scrollBar(BarState.Auto) 让滚动条按需出现。

第二块是横向滚动。标签、快捷入口、横向卡片都适合这种写法:Scroll 里面放 Row,再把方向换成 Horizontal。这里不要急着做复杂联动,先让用户知道内容还能往旁边滑。

第三块是固定区域。上面的说明不动,下面的小区域自己滚动。这种写法在设置页、日志预览、说明面板里很常见。

你自己写页面时,最容易忘记给哪个区域定高度?是外层页面,还是里面那块局部滚动区?

完整代码

class ScrollCard {
  title: string
  desc: string
  color: string

  constructor(title: string, desc: string, color: string) {
    this.title = title
    this.desc = desc
    this.color = color
  }
}

@Entry
@Component
struct ArkUIScrollDemo {
  private notes: ScrollCard[] = [
    new ScrollCard('第一段', '内容超过容器高度时,让 Scroll 接管滚动,页面结构会清楚很多。', '#2563EB'),
    new ScrollCard('第二段', 'Scroll 外层定高度,里面的 Column 继续自然排布。', '#0F766E'),
    new ScrollCard('第三段', 'scrollBar 可以让用户知道这里还能继续看。', '#C2410C'),
    new ScrollCard('第四段', 'edgeEffect 负责边缘反馈,手感会比硬停住自然。', '#7C3AED'),
    new ScrollCard('第五段', '横向内容也可以放进 Scroll,只要把 scrollable 改成 Horizontal。', '#B45309')
  ]
  private tags: string[] = ['ArkUI', 'Scroll', 'Vertical', 'Horizontal', 'BarState', 'EdgeEffect', 'Scrollable']

  @Builder
  sectionTitle(title: string, desc: string) {
    Column({ space: 6 }) {
      Text(title)
        .fontSize(19)
        .fontWeight(FontWeight.Bold)
        .fontColor('#111827')
      Text(desc)
        .fontSize(13)
        .fontColor('#6B7280')
        .lineHeight(20)
    }
    .width('100%')
    .alignItems(HorizontalAlign.Start)
  }

  @Builder
  verticalItem(item: ScrollCard) {
    Column({ space: 6 }) {
      Text(item.title)
        .fontSize(16)
        .fontWeight(FontWeight.Bold)
        .fontColor(item.color)
      Text(item.desc)
        .fontSize(13)
        .fontColor('#4B5563')
        .lineHeight(20)
    }
    .width('100%')
    .padding(12)
    .borderRadius(8)
    .backgroundColor('#F8FAFC')
    .border({ width: 1, color: '#E5E7EB' })
  }

  @Builder
  tagItem(text: string, index: number) {
    Text(text)
      .fontSize(14)
      .fontWeight(FontWeight.Medium)
      .fontColor(index % 2 === 0 ? '#1D4ED8' : '#0F766E')
      .padding({ left: 16, right: 16 })
      .height(44)
      .borderRadius(22)
      .backgroundColor(index % 2 === 0 ? '#DBEAFE' : '#CCFBF1')
  }

  build() {
    Scroll() {
      Column({ space: 22 }) {
        Column({ space: 8 }) {
          Text('ArkUI Scroll')
            .fontSize(28)
            .fontWeight(FontWeight.Bold)
            .fontColor('#111827')
          Text('内容一长,别让页面硬撑')
            .fontSize(16)
            .fontColor('#4B5563')
          Text('Scroll 负责处理超出区域的内容。我们先看纵向、横向、滚动条和边缘效果,不急着加入复杂业务。')
            .fontSize(14)
            .fontColor('#6B7280')
            .lineHeight(22)
        }
        .width('100%')
        .alignItems(HorizontalAlign.Start)

        this.sectionTitle('纵向滚动:给内容一个固定窗口', '外层 Scroll 定高度,内部 Column 可以继续按正常方式往下排。')
        Scroll() {
          Column({ space: 10 }) {
            ForEach(this.notes, (item: ScrollCard) => {
              this.verticalItem(item)
            }, (item: ScrollCard) => item.title)
          }
          .width('100%')
          .padding(12)
        }
        .width('100%')
        .height(230)
        .borderRadius(12)
        .backgroundColor('#F9FAFB')
        .scrollable(ScrollDirection.Vertical)
        .scrollBar(BarState.Auto)
        .scrollBarColor('#2563EB')
        .scrollBarWidth(6)
        .edgeEffect(EdgeEffect.Spring)

        this.sectionTitle('横向滚动:标签和卡片不用硬挤', '横向内容放进 Row,再把 Scroll 的方向切到 Horizontal。')
        Scroll() {
          Row({ space: 10 }) {
            ForEach(this.tags, (item: string, index: number) => {
              this.tagItem(item, index)
            }, (item: string) => item)
          }
          .padding({ left: 12, right: 12 })
        }
        .width('100%')
        .height(76)
        .borderRadius(12)
        .backgroundColor('#F9FAFB')
        .scrollable(ScrollDirection.Horizontal)
        .scrollBar(BarState.Auto)
        .edgeEffect(EdgeEffect.Fade)

        this.sectionTitle('固定区域:长列表也别挤压下面内容', 'Scroll 的重点不是让页面变花,而是把可滚动范围说清楚。')
        Column({ space: 10 }) {
          Row() {
            Text('上方固定说明')
              .fontSize(14)
              .fontWeight(FontWeight.Bold)
              .fontColor('#111827')
            Blank()
            Text('不参与滚动')
              .fontSize(12)
              .fontColor('#6B7280')
          }
          .width('100%')

          Scroll() {
            Column({ space: 8 }) {
              ForEach(this.notes.slice(0, 4), (item: ScrollCard) => {
                Text(item.desc)
                  .fontSize(13)
                  .fontColor('#374151')
                  .lineHeight(20)
                  .width('100%')
                  .padding(10)
                  .borderRadius(8)
                  .backgroundColor('#FFFFFF')
              }, (item: ScrollCard) => item.title)
            }
            .width('100%')
            .padding(10)
          }
          .width('100%')
          .height(150)
          .borderRadius(10)
          .backgroundColor('#EEF2FF')
          .scrollable(ScrollDirection.Vertical)
          .scrollBar(BarState.On)
        }
        .width('100%')
        .padding(14)
        .borderRadius(12)
        .backgroundColor('#F8FAFC')
      }
      .width('100%')
      .padding({ left: 18, right: 18, top: 22, bottom: 32 })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#FFFFFF')
  }
}
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。