HarmonyOS鸿蒙Next中请问怎么实现轮播图,但是显示三个,第一个会缩放放大,其他的还是不变

HarmonyOS鸿蒙Next中请问怎么实现轮播图,但是显示三个,第一个会缩放放大,其他的还是不变 现在需求是轮播图,滑动到第一个会缩放放大,其他的还是不变,有三方库吗

6 回复

使用 Swiper 实现轮播,通过 customContentTransition 接口,自定义切换动画变化透明度、缩放页面、抵消系统默认位移、渲染层级等。下面代码实现切换过程中两边缩放效果。开发者可参考 demo 中的实现,稍作修改。

图片

@Entry
@Component
struct Index {
  @State items: string[] = ['1', '2', '3', '4', '5']
  @State scaleList: number[] = [0.8, 1, 0.8, 0.8, 0.8];

  build() {
    Swiper() {
      ForEach(this.items, (item: string, index: number) => {
        Text(item)
          .textAlign(TextAlign.Center)
          .width('100%')
          .height(300)
          .backgroundColor('#999')
          .fontColor('#fff')
          .fontSize(30)
          .scale({ x: this.scaleList[index], y: this.scaleList[index] })

      }, (item: string) => item)
    }
    .width('100%')
    .prevMargin(50)
    .nextMargin(50)
    .index(1)
    .interval(5000)
    .loop(true)
    .indicator(false)
    .margin({ top: 100 })
    .customContentTransition({
      timeout: 1000,
      transition: (proxy: SwiperContentTransitionProxy) => {
        const scale = 0.8
        const scaleFactor = 1 - scale * Math.abs(proxy.position); 
        this.scaleList[proxy.index] = Math.max(scaleFactor, scale);
      }
    })
  }
}

更多关于HarmonyOS鸿蒙Next中请问怎么实现轮播图,但是显示三个,第一个会缩放放大,其他的还是不变的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


楼上回复的非常棒,不过如果想要使用三方库,可以参考链接:https://ohpm.openharmony.cn/#/cn/detail/@abner%2Fbanner,

期待HarmonyOS能在未来带来更多创新的技术和理念。

推荐使用Swiper组件:

// xxx.ets
class MyDataSource implements IDataSource {
  private list: number[] = [];
  constructor(list: number[]) {
    this.list = list;
  }
  totalCount(): number {
    return this.list.length;
  }
  getData(index: number): number {
    return this.list[index];
  }
  registerDataChangeListener(listener: DataChangeListener): void {
  }
  unregisterDataChangeListener() {
  }
}
@Entry
@Component
struct SwiperExample {
  private swiperController: SwiperController = new SwiperController();
  private data: MyDataSource = new MyDataSource([]);
  aboutToAppear(): void {
    let list: number[] = [];
    for (let i = 1; i <= 10; i++) {
      list.push(i);
    }
    this.data = new MyDataSource(list);
  }
  build() {
    Column({ space: 5 }) {
      Swiper(this.swiperController) {
        LazyForEach(this.data, (item: string) => {
          Text(item.toString())
            .width('90%')
            .height(160)
            .backgroundColor(0xAFEEEE)
            .textAlign(TextAlign.Center)
            .fontSize(30)
        }, (item: string) => item)
      }
      .cachedCount(2)
      .index(1)
      .autoPlay(true)
      .interval(4000)
      .loop(true)
      .indicatorInteractive(true)
      .duration(1000)
      .itemSpace(5)
      .prevMargin(35)
      .nextMargin(35)
      .indicator( // 设置圆点导航点样式
        new DotIndicator()
          .itemWidth(15)
          .itemHeight(15)
          .selectedItemWidth(15)
          .selectedItemHeight(15)
          .color(Color.Gray)
          .selectedColor(Color.Blue))
      .displayArrow({ // 设置导航点箭头样式
        showBackground: true,
        isSidebarMiddle: true,
        backgroundSize: 24,
        backgroundColor: Color.White,
        arrowSize: 18,
        arrowColor: Color.Blue
      }, false)
      .curve(Curve.Linear)
      .onChange((index: number) => {
        console.info(index.toString());
      })
      .onScrollStateChanged((event: ScrollState) => {
        console.info("event: " + event);
      })
      .onGestureSwipe((index: number, extraInfo: SwiperAnimationEvent) => {
        console.info("index: " + index);
        console.info("current offset: " + extraInfo.currentOffset);
      })
      .onAnimationStart((index: number, targetIndex: number, extraInfo: SwiperAnimationEvent) => {
        console.info("index: " + index);
        console.info("targetIndex: " + targetIndex);
        console.info("current offset: " + extraInfo.currentOffset);
        console.info("target offset: " + extraInfo.targetOffset);
        console.info("velocity: " + extraInfo.velocity);
      })
      .onAnimationEnd((index: number, extraInfo: SwiperAnimationEvent) => {
        console.info("index: " + index);
        console.info("current offset: " + extraInfo.currentOffset);
      })
      Row({ space: 12 }) {
        Button('showPrevious')
          .onClick(() => {
            this.swiperController.showPrevious();
          })
        Button('showNext')
          .onClick(() => {
            this.swiperController.showNext();
          })
      }.margin(5)
      Row({ space: 5 }) {
        Button('FAST 0')
          .onClick(() => {
            this.swiperController.changeIndex(0, SwiperAnimationMode.FAST_ANIMATION);
          })
        Button('FAST 3')
          .onClick(() => {
            this.swiperController.changeIndex(3, SwiperAnimationMode.FAST_ANIMATION);
          })
        Button('FAST ' + 9)
          .onClick(() => {
            this.swiperController.changeIndex(9, SwiperAnimationMode.FAST_ANIMATION);
          })
      }.margin(5)
    }.width('100%')
    .margin({ top: 5 })
  }
}

cke_977.png

在HarmonyOS Next中实现显示三个轮播项且第一项放大的效果,可通过以下步骤实现:

  1. 使用Swiper组件创建轮播容器,设置displayCount为3显示三项
  2. 通过SwiperonChange事件监听当前激活项索引
  3. 在子项组件中使用scale属性实现缩放效果,根据当前索引判断:
    • 当索引为0时应用放大变换(如scale({x:1.2,y:1.2})
    • 其他索引保持正常尺寸(scale({x:1,y:1})
  4. 结合animateTo添加平滑过渡动画

关键代码结构:

@State currentIndex: number = 0

Swiper({
  index: this.currentIndex,
  displayCount: 3,
  onChange: (index: number) => {
    this.currentIndex = index
  }
}) {
  ForEach(this.data, (item, index) => {
    Image(item.src)
      .scale({
        x: this.currentIndex === index ? 1.2 : 1,
        y: this.currentIndex === index ? 1.2 : 1
      })
      .animation({...})
  })
}

在HarmonyOS Next中实现轮播图并控制第一个元素缩放,可以通过以下方式:

  1. 使用Swiper组件:这是HarmonyOS内置的轮播组件,支持循环滑动和自定义指示器。

  2. 结合自定义动画

    • onChange事件中监听当前激活项
    • 通过条件判断,为第一个元素添加缩放动画
    • 使用animateTo方法或属性动画实现缩放效果
  3. 示例代码框架

@State currentIndex: number = 0

Swiper(this.currentIndex) {
  ForEach(this.imageList, (item, index) => {
    Image(item)
      .scale(this.currentIndex === 0 ? { x: 1.2, y: 1.2 } : { x: 1.0, y: 1.0 })
      .animation({ duration: 300, curve: Curve.EaseInOut })
  })
}
.onChange((index: number) => {
  this.currentIndex = index
})
  1. 关于三方库:目前HarmonyOS生态还在完善中,建议优先使用官方组件实现。可以关注华为开发者联盟的更新,看是否有相关UI库发布。

这种方式完全基于原生能力,性能更好,且无需依赖第三方库。

回到顶部