HarmonyOS 如何实现自定义弹窗从底部弹出关闭弹回效果

想实现将弹窗框改为占满屏幕宽和到最下方屏幕底部边缘,以及弹窗效果改为从屏幕下方边缘向上拉起,退出则反向拉回至底部隐藏。

HarmonyOS
2024-09-24 12:39:19
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
superinsect
const INIT_OFFSET: number = 400;  
  
@Component  
export struct CustomDialogC {  
  @State heightSize: string = "100%";  
  @State offsetY: number = INIT_OFFSET;  
  @State positionY: number = INIT_OFFSET;  
  
  build() {  
    NavDestination() {  
      Stack({ alignContent: Alignment.Bottom }) {  
        Column() {  
        }  
        .width("100%")  
        .height(this.heightSize)  
        .onClick(() => {  
          console.log(this.heightSize)  
          animateTo({  
            duration: 300,  
            curve: Curve.Friction,  
            onFinish: () => {  
              AppRouter.pop();  
            }  
          }, () => {  
            this.heightSize = "0%"  
          })  
        })  
  
        Column() {  
          Text("弹窗")  
            .fontColor(Color.White)  
        }  
        .width("100%")  
        .backgroundColor(Color.Blue)  
        .height(this.heightSize)  
        .offset({ x: 0, y: this.offsetY })  
        .gesture(  
          PanGesture({ direction: PanDirection.Vertical, distance: 1 })  
            .onActionUpdate((event?: GestureEvent) => {  
              this.handlePanGestureUpdate(event?.offsetY);  
            })  
            .onActionEnd((event?: GestureEvent) => {  
              this.handlePanGestureEnd(event?.offsetY);  
            })  
        )  
        .transition(  
          TransitionEffect.move(TransitionEdge.BOTTOM)  
            .animation({  
              duration: 500,  
              curve: Curve.Friction  
            })  
        )  
      }  
      .width("100%")  
      .height("100%")  
    }  
    .mode(NavDestinationMode.DIALOG)  
    .hideTitleBar(true)  
  }  
  
  handlePanGestureUpdate(offsetY?: number): void {  
    if (!offsetY || (offsetY < 0 && this.positionY < INIT_OFFSET)) {  
      return;  
    }  
    console.log(`Update offsetY:${offsetY}`)  
    this.offsetY = this.positionY + offsetY!;  
  }  
  
  handlePanGestureEnd(offsetY?: number): void {  
    if (!offsetY) {  
      return;  
    }  
    console.log(`End offsetY:${offsetY}`)  
    if (this.positionY < INIT_OFFSET) {  
      if (offsetY > 300) {  
        this.close();  
      } else if (offsetY > 150) {  
        this.reset();  
      } else {  
        animateTo({  
          curve: Curve.Friction,  
        }, () => {  
          this.positionY = this.offsetY;  
        })  
      }  
    } else {  
      if (offsetY < -200) {  
        animateTo({  
          curve: Curve.Friction,  
        }, () => {  
          this.offsetY = 0;  
          this.positionY = this.offsetY;  
        })  
      } else if (offsetY > 200) {  
        this.close();  
      } else {  
        this.reset();  
      }  
    }  
  }  
  
  private reset() {  
    animateTo({  
      curve: Curve.Friction  
    }, () => {  
      this.offsetY = INIT_OFFSET;  
      this.positionY = this.offsetY;  
    });  
  }  
  
  private close() {  
    animateTo({  
      curve: Curve.Friction,  
      onFinish: () => {  
        AppRouter.pop();  
      }  
    }, () => {  
      this.heightSize = "0%";  
    });  
  }  
}
分享
微博
QQ
微信
回复
2024-09-24 16:04:18
相关问题
HarmonyOS 如何实现底部弹窗效果
11浏览 • 1回复 待解决
弹窗打开、关闭动画是否支持自定义
2358浏览 • 1回复 待解决
HarmonyOS CoverFlow效果自定义组件实现
266浏览 • 1回复 待解决
使用自定义弹窗实现分享弹窗
566浏览 • 1回复 待解决
自定义弹窗自定义转场动画
1128浏览 • 1回复 待解决
HarmonyOS 自定义弹窗选择
356浏览 • 1回复 待解决