鸿蒙开发 - Scroll组件

自适应延伸是指在不同尺寸设备下,当页面的内容超出屏幕大小而无法完全显示时,可以通过滚动条进行拖动展示。这种方法适用于线性布局中内容无法一屏展示的场景。通常有以下两种实现方式。

1.在List中添加滚动条:当List子项过多一屏放不下时,可以将每一项子元素放置在不同的组件中,通过滚动条进行拖动展示。可以通过scrollBar属性设置滚动条的常驻状态,edgeEffect属性设置拖动到内容最末端的回弹效果。

2.使用Scroll组件:在线性布局中,开发者可以进行垂直方向或者水平方向的布局。当一屏无法完全显示时,可以在ColumnRow组件的外层包裹一个可滚动的容器组件Scroll来实现可滑动的线性布局。

垂直方向布局Column中使用Scroll组件

@Entry
@Component
struct ScrollExample {
  scroller: Scroller = new Scroller();
  private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

  build() {
    Scroll(this.scroller) {
      Column() {
        ForEach(this.arr, (item) => {
          Text(item.toString())
            .width('90%')
            .height(150)
            .backgroundColor(0xFFFFFF)
            .borderRadius(15)
            .fontSize(16)
            .textAlign(TextAlign.Center)
            .margin({ top: 10 })
        }, item => item)
      }.width('100%')
    }
    .backgroundColor(0xDCDCDC)
    .scrollable(ScrollDirection.Vertical) // 滚动方向为垂直方向
    .scrollBar(BarState.On) // 滚动条常驻显示
    .scrollBarColor(Color.Gray) // 滚动条颜色
    .scrollBarWidth(10) // 滚动条宽度
    .edgeEffect(EdgeEffect.Spring) // 滚动到边沿后回弹
  }
}

弹性布局Flex中使用Scroll组件

@Entry
@Component
struct StackSample {
  private arr: string[] = ["APP101", "APP102", "APP103", "APP104", "APP105", "APP106", "APP107", "APP108", "APP109", "APP110", "APP111", "AP112", "APP113", "APP114", "APP1115", "APP116", "APP117", "APP118", "APP119", "APP120", "APP121", "APP122", "APP123", "APP124", "APP125", "APP126", "APP127"];
  private scroller: Scroller = new Scroller();
  private space: number = 10;

  // 计算高度
  getHeight(): number {
    var height = (this.arr.length / 3.0);
    // 取余=0
    if (height == 0) {
      height = height * (100 + this.space);
    } else {
      height = (height + 1) * (100 + this.space);
    }
    return height;
  }

  build() {
    Stack({ alignContent: Alignment.Bottom }) {
      Scroll(this.scroller) {
        Flex({ wrap: FlexWrap.Wrap, direction: FlexDirection.Column }) {
          ForEach(this.arr, (item) => {
            Text(item)
              .width(100)
              .height(100)
              .fontSize(16)
              .margin(this.space)
              .textAlign(TextAlign.Center)
              .borderRadius(10)
              .backgroundColor(0xFFFFFF)
          }, item => item)
        }.width('100%').height(this.getHeight())
      }
      .backgroundColor(0xDCDCDC)
      .scrollable(ScrollDirection.Vertical) // 滚动方向为垂直方向
      .scrollBar(BarState.On) // 滚动条常驻显示
      .scrollBarColor(Color.Gray) // 滚动条颜色
      .scrollBarWidth(5) // 滚动条宽度
      .edgeEffect(EdgeEffect.Spring) // 滚动到边沿后回弹

      Flex({ justifyContent: FlexAlign.SpaceAround, alignItems: ItemAlign.Center }) {
        Text('联系人').fontSize(16)
        Text('设置').fontSize(16)
        Text('短信').fontSize(16)
      }
      .width('50%')
      .height(50)
      .backgroundColor('#16302e2e')
      .margin({ bottom: 15 })
      .borderRadius(15)
    }.width('100%').height('100%').backgroundColor('#CFD0CF')
  }
}

两者区别ColumnRow使用Scroll时,会自动计算容器容量高度,可以直接滑动到最底部;而Flex使用Scroll时,需要计算height属性的具体的值,Flexdirection默认是横向的,如果使用 .height('100%') ,会出现滑不到最底部的情况,只能出现一屏数据,所以需要使用 direction: FlexDirection.Column,然后手动计算出高度.height(this.getHeight()),然后再预览就可以滑到底部了。

### 鸿蒙 Scroll 组件触底事件处理方法 在鸿蒙系统中,`ScrollView` 的触底事件可以通过监听特定的滚动状态来实现。当 `ScrollView` 达到底部时,可以触发相应的回调函数来进行数据加载或其他操作。 为了检测 ScrollView 是否到达底部,通常的做法是在组件上绑定滚动事件监听器,并计算当前滚动位置与最大可滚动距离的关系。一旦接近或达到底部,则执行指定的操作,比如加载更多数据[^2]。 下面是一个简单的例子展示如何在鸿蒙应用中实现这一功能: #### 实现代码示例 ```javascript // JavaScript部分 export default { data: { isLoadingMore: false, hasMoreData: true, // 假设有更多的数据可供加载 dataList: [], // 数据列表 }, onInit() { this.loadInitialData(); }, loadInitialData() { // 初始化加载一些数据... setTimeout(() => { let newData = Array.from({ length: 10 }, (_, i) => 'Item ' + (i + 1)); this.dataList.push(...newData); }, 500); }, handleScroll(event) { const scrollHeight = event.scrollHeight; const scrollTop = event.scrollTop; const clientHeight = event.clientHeight; if (!this.isLoadingMore && !this.hasMoreData) return; // 判断是否已经滚到底部附近 if ((scrollTop + clientHeight >= scrollHeight - 50 /*提前量*/) && this.hasMoreData) { console.log('已触底'); this.isLoadingMore = true; setTimeout(() => { // 模拟网络请求获取新一批的数据并更新界面 let newItems = ['New Item 1', 'New Item 2']; this.dataList.push(...newItems); // 更新标志位以便下次继续判断 this.isLoadingMore = false; this.hasMoreData = Math.random() > 0.5 ? true : false; //随机决定是否有更多数据 console.log(`加载完成,还有更多数据吗?${this.hasMoreData}`); }, 1000); //模拟延迟 } } } ``` ```xml <!-- XML布局文件 --> <template> <div class="container"> <!-- 使用scroll-view包裹内容区 --> <scroll-view @scroll="handleScroll" style="height: 100%;"> <list-item v-for="(item,index) in dataList" :key="index">{{ item }}</list-item> </scroll-view> <!-- 加载指示符 --> <loading-indicator v-if="isLoadingMore"></loading-indicator> </div> </template> ``` 此代码片段展示了如何利用 `@scroll` 事件监听器捕获用户的滚动行为,并通过比较视口内的可见区域 (`clientHeight`) 和整个文档的高度 (`scrollHeight`) 来确定何时应该发起新的数据请求。同时,在每次成功加载之后都会重置相关标记变量以准备下一次可能发生的加载动作[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值