目录

如何动态设置Swiper组件的nextMargin属性

问题现象

如何在Swiper组件运行时调整其nextMargin属性以此来控制Swiper页面的后边距?

效果预览

背景知识

解决方案

实现思路如下:

  1. 为了使动画过渡柔和,在切换动画开始时,可以在onAnimationStart回调中结合animateTo方法来更新当前轮播页的索引。
  2. 设置nextMargin属性来控制后边距,从而展示下一项的部分内容。

防止出现闪动,animateTo中参数duration数值需要保持和Swiper组件属性duration数值保持一致。

@Entry
@Component
struct SwiperDemo {
  private swiperController: SwiperController = new SwiperController();
  private data: string[] = ['0', '1', '2', '3', '4', '5', '6'];
  @State currentIndex: number = 0; // 当前页面

  build() {
    Column({ space: 25 }) {
      Swiper(this.swiperController) {
        ForEach(this.data, (item: string) => {
          Column() {
            Text(item).width(40).height(40).textAlign(TextAlign.Center).fontSize(30);
          }
          .width('100%')
          .height('100%')
          .border({ width: 3, color: '#ff24d8e5' });
        });
      }
      .displayMode(SwiperDisplayMode.STRETCH)
      .displayCount(1) // 设置Swiper视窗内元素显示个数
      .loop(false)
      .index(this.currentIndex)
      .cachedCount(2)
      .indicator(true)
      .duration(500) // 设置子组件切换的动画时长
      .nextMargin(this.currentIndex <= 2 ? 50 : 0) // nextMargin属性来控制后边距
      .curve(Curve.Linear)
      .backgroundColor('#ffbbfce2')
      .onAnimationStart((targetIndex: number) => {
        // 在onAnimationStart回调中结合animateTo方法来更新当前轮播页的索引
        this.getUIContext()?.animateTo
        ({
          duration: 500,
          curve: Curve.Linear,
          playMode: PlayMode.Normal,
        }, () => {
          this.currentIndex = targetIndex;
        });
      });
    }.width('100%').height('20%').margin({ top: 5 });
  }
}

常见FAQ

Q:在onChange回调中修改当前页索引,然后通过nextMargin动态设置后边距,为什么会出现闪动?

A:因为onChange回调在动画执行结束时触发,因此会出现闪动。建议在onAnimationStart回调中修改当前页索引,然后通过nextMargin动态设置后边距。