Scroll初始时自动滚动一段距离

Scroll容器初始创建时就能自动滚动一段距离(或者说偏移量)。使用场景包括:进入页面自动滚动到指定位置(例如点击某个微博或者直接点击评论按钮,跳转后自动滚动到评论区位置)

HarmonyOS
2024-05-26 15:35:25
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
superinsect

使用的核心API

核心代码解释

方案1:aboutToAppear回调函数中设置延迟操作(setTimeout接口)

代码示例:

const  scroller: Scroller = new Scroller() 
// scroller.scrollTo({ xOffset: 0, yOffset: 100 })  未生效 
  
@Entry 
@Component 
struct ScrollDemo { 
  private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
  
  aboutToAppear(): void { 
    setTimeout(() => { 
      scroller.scrollTo({ xOffset: 0, yOffset: 100 }) // 包在setTimeout()里生效 
    },100) 
  } 
  
  build() { 
    Stack({ alignContent: Alignment.TopStart }) { 
      Scroll(scroller) { 
        Column() { 
          ForEach(this.arr, (item: number) => { 
            Text(item.toString()) 
              .width('90%') 
              .height(150) 
              .backgroundColor(0xFFFFFF) 
              .borderRadius(15) 
              .fontSize(16) 
              .textAlign(TextAlign.Center) 
              .margin({ top: 10 }) 
          }, (item: string) => item) 
        }.width('100%') 
      } 
      .scrollable(ScrollDirection.Vertical) // 滚动方向纵向 
      .onScroll((xOffset: number, yOffset: number) => { 
        console.info('scrolled: xoffset->'+ xOffset + ' yoffset: ' + yOffset) 
      }) 
    }.width('100%').height('100%').backgroundColor(0xDCDCDC) 
  } 
}

运行日志:

方案2:自定义类继承scroller,并重写构造方法。在构造方法中设置延迟操作

代码示例:

// 自定义scroller类 
export class MyScroller extends  Scroller { 
  constructor(delayTime: number) { //重写构造方法,构造时设置延时器 
    super() 
    setTimeout(() => { 
      this.scrollTo({xOffset: 0, yOffset: 100}) 
    },delayTime) 
  } 
} 
  
//测试页 
import { MyScroller } from '../viewmodel/MyScroller' 
  
const  scroller: Scroller = new MyScroller(100) //这里使用自定义的scroller 
// scroller.scrollTo({ xOffset: 0, yOffset: 100 })  未生效 
  
@Entry 
@Component 
struct ScrollDemo { 
  private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
  
  build() { 
    Stack({ alignContent: Alignment.TopStart }) { 
      Scroll(scroller) { 
        Column() { 
          ForEach(this.arr, (item: number) => { 
            Text(item.toString()) 
              .width('90%') 
              .height(150) 
              .backgroundColor(0xFFFFFF) 
              .borderRadius(15) 
              .fontSize(16) 
              .textAlign(TextAlign.Center) 
              .margin({ top: 10 }) 
          }, (item: string) => item) 
        }.width('100%') 
      } 
      .scrollable(ScrollDirection.Vertical) // 滚动方向纵向 
      .onScroll((xOffset: number, yOffset: number) => { 
        console.info('scrolled: xoffset->'+ xOffset + ' yoffset: ' + yOffset) 
      }) 
    }.width('100%').height('100%').backgroundColor(0xDCDCDC) 
  } 
}

运行日志:

方案3:基于组件通用的onAppear回调函数挂载卸载事件,在该回到函数中执行scroller的scrollTo函数或者scrollBy函数

代码示例:

const  scroller: Scroller = new Scroller() 
// scroller.scrollTo({ xOffset: 0, yOffset: 100 })  未生效 
  
@Entry 
@Component 
struct ScrollDemo { 
  private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
  
  build() { 
    Stack({ alignContent: Alignment.TopStart }) { 
      Scroll(scroller) { 
        Column() { 
          ForEach(this.arr, (item: number) => { 
            Text(item.toString()) 
              .width('90%') 
              .height(150) 
              .backgroundColor(0xFFFFFF) 
              .borderRadius(15) 
              .fontSize(16) 
              .textAlign(TextAlign.Center) 
              .margin({ top: 10 }) 
          }, (item: string) => item) 
        }.width('100%') 
        .onAppear(() => { //子组件挂载显示时触发该回调,调用scrollTo完成滚动一定距离 
          scroller.scrollTo({xOffset: 0, yOffset: 100}) 
        }) 
      } 
      .scrollable(ScrollDirection.Vertical) // 滚动方向纵向 
      .onScroll((xOffset: number, yOffset: number) => { 
        console.info('scrolled: xoffset->'+ xOffset + ' yoffset: ' + yOffset) 
      }) 
    }.width('100%').height('100%').backgroundColor(0xDCDCDC) 
  } 
}

运行日志:

上述是单一页面场景,可能有些业务场景 scroll容器和子组件以及业务页是分开的,scroll容器和子组件基于Builder函数构建。Builder函数场景示例代码如下:

@Builder 
export function testScrollView(params: ScrollUIParams) { 
  Scroll(params.scroller) { 
    Column() { 
      ForEach([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], (item: number) => { 
        Text(item.toString()) 
          .width('90%') 
          .height(150) 
          .backgroundColor(0xFFFFFF) 
          .borderRadius(15) 
          .fontSize(16) 
          .textAlign(TextAlign.Center) 
          .margin({ top: 10 }) 
      }, (item: string) => item) 
    }.width('100%') 
  }.onAppear(() => { 
    params.scroller.scrollTo({xOffset: 0, yOffset: 100}) // 此处可设置初始偏移量 
  }).onScroll((xoffSet: number, yOffSet: number) => { 
    console.info(`scrolled xofset:${xoffSet}, yoffset:${yOffSet}`) 
  }).scrollable(params?.uiParams) 
}

注:当子组件与Scroll容器分开时,可以改为在子组件上的onAppear回调中调用。

实现效果

分享
微博
QQ
微信
回复
2024-05-27 20:38:43
相关问题
鸿蒙-如何实现播放一段音频
9872浏览 • 2回复 待解决
如何实现RSA的公钥PK加密一段文字
207浏览 • 1回复 待解决
如何获取List组件滚动滚动距离
1037浏览 • 1回复 待解决
如何获取Scroll组件的当前滚动偏移量
810浏览 • 1回复 待解决
mysql 初始用户定是root吗?
3072浏览 • 1回复 待解决