HarmonyOS Swiper结合Image图片显示问题?

Swiper 结合 Image使用,Image组件通过scale属性缩放后, 超出swiper单页的区域应该不显示, 现在显示效果异常,有没有好的解决方案

目前我Image组件监听Pan手势控制translate属性实现图片拖动,我想要放大的Image拖到边缘自动触发Swiper的next事件,应该如何处理

import hilog from '@ohos.hilog';

@Entry
@Component
struct Index {
  private sc = new SwiperController()
  @State private scaleValue: number = 1

  build() {
    Stack(){
      Swiper(this.sc) {
        Column() {
          Image("https://img.***.com/imgextra/i3/1917047079/O1CN01JX9jtW22AEclEOGq3_!!2-item_pic.png")
            .objectFit(ImageFit.Auto)
            .width(`${720 * this.scaleValue}lpx`)
            .scale({ x: this.scaleValue, y: this.scaleValue, z: 1 })
            .gesture(
              // 监听捏合手势事件
              PinchGesture({ fingers: 2 })
                .onActionStart(() => {
                  console.log('pinch start');
                })
                .onActionUpdate((event: GestureEvent | undefined) => {
                  if (event) {
                    this.scaleValue = event.scale;
                  }
                })
                .onActionEnd(() => {
                  this.scaleValue = 1
                })
            )
        }.width('100%')
        .height('100%')
        .justifyContent(FlexAlign.Center)

        Column() {
          Image("https://img.***.com/imgextra/i2/O1CN01lX3caY1cDjfPguEwb_!!0-tbbala.jpg")
            .objectFit(ImageFit.Auto)
            .width(`${720 * this.scaleValue}lpx`)
            .scale({ x: this.scaleValue, y: this.scaleValue, z: 1 })
            .gesture(
              // 监听捏合手势事件
              PinchGesture({ fingers: 2 })
                .onActionStart(() => {
                  console.log('pinch start');
                })
                .onActionUpdate((event: GestureEvent | undefined) => {
                  if (event) {
                    this.scaleValue = event.scale;
                    console.log("" + event.scale)
                  } else {
                    hilog.error(0x3d00, 'JSAPP', 'undefined event')
                  }
                })
                .onActionEnd(() => {
                  this.scaleValue = 1
                })
            )
        }.width('100%')
        .height('100%')
        .justifyContent(FlexAlign.Center)
      }.indicator(false)
      .autoPlay(false)
      .loop(false)
      Row() {
        Text('x')
          .fontFamily('tbIconFont')
          .fontSize(16)
          .fontColor(Color.White)
        Text('0/0')
          .fontFamily('tbIconFont')
          .fontSize(16)
          .fontColor(Color.White)
        Text('x')
          .fontFamily('tbIconFont')
          .fontSize(16)
          .fontColor(Color.White)
      }.padding({
        left:'12lpx',
        right:'12lpx',
        top:'12lpx'
      })
      .justifyContent(FlexAlign.SpaceBetween)
      .width('100%')
    }.width('100%').height('100%').backgroundColor('#9a000000')
    .alignContent(Alignment.TopStart)
  }
}
阅读 416
1 个回答

请参考以下代码调用 CommonImagePage, 传入 imageModel, imageModel 的 imageArray里为图片列表,currentIndex为当前点击图片的索引。

export class CommonImageDetailModel {
  imageArray: Array<Resource>
  currentIndex: number

  constructor(imageArray: Array<Resource>, currentIndex: number) {
    this.imageArray = imageArray
    this.currentIndex = currentIndex
  }
}

@Component
export struct CommonImagePage {
  imageModel: CommonImageDetailModel = new CommonImageDetailModel([], 0)
  @State currentIndex: number = 0
  @StorageLink("windowHeight") windowHeight: number = 0 //手机window大小
  @State scaleArray: Array<ImageScaleModel> = []

  aboutToAppear() {
    this.currentIndex = this.imageModel.currentIndex + 1
    for (let index = 0; index < this.imageModel.imageArray.length; index++) {
      this.scaleArray.push(new ImageScaleModel(1, 1))
    }
  }

  build() {
    NavDestination() {
      Stack() {
        Swiper() {
          ForEach(this.imageModel.imageArray, (icon: Resource, idx) => {
            Scroll() {
              ImageContentView({imageScale: this.scaleArray[idx], icon: icon})
            }
            .scrollable(ScrollDirection.Horizontal)
            .nestedScroll({
              scrollForward: NestedScrollMode.SELF_FIRST,
              scrollBackward: NestedScrollMode.SELF_FIRST
            })
            .width('100%')
            .height('100%')
          })
        }
        .index(this.imageModel.currentIndex)
        .loop(false)
        .backgroundColor('#000000')
        .autoPlay(false)
        .indicator(false)
        .width('100%')
        .height('100%')
        .onChange((index: number) => {
          this.currentIndex = index + 1
        })

        if (this.imageModel.imageArray.length > 1) {
          Text(this.currentIndex.toString() + '/' + this.imageModel.imageArray.length.toString())
            .fontColor('#ffffff')
            .fontSize(12)
            .height(20)
            .position({x:10, y: px2vp(this.windowHeight) - 20 -60})
        }
      }
    }
    .hideTitleBar(true)
  }
}

@Component
struct ImageContentView {
  @State imageScale: ImageScaleModel = new ImageScaleModel(1, 1)
  @StorageLink("windowWidth") windowWidth: number = 0
  icon: Resource = $r('app.media.icon')
  @Consume('pageInfo') pageInfo: NavPathStack;

  build() {
    Image(this.icon)
      .width(px2vp(this.windowWidth) * this.imageScale.scaleValue)
      .objectFit(ImageFit.Contain)
      .gesture(
        TapGesture()
          .onAction((_event: GestureEvent) => {
            this.pageInfo.pop()
          })
      )
      .priorityGesture(
        TapGesture({count: 2})
          .onAction((_event: GestureEvent) => {
            if (this.imageScale.scaleValue > 1) {
              this.imageScale.scaleValue = 1
              this.imageScale.pinchValue = 1
            } else {
              this.imageScale.scaleValue = 2
              this.imageScale.pinchValue = 2
            }
          })
      )
      .gesture(
        PinchGesture({ fingers: 2 })
          .onActionUpdate((event?: GestureEvent) => {
            if (event) {
              this.imageScale.scaleValue = this.imageScale.pinchValue * event.scale
            }
          })
          .onActionEnd(() => {
            if (this.imageScale.scaleValue < 1) {
              this.imageScale.scaleValue = 1
            }
            if (this.imageScale.scaleValue > 3) {
              this.imageScale.scaleValue = 3
            }
            this.imageScale.pinchValue = this.imageScale.scaleValue
            console.info('Pinch end')
          })
      )
  }
}

@Observed
class ImageScaleModel {
  public scaleValue: number
  public pinchValue: number
  constructor(scaleValue: number, pinchValue: number) {
    this.scaleValue = scaleValue
    this.pinchValue = pinchValue
  }
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进