黑马健康-欢迎页面业务

注:本人在创作过程中的疑难杂点,全以TODO Z-形式在代码中标注。设计所有页面的TODO会在结尾的注意事项中展示

一,业务逻辑

当用户打开某个软件时,弹出一个窗口询问是否同意某个隐私协议,

若同意直接就跳转首页并记住保存的选项,确保下次不会再弹出窗口;

若不同意直接退出APP。

简单如下图示:

二,实现技术

1.用户首选项:持久化存储自定义弹窗的按钮状态量数据

2.自定义弹窗:

三,代码框架

1.WelcomePage页面代码框架

...

@Entry
@Component
struct WelcomePage {
  //TODO z5. 关闭APP
  context=getContext(this) as common.UIAbilityContext

  /*创建弹窗*/
  controller:CustomDialogController=new CustomDialogController(...)
  
  //TODO z4. 欢迎页面一加载就弹出弹窗
  async aboutToAppear(){...}

  /*跳转首页函数*/
  jumpToIndex(){... }

  /*弹窗同意函数*/
  onConfirm(){...}

  /*弹窗不同意函数*/
  exitAPP(){...}
  build(){
    Column({space:10}){
      //1.中央slogon 
      Row(){...}
      ...
      //2.logo
      Image(...)...
      //3.文字描述
      Row() {
        Text('黑马健康支持')...
        Text('IPv6')
          ...
        Text('网络')...
      }
      Text('减更多指黑马健康App希望通过软件工具的形式,帮助更多用户实现身材管理')
        ...
      Text('浙ICP备0000000号-36D')
        ...

  }
    ...
  }
}

2.PreferenceUtil页面代码框架

import...
class PreferenceUtil{
    private pref: preferences.Preferences
    async loadPreference(context){
        if (!this.pref) {...}
        try {...} catch (e) {...}
    }
    //给键值对存值
    async putPreferenceValue(key: string, value: preferences.ValueType){
        if (!this.pref) {...}
        try {...} catch (e) {...}
    }
    //给默认值,取值
  async getPreferenceValue(key: string, defaultValue:preferences.ValueType){        
        if (!this.pref) {...}
        try {...} catch (e) {...}
    }
    const preferenceUtil = new PreferenceUtil()

    export default preferenceUtil as PreferenceUtil

3.在EntryAbility页面应用启动时加载用户首选项

export default class EntryAbility extends UIAbility {
  async onCreate(want, launchParam) {
    
    // 1.加载用户首选项
    PreferenceUtil.loadPreference(this.context)
    // 2.初始化日期
    AppStorage.SetOrCreate(CommonConstants.RECORD_DATE, DateUtil.beginTimeOfDay(new Date()))
    // 3.初始化RDB工具
    await DbUtil.initDB(this.context)
    // 4.创建record表
    DbUtil.createTable(RecordModel.getCreateTableSql())

    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
  }

4.自定义组件代码框架

import ...

//自定义弹窗
@CustomDialog
export struct UserPrivacyDialog {
  contlloer:CustomDialogController
  confirm:()=>void
  cancel:()=>void
  build() {//弹窗内容
    Column(...){
      //1.标题
      Text(...)
      //2.内容
      Text(...)
      //3.按钮
      Button(...)
        ...
        .onClick(()=>{...})
      Button(...)
        ...
        .onClick(()=>{...})
    }
    ...
  }
}

 四,完整代码

1.UserPrivacyDialog页面--自定义组件

//TODO z1.主页面的自定义组件放view下;z2. dialog自动弹出自定义组件模版
import { CommonConstants } from '../../common/constants/CommonConstants'


//@Preview//TODO z4. 呈现组件的渲染
//自定义弹窗
@CustomDialog
export struct UserPrivacyDialog {
  contlloer:CustomDialogController
  //TODO z5. 只声明不实现 TODO w2. 为什么函数由用户决定
  confirm:()=>void
  cancel:()=>void
  build() {//弹窗内容
    Column({space:CommonConstants.SPACE_10}){
      //1.标题
      Text($r('app.string.user_privacy_title'))
        .fontWeight(CommonConstants.FONT_WEIGHT_700)
        .fontSize(20)
      //2.内容
      Text($r('app.string.user_privacy_content'))
      //3.按钮
      Button($r('app.string.agree_label'))
        .width(150)
        .backgroundColor($r('app.color.primary_color'))
        .onClick(()=>{
          this.confirm()
          this.contlloer.close()
        })
      Button($r('app.string.refuse_label'))
        .width(150)
        .backgroundColor($r('app.color.lightest_primary_color'))
        .fontColor($r('app.color.light_gray'))
        .onClick(()=>{//TODO w1. 为什么()=>{}
          this.cancel()
          this.contlloer.close()
        })
    }
    .width('100%')//TODO z3. 高度自适应,有多少内容就多高
    .padding(10)
  }
}

 2.WelcomePage页面--增加自定义组件


import { UserPrivacyDialog } from '../view/welcome/UserPrivacyDialog'
import common from '@ohos.app.ability.common'
import preferences from '@ohos.data.preferences'
import preferenceUtil from '../common/utils/PreferenceUtil'
import router from '@ohos.router'
//TODO Z2.细节优化,字体格式统一化 z3.设置参数保证后续可修改
@Extend(Text) function opacitywhiteText(opacity:number,fontsize:number=10){
  .fontSize(fontsize)
  .fontColor(Color.White)
  .opacity(opacity)//透明度
}

//TODO Z8. 设置变量key,调用用户首选项put,get都用到
const PREF_KEY='userPrivacyKey'
@Entry
@Component
struct WelcomePage {
  //TODO z5. 关闭APP
  context=getContext(this) as common.UIAbilityContext
  /*创建弹窗*/
  controller:CustomDialogController=new CustomDialogController({
    builder:UserPrivacyDialog({
      confirm:()=>this.onConfirm(),
      cancel:()=>this.exitAPP()
    })//TODO z3.需要传confirm,cancel两个函数,需要定义俩专门处理的函数
  })
  //TODO z4. 欢迎页面一加载就弹出弹窗
  async aboutToAppear(){
    //1.加载首选项
    let isAgree = await preferenceUtil.getPreferenceValue(PREF_KEY,false)//TODO z6. 默认值false,状态量未改变时,继续弹窗
    //2.判断是否同意
    if(isAgree){
      //2.1同意,跳转首页//TODO z6.router.replaceUrl方法跳转,不用push压栈因为欢迎页面出现一次即可
      this.jumpToIndex()
    }else{
      //2.2不同意,弹窗
      this.controller.open()
    }
  }
  /*跳转首页函数*/
  jumpToIndex(){
    //TODO z7.跳转时需要缓冲:加载数据/看欢迎页面广告
    //setTimeout定时器
    setTimeout(()=>{
      router.replaceUrl({
        url:'pages/Index'
      })
    },1000)//延迟1000ms
  }
  /*弹窗同意函数*/
  onConfirm(){
    //1.保存首选项
    preferenceUtil.putPreferenceValue(PREF_KEY,true)
    //2.跳转到页面
    this.jumpToIndex()
  }
  /*弹窗不同意函数*/
  exitAPP(){
    //退出APP
    this.context.terminateSelf()
  }
  build(){
    //space:子元素间距
    Column({space:10}){
      //1.中央slogon TODO z1.通过layoutWeight(1)布局权重实现第一张图片站
      Row(){
        Image($r('app.media.home_slogan')).width(260)
      }
      .layoutWeight(1)
      //2.logo
      Image($r('app.media.home_logo')).width(150)
      //3.文字描述
      Row() {
        Text('黑马健康支持').opacitywhiteText(0.8,12)
        Text('IPv6')
          .opacitywhiteText(0.8,12)
            //套边框;solid(实现);radius(边框弧度)
          .border({ style: BorderStyle.Solid, width: 1, radius: 15, color: Color.White })
          .padding({ left: 5, right: 5 })
        Text('网络').opacitywhiteText(0.8,12)
      }
      Text('减更多指黑马健康App希望通过软件工具的形式,帮助更多用户实现身材管理')
        .opacitywhiteText(0.6,10)
      Text('浙ICP备0000000号-36D')
        .opacitywhiteText(0.4,10)
        .margin({bottom:35})

  }
    .height('100%')
    .width('100%')
    .backgroundColor($r('app.color.welcome_page_background'))
  }
}

3.PreferenceUtil页面--用户首选项

import preferences from '@ohos.data.preferences';
import { CommonConstants } from '../constants/CommonConstants';
import Logger from './Logger';

class PreferenceUtil{
  private pref: preferences.Preferences

  async loadPreference(context){
    try { // 加载preferences
      this.pref = await preferences.getPreferences(context, CommonConstants.H_STORE)
      Logger.debug(`加载Preferences[${CommonConstants.H_STORE}]成功`)
    } catch (e) {
      Logger.debug(`加载Preferences[${CommonConstants.H_STORE}]失败`, JSON.stringify(e))
    }
  }
//给键值对存值
  async putPreferenceValue(key: string, value: preferences.ValueType){
    if (!this.pref) {
      Logger.debug(`Preferences[${CommonConstants.H_STORE}]尚未初始化!`)
      return
    }
    try {
      // 写入数据
      await this.pref.put(key, value)
      // 刷盘
      await this.pref.flush()
      Logger.debug(`保存Preferences[${key} = ${value}]成功`)
    } catch (e) {
      Logger.debug(`保存Preferences[${key} = ${value}]失败`, JSON.stringify(e))
    }
  }
//给默认值,取值
  async getPreferenceValue(key: string, defaultValue: preferences.ValueType){
    if (!this.pref) {
      Logger.debug(`Preferences[${CommonConstants.H_STORE}]尚未初始化!`)
      return
    }
    try {
      // 读数据
      let value = await this.pref.get(key, defaultValue)
      Logger.debug(`读取Preferences[${key} = ${value}]成功`)
      return value
    } catch (e) {
      Logger.debug(`读取Preferences[${key}]失败`, JSON.stringify(e))
    }
  }
}

const preferenceUtil = new PreferenceUtil()

export default preferenceUtil as PreferenceUtil

 4.EntryAbility页面--加载用户首选项

import UIAbility from '@ohos.app.ability.UIAbility';
import hilog from '@ohos.hilog';
import window from '@ohos.window';
import { CommonConstants } from '../common/constants/CommonConstants';
import DateUtil from '../common/utils/DateUtil';
import DbUtil from '../common/utils/DbUtil';
import PreferenceUtil from '../common/utils/PreferenceUtil';
import RecordModel from '../model/RecordModel';

export default class EntryAbility extends UIAbility {
  async onCreate(want, launchParam) {
    //TODO z1.应用启动时加载用户首选项
    // 1.加载用户首选项
    PreferenceUtil.loadPreference(this.context)
    // 2.初始化日期
    AppStorage.SetOrCreate(CommonConstants.RECORD_DATE, DateUtil.beginTimeOfDay(new Date()))
    // 3.初始化RDB工具
    await DbUtil.initDB(this.context)
    // 4.创建record表
    DbUtil.createTable(RecordModel.getCreateTableSql())

    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
  }

  onDestroy() {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
  }

  onWindowStageCreate(windowStage: window.WindowStage) {
    // Main window is created, set main page for this ability
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
    //TODO z1. 默认加载页面是WelcomePage
    windowStage.loadContent('pages/WelcomePage', (err, data) => {
      if (err.code) {
        hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
        return;
      }
      hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
    });
  }

  onWindowStageDestroy() {
    // Main window is destroyed, release UI related resources
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
  }

  onForeground() {
    // Ability has brought to foreground
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
  }

  onBackground() {
    // Ability has back to background
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
  }
}

 五,注意事项

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值