HarmonyOS 如何实现类似DialogActivity的效果

需要跳转一个Page,但是希望这个Page的样式是一个Dialog样式

HarmonyOS
2024-12-18 16:20:23
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
Excelsior_abit

可以使用自定义弹窗组件来实现效果。参考地址:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-methods-custom-dialog-box-V5#示例PageB直接为一个空页面,在页面的 aboutToAppear()方法中打开自定义弹窗,弹窗内部按钮加上router.back()方法,处理完本身逻辑后返回PageA。

PageA在entry包下:

import { router } from '@kit.ArkUI';

import('library_hsp/src/main/ets/pages/PageB'); // 引入共享包中的命名路由页面

@Entry({ routeName: "PageA" })
@Component
struct PageA {
  @State message: string = 'PageA';

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(32)
          .fontWeight(FontWeight.Bold)

        Button("进入B页面").onClick(() => {
          router.pushNamedRoute({
            name: 'PageB'
          })
        })
      }
      .width('100%')
    }
    .height('100%')
  }
}

PageB在HSP包下:

import { router } from '@kit.ArkUI'

@CustomDialog
struct CustomDialogExample {
  @Link textValue: string
  @Link inputValue: string
  controller?: CustomDialogController
  // 若尝试在CustomDialog中传入多个其他的Controller,以实现在CustomDialog中打开另一个或另一些CustomDialog,那么此处需要将指向自己的controller放在所有controller的后面
  cancel: () => void = () => {
  }
  confirm: () => void = () => {
  }

  build() {
    Column() {
      Text('Change text').fontSize(20).margin({ top: 10, bottom: 10 })
      TextInput({ placeholder: '', text: this.textValue }).height(60).width('90%')
        .onChange((value: string) => {
          this.textValue = value
        })
      Text('Whether to change a text?').fontSize(16).margin({ bottom: 10 })
      Flex({ justifyContent: FlexAlign.SpaceAround }) {
        Button('cancel')
          .onClick(() => {
            if (this.controller != undefined) {
              this.controller.close()
              this.cancel()
            }
          }).backgroundColor(0xffffff).fontColor(Color.Black)
        Button('confirm')
          .onClick(() => {
            if (this.controller != undefined) {
              this.inputValue = this.textValue
              this.controller.close()
              this.confirm()
            }
          }).backgroundColor(0xffffff).fontColor(Color.Red)
      }.margin({ bottom: 10 })

    }.borderRadius(10)

  }
}

@Entry({ routeName: 'PageB' })
@Component
export struct PageB {
  @State textValue: string = ''
  @State inputValue: string = 'click me'
  dialogController: CustomDialogController | null = new CustomDialogController({
    builder: CustomDialogExample({
      cancel: () => {
        this.onCancel()
      },
      confirm: () => {
        this.onAccept()
      },
      textValue: $textValue,
      inputValue: $inputValue
    }),
    cancel: this.exitApp,
    autoCancel: true,
    alignment: DialogAlignment.Bottom,
    offset: { dx: 0, dy: -20 },
    gridCount: 4,
    customStyle: false,
    cornerRadius: 10,
  })

  aboutToAppear(): void {
    this.dialogController?.open()
  }

  // 在自定义组件即将析构销毁时将dialogControlle置空
  aboutToDisappear() {
    this.dialogController = null // 将dialogController置空
  }

  onCancel() {
    console.info('Callback when the first button is clicked')
    router.back()
  }

  onAccept() {
    console.info('Callback when the second button is clicked')
    router.back()
  }

  exitApp() {
    console.info('Click the callback in the blank area')
  }

  build() {
    Column() {
    }.width('100%').margin({ top: 5 })
  }
}

可以把弹窗页代码编写成自定义弹窗格式合入到打开弹窗页的入口页的module中,然后使用自定义弹窗的方法来谈起弹窗页。通过router跳转后,新页面透明底下印出入口页面是做不到的。如果不用自定义弹窗,也可以自定义一个组件通过stack布局放置在入口页面前,并设置该组件visibility属性来先隐藏该页面,需要谈起弹窗后,再设置visibility为可见,达到伪弹窗的效果。这种情况的前提也是代码入口页与弹窗页代码再同一个页面进行显隐。


分享
微博
QQ
微信
回复
2024-12-18 17:53:05
相关问题
如何实现类似keyframes效果
2092浏览 • 1回复 待解决
HarmonyOS 怎么实现类似SnackBar效果
364浏览 • 1回复 待解决
HarmonyOS 类似翻页效果实现
607浏览 • 1回复 待解决