HarmonyOS 有没有可以左右上下都可以滚动的组件?

有没有可以左右上下都可以滚动的组件,要做查看大图的效果。

HarmonyOS
2024-10-18 11:03:10
695浏览
收藏 0
回答 1
回答 1
按赞同
/
按时间
superinsect

暂时没有同时支持上下左右滚动的组件,查看大图的demo可以参考:

// xxx.ets  
import router from '@ohos.router'  
@Entry  
@Component  
struct SharedTransitionExample {  
  @State active: boolean = false  
  @State imageNames: Resource[] = [$r('app.media.image1'), $r('app.media.image2'), $r('app.media.image3')]  
  @StorageLink('currentIndex') currentIndex: number = 0  
  build() {  
    Row() {  
      ForEach(this.imageNames, (res: Resource, index: number) => {  
        Column() {  
          Image(res)  
            .width('100%')  
            .height('100%')  
            .objectFit(ImageFit.Contain) // 在组件上绑定缩放比例,可以通过修改缩放比例来实现组件的缩小或者放大  
        }  
        .width(100)  
        .height(100)  
        .clip(true)  
        .sharedTransition('sharedImage' + res.id, {  
          duration: 200,  
          curve: Curve.Linear,  
          zIndex: this.currentIndex === index ? 10 : -10  
        })  
        .onClick(() => {  
          this.currentIndex = index  
          router.pushUrl({  
            url: 'pages/Index', params: {  
              data: this.imageNames,  
            }  
          })  
        })  
      })  
    }.width('100%')  
    .height('100%')  
  }  
  pageTransition() {  
    PageTransitionEnter({ duration: 0, curve: Curve.Linear })  
      .onEnter((type?: RouteType, progress?: number) => {  
      }) // 进场过程中会逐帧触发onEnter回调,入参为动效的归一化进度(0% -- 100%)  
    PageTransitionExit({ duration: 0, curve: Curve.Ease })  
      .onExit((type?: RouteType, progress?: number) => {  
      }) // 退场过程中会逐帧触发onExit回调,入参为动效的归一化进度(0% -- 100%)  
  }  
}
//Index页面  
import window from '@ohos.window';  
import router from '@ohos.router';  
interface Data {  
  data: Resource[];  
}  
enum Direction {  
  None,  
  Left,  
  Right,  
}  
@Entry  
@Component  
struct Index {  
  private swiperController: SwiperController = new SwiperController();  
  @State imageNames: Resource[] = []  
  @StorageLink('currentIndex') currentIndex: number = 0  
  @State screenWidth: number = 0;  
  @State op: number = 0  
  aboutToAppear() {  
    const data = (router.getParams() as Data)  
    this.imageNames = data.data  
    window.getLastWindow(getContext(this)).then(currentWindow => {  
  
      let property = currentWindow.getWindowProperties();  
      this.screenWidth = property.windowRect.width;  
    })  
  }  
  build() {  
    Stack({ alignContent: Alignment.Center }) {  
      Swiper(this.swiperController) {  
        ForEach(this.imageNames, (name: Resource, index: number) => {  
          Column() {  
            ImageComponent({  
              image: name,  
              viewWidth: this.screenWidth,  
              isCurrent: this.currentIndex === index,  
              onNeedGoNext: (dire: Direction) => {  
                if (dire === Direction.Right) {  
                  this.swiperController.showNext()  
                } else if (dire === Direction.Left) {  
                  this.swiperController.showPrevious()  
                }  
              }  
            }).zIndex(index == this.currentIndex ? 2 : 1)  
          }.width('100%')  
          .height('100%')  
          .justifyContent(FlexAlign.Center)  
        })  
      }  
      .index(this.currentIndex)  
      .indicator(false)  
      .disableSwipe(true)  
      .itemSpace(10)  
      .onChange((index: number) => {  
        this.currentIndex = index  
      })  
    }.width('100%').height('100%')  
    .backgroundColor(`rgba(0,0,0,${this.op})`)  
  }  
  pageTransition() {  
PageTransitionEnter({ duration: 200, curve: Curve.Linear })  
.onEnter((type?: RouteType, progress?: number) => {  
if (progress) {  
this.op = progress  
}  
}) // 进场过程中会逐帧触发onEnter回调,入参为动效的归一化进度(0% -- 100  
@Component  
struct ImageComponent {  
private image: Resource = $r('app.media.icon')  
private preGeometryScale: number = 1  
@State geometryScale: number = 1  
private preOffsetX: number = 0  
private preOffsetY: number = 0  
@State geometryOffsetX: number = 0  
@State geometryOffsetY: number = 0  
@State imageWidth: number = 0  
@State imageHeight: number = 0  
@Prop viewWidth: number = 0  
@Prop isCurrent: boolean = false  
private dire: Direction = Direction.None  
private goNext: boolean = true  
private pinching: boolean = false  
private onNeedGoNext: (dire: Direction) => void = () => {  
}  
  
  reset(): Promise<void> | undefined {  
    this.preGeometryScale = 1  
    this.preOffsetX = 0  
    this.preOffsetY = 0  
    this.dire = Direction.None  
    this.goNext = true  
    if (this.geometryScale === 1) {  
      return  
    }  
    return new Promise<void>(res => {  
      animateTo({ duration: 200, onFinish: res }, () => {  
        this.geometryScale = 1  
        this.geometryOffsetX = 0  
        this.geometryOffsetY = 0  
      })  
    })  
  }  
  
  build() {  
    Column() {  
      Image(this.image)  
        .onComplete((e) => {  
          this.imageWidth = (e?.width || 0)  
          this.imageHeight = (e?.height || 0)  
        })  
        .objectFit(ImageFit.Cover)  
        .width(this.imageWidth + 'px')  
        .height(this.imageHeight + 'px')  
        .scale({  
          x: this.geometryScale,  
          y: this.geometryScale  
        })  
        .offset({  
          x: this.geometryOffsetX,  
          y: this.geometryOffsetY  
        })  
        .focusable(true)  
        .objectFit(ImageFit.Cover)  
        .autoResize(false)  
        .sharedTransition('sharedImage' + this.image.id, {  
          duration: 200,  
          curve: Curve.Linear,  
          zIndex: this.isCurrent ? 10 : -10  
        })  
    }  
    .clip(true)  
    .width('100%')  
    .height('100%')  
    .justifyContent(FlexAlign.Center)  
    .hitTestBehavior(HitTestMode.Default)  
    .parallelGesture( // 在组件上绑定二指触发的捏合手势  
      GestureGroup(GestureMode.Parallel,  
        PinchGesture({ fingers: 2 })  
          .onActionStart((event: GestureEvent) => {  
            this.pinching = true  
            this.goNext = false  
          })// 当捏合手势触发时,可以通过回调函数获取缩放比例,从而修改组件的缩放比例  
          .onActionUpdate((event: GestureEvent) => {  
            const s = this.preGeometryScale * event.scale;  
            this.geometryScale = Math.max(0.6, Math.min(2, s))  
          })  
          .onActionEnd(async () => {  
            this.preGeometryScale = this.geometryScale  
            if (this.preGeometryScale < 1) {  
              await this.reset()  
            }  
            this.pinching = false  
          }),  
        PanGesture()  
          .onActionStart((event?: GestureEvent) => {  
          })  
          .onActionUpdate((event?: GestureEvent) => {  
            let offsetX = this.preOffsetX + (event?.offsetX || 0)  
            let offsetY = this.preOffsetY + (event?.offsetY || 0)  
            if (((this.imageWidth * this.geometryScale - this.viewWidth) / 2 - Math.abs(vp2px(offsetX))) <= 0) {  
              if (!this.pinching) {  
                this.dire = offsetX < 0 ? Direction.Right : Direction.Left  
              }  
              return;  
            }  
            this.goNext = false  
            this.geometryOffsetX = offsetX  
            this.geometryOffsetY = offsetY  
          })  
          .onActionEnd((event?: GestureEvent) => {  
            if ((this.dire !== Direction.None)) {  
              if (this.goNext) {  
                this.onNeedGoNext(this.dire)  
                this.reset()  
              }  
              this.goNext = true  
            }  
            this.preOffsetX = this.geometryOffsetX  
            this.preOffsetY = this.geometryOffsetY  
          }),  
      )  
    )  
  }  
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.
  • 159.
  • 160.
  • 161.
  • 162.
  • 163.
  • 164.
  • 165.
  • 166.
  • 167.
  • 168.
  • 169.
  • 170.
  • 171.
  • 172.
  • 173.
  • 174.
  • 175.
  • 176.
  • 177.
  • 178.
  • 179.
  • 180.
  • 181.
  • 182.
  • 183.
  • 184.
  • 185.
  • 186.
  • 187.
  • 188.
  • 189.
  • 190.
  • 191.
  • 192.
  • 193.
  • 194.
  • 195.
  • 196.
  • 197.
  • 198.
  • 199.
  • 200.
  • 201.
  • 202.
  • 203.
  • 204.
  • 205.
  • 206.
  • 207.
  • 208.
  • 209.
  • 210.
  • 211.
  • 212.
  • 213.
  • 214.
  • 215.
  • 216.
  • 217.
  • 218.
  • 219.
  • 220.
  • 221.
  • 222.
  • 223.
  • 224.
  • 225.
  • 226.
  • 227.
  • 228.
  • 229.
  • 230.
  • 231.
分享
微博
QQ
微信
回复
2024-10-18 18:14:26


相关问题
HarmonyOS ArkTS有没有可以组件继承?
811浏览 • 1回复 待解决
HarmonyOS 有没有提供可以直播sdk
767浏览 • 1回复 待解决