HarmonyOS 鸿蒙Next swiper中前后两个组件的高度如何设置

发布于 1周前 作者 eggper 来自 鸿蒙OS

HarmonyOS 鸿蒙Next swiper中前后两个组件的高度如何设置

cke_274.jpeg

如何实现图示效果,在swiper中将左右两个图片的高度进行缩小


更多关于HarmonyOS 鸿蒙Next swiper中前后两个组件的高度如何设置的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

可以参考以下demo

class MyDataSource implements IDataSource {
  private list: string[] = []

  constructor(list: string[]) {
    this.list = list
  }

  totalCount(): number {
    return this.list.length
  }

  getData(index: number): string {
    return this.list[index]
  }

  registerDataChangeListener(listener: DataChangeListener): void {
  }

  unregisterDataChangeListener() {
  }
}


const MAX_SCALE = 1 // 最大缩放
const MIN_SCALE = 0.8 // 最小缩放
// 可通过以下两个参数变化观察效果,然后优化
const PAGE_DURATION = 100 // 子控件动画时长
const SWIPER_DURATION = 500 // swiper组件切换动画时长
// 拖动时用来计算缩放,影响拖动缩放速度,可根据屏幕尺寸来定
const DRAGGING_MAX_DISTANCE = 1000

@Entry
@Component
struct Gauge3 {
  private swiperController: SwiperController = new SwiperController()
  private data: MyDataSource = new MyDataSource([])
  @State currentIndex: number = 0
  @State scaleArray: number[] = [];
  startSwiperOffset: number = 0

  aboutToAppear(): void {
    let list: string[] = []
    for (let i = 0; i <= 5; i++) {
      list.push(i.toString());
      this.scaleArray.push(i == 0 ? MAX_SCALE : MIN_SCALE)
    }
    this.data = new MyDataSource(list)
  }

  build() {
    Column({ space: 25 }) {
      Swiper(this.swiperController) {
        LazyForEach(this.data, (item: string, index: number) => {
          Column() {
            Text(item)
              .width(40)
              .height(40)
              .textAlign(TextAlign.Center)
              .fontSize(30)
          }
          .width("100%")
          .height('100%')
          .backgroundColor(0xFFFF00)
          .scale({ x: this.scaleArray[index], y: this.scaleArray[index] })
          .animation({
            duration: PAGE_DURATION,
            curve: Curve.Linear
          })
        }, (item: string, index: number) => item)
      }
      .displayMode(SwiperDisplayMode.STRETCH)
      .displayCount(1)
      .width('100%')
      .height('100%')
      .index(this.currentIndex) //状态变量
      .cachedCount(2)
      .indicator(true)
      // .loop(true)
      .duration(SWIPER_DURATION)
      .itemSpace(0)
      .nextMargin(40)
      .prevMargin(40)
      .curve(Curve.Linear)
      .backgroundColor(0x999999)
      .onChange((index: number) => {
        this.currentIndex = index
        this.scaleArray[this.currentIndex] = MAX_SCALE;
        if (this.currentIndex == 0) {
          this.scaleArray[this.scaleArray.length - 1] = MIN_SCALE
        } else {
          this.scaleArray[this.currentIndex -1] = MIN_SCALE
        }
        if (this.currentIndex == this.scaleArray.length - 1) {
          this.scaleArray[0] = MIN_SCALE
        } else {
          this.scaleArray[this.currentIndex + 1] = MIN_SCALE
        }
      })
      .onGestureSwipe((index: number, extraInfo: SwiperAnimationEvent) => {
        if (this.startSwiperOffset == 0) {
          this.startSwiperOffset = extraInfo.currentOffset;
        }
        let offset: number = extraInfo.currentOffset
        let currentScale: number = this.scaleArray[index]
        let nextIndex = (index == this.scaleArray.length - 1 ? 0 : index + 1)
        let preIndex = (index == 0 ? this.scaleArray.length - 1 : index - 1)
        let nextScale: number = this.scaleArray[nextIndex]
        let preScale: number = this.scaleArray[preIndex]

        // 滑动距离
        let distance = Math.abs(this.startSwiperOffset - offset)
        currentScale = MAX_SCALE - Math.min(distance / DRAGGING_MAX_DISTANCE, MAX_SCALE - MIN_SCALE)
        if (this.startSwiperOffset > offset) {
          nextScale = MIN_SCALE + Math.min(distance / DRAGGING_MAX_DISTANCE, MAX_SCALE - MIN_SCALE)
          preScale = MIN_SCALE
        } else {
          preScale = MIN_SCALE + Math.min(distance / DRAGGING_MAX_DISTANCE, MAX_SCALE - MIN_SCALE)
          nextScale = MIN_SCALE
        }
        this.scaleArray[this.currentIndex] = currentScale
        this.scaleArray[nextIndex] = nextScale
        this.scaleArray[preIndex] = preScale
      })
      .onAnimationStart((index: number, targetIndex: number, extraInfo: SwiperAnimationEvent) => {
        if (index == targetIndex) {
          let nextIndex = (index == this.scaleArray.length - 1 ? 0 : index + 1)
          let preIndex = (index == 0 ? this.scaleArray.length - 1 : index - 1)
          this.scaleArray[index] = MAX_SCALE
          this.scaleArray[nextIndex] = MIN_SCALE
          this.scaleArray[preIndex] = MIN_SCALE
        } else {
          let nextIndex = (targetIndex == this.scaleArray.length - 1 ? 0 : targetIndex + 1)
          let preIndex = (targetIndex == 0 ? this.scaleArray.length - 1 : targetIndex - 1)
          this.scaleArray[targetIndex] = MAX_SCALE
          this.scaleArray[nextIndex] = MIN_SCALE
          this.scaleArray[preIndex] = MIN_SCALE
        }
      })
      .onAnimationEnd((index: number, extraInfo: SwiperAnimationEvent) => {
        this.startSwiperOffset = 0
      })
    }
    .width('100%')
    .height('20%')
    .margin({ top: 5 })
  }
}

通过调整MIN_SCALE和prevMargin、nextMargin调整左右图片高度和距离

更多关于HarmonyOS 鸿蒙Next swiper中前后两个组件的高度如何设置的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


实现了,感谢大佬!

在HarmonyOS鸿蒙系统的Next swiper组件中,前后两个组件(或称为页面/视图)的高度设置通常是通过布局文件(XML)或代码动态控制的。以下是一些基本方法:

  1. XML布局文件

    • 在XML布局文件中,为swiper的子组件(如Page1和Page2)设置高度属性。可以使用height属性直接指定固定值(如dpsp),或者使用match_parentwrap_content等关键字。
    • 示例:<Component height="500dp" ... /><Component height="match_parent" ... />
  2. 代码动态设置

    • 在Java或Kotlin代码中,通过组件的setHeight方法或布局参数来动态设置高度。
    • 示例:component.setHeight(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 500, getResources().getDisplayMetrics()));
  3. 注意事项

    • 确保swiper组件及其子组件的布局方向(orientation)正确设置,以匹配高度设置的预期效果。
    • 如果swiper包含滚动效果,高度设置可能影响滚动行为。

如果问题依旧没法解决请联系官网客服,官网地址是: https://www.itying.com/category-93-b0.html

回到顶部