Skip to content

HarmonyOS 实现用户首次启动时弹出协议弹窗

更新: 2025/8/19 字数: 0 字 时长: 0 分钟

自定义弹窗

CustomDialogComponent.ets(简化,去除绝大部分样式代码,便于查看逻辑类的代码)

支持“查看隐私政策/用户协议”“同意/不同意”四个动作。

跳转协议界面使用了 router.pushUrl({ url: 'pages/PrivacyPolicy' })

  • 同意时写入 policy_agreed=true;

  • 不同意时 terminateSelf() 退出;

typescript
@CustomDialog
export default struct CustomDialogComponent {
  controller: CustomDialogController;
  cancel: () => void = () => {};
  confirm: () => void = () => {};
  openPrivacy?: () => void;
  openAgreement?: () => void;

  build() {
    Column() {
      Text('用户协议与隐私政策')
      Text('用户协议与隐私政策')
        .textAlign(TextAlign.Center)

      Text('为保障您的权益,请先阅读并同意用户协议与隐私政策后继续使用本应用。')
        .textAlign(TextAlign.Center)

      Row({ space: 12 }) {
        Button({ type: ButtonType.Normal }) {
          Text('查看隐私政策')
        }
        .onClick(() => {
          this.openPrivacy && this.openPrivacy();
          this.controller.close();
        })

        Button({ type: ButtonType.Normal }) {
          Text('查看用户协议')
        }
        .onClick(() => {
          this.openAgreement && this.openAgreement();
          this.controller.close();
        })
      }

      Row({ space: 12 }) {
        Button({ type: ButtonType.Normal }) {
          Text('不同意')
        }
        .onClick(() => {
          this.controller.close();
          this.cancel();
        })

        Button({ type: ButtonType.Capsule }) {
          Text('同意并继续')
        }
         .onClick(() => {
           this.controller.close();
           this.confirm();
         })
      }
    }
  }
}

在应用首页中导入

typescript
import CustomDialogComponent from '../view/CustomDialogComponent';

添加一个控制器

// 首启协议弹窗控制器(使用自定义组件)
  private firstStartController: CustomDialogController = new CustomDialogController({
    builder: CustomDialogComponent({
      openPrivacy: () => router.pushUrl({ url: 'pages/PrivacyPolicy' }),
      openAgreement: () => router.pushUrl({ url: 'pages/UserAgreement' }),
      confirm: async () => {
        try {
          const uiCtx = this.getUIContext().getHostContext() as common.UIAbilityContext;
          const prefs = await dataPreferences.getPreferences(uiCtx, 'app_prefs');
          await prefs.put('policy_agreed', true);
          await prefs.flush();
        } catch (e) {
          const msg = (e as Error)?.message ?? String(e);
          hilog.error(DOMAIN, TAG, 'save policy flag failed: ' + msg);
        }
      },
      cancel: () => {
        try {
          const uiCtx = this.getUIContext().getHostContext() as common.UIAbilityContext;
          uiCtx.terminateSelf();
        } catch (e) {
          const msg = (e as Error)?.message ?? String(e);
          hilog.error(DOMAIN, TAG, 'terminateSelf failed: ' + msg);
        }
      }
    }),
    autoCancel: false,
    alignment: DialogAlignment.Center
  });

编写一个检查逻辑,在应用打开时,检查是否勾选了同意协议

onPageShow() {
    // 首次启动检查
    (async () => {
      try {
        const uiCtx = this.getUIContext().getHostContext() as common.UIAbilityContext;
        const prefs = await dataPreferences.getPreferences(uiCtx, 'app_prefs');
        const agreed = (await prefs.get('policy_agreed', false)) as boolean;
        if (!agreed) {
          this.firstStartController.open();
        }
      } catch (e) {
        const msg = (e as Error)?.message ?? String(e);
        hilog.error(DOMAIN, TAG, 'read policy flag failed: ' + msg);
      }
    })();

    this.filterPublicNotes();
    this.filterPrivateNotes();
    if (!this.isShowingPrivate) {
      this.fetchPoetry();
    }
  }

TIP

主要不要忘记编写main_pages.json,将协议页面跳转路径写上 { "src": [ "pages/Index", "pages/NoteEditPage", "pages/PrivacyPolicy", "pages/UserAgreement" ] }

本站访客数 人次 本站总访问量