写在前面
- 博文为鸿蒙os自定义弹窗及数据持久化(Preferences)详解
- 需要DevEco工具
- 需要搭建本地模拟器
不积跬步无以至千里,不积小流无以成江海
需求
实现用户开屏幕广告及保存用户隐私协议
如何实现
- 首页将启动页改为广告页
- 实现隐私协议弹窗
- 点击同意将用户同意值存储起来
- 不同意及退出App
动手开搞
一、用户进入app首先触发entryability文件中的onDestroy生命周期钩子,其次触发
onWindowStageCreate钩子将启动页修改为
//修改启动页
onWindowStageCreate(windowStage: window.WindowStage) {
// Main window is created, set main page for this ability
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
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) ?? '');
});
二、 在子组件中创建一个弹窗
/**
* 用户协议弹窗
*/
import { CommonConstants } from '../../../common/constants/CommonConstants'
@CustomDialog //这里的注解表示创建一个弹窗
export default struct UserPrivacyDialog {
controller: CustomDialogController
confirm:()=> void // 确定回调
cancel:()=> void // 取消回调
build() {
Column({space:CommonConstants.SPACE_10}){
Text($r('app.string.user_privacy_title'))
.fontWeight(CommonConstants.FONT_WEIGHT_700)
.fontSize(20)
Text($r('app.string.user_privacy_content'))
Button('同意')
.width(150)
.backgroundColor($r('app.color.primary_color'))
.onClick(()=>{
this.confirm()
this.controller.close()
})
Button('不同意')
.backgroundColor($r('app.color.lightest_primary_color'))
.width(150)
.fontColor($r('app.color.light_gray'))
.onClick(()=>{
this.cancel()
this.controller.close()
})
}
.width('100%')
.padding(20)
}
}
在父组件中引入该弹窗
import UserPrivacyDialog from './view/UserPrivacyDialog/UserPrivacyDialog'
controller:CustomDialogController = new CustomDialogController({
builder: UserPrivacyDialog({
confirm:()=> this.onConfirm(),
cancel:() => this.exitApp()
})
})
三、这里涉及到一个知识数据持久化(用户首选项)
- 定义
用户首选项为应用提供Key-Value键值型的数据处理能力,支持应用持久化轻量级数据,并对其修改和查询。当用户希望有一个全局唯一存储的地方,可以采用用户首选项来进行存储。
- 运作机制
- 如何使用
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
- 使用注意
Preferences会将该数据缓存在内存中,当用户读取的时候,能够快速从内存中获取数据。Preferences会随着存放的数据量越多而导致应用占用的内存越大,因此,Preferences不适合存放过多的数据,适用的场景一般为应用保存用户的个性化设置(字体大小,是否开启夜间模式)等。
- 使用该工具实现需求
1.1 首先在用户点击app加载首选项
async onCreate(want, launchParam) {
// 加载用户首选项
await PreferenceUtil.loadPreference(this.context)
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
}
1.2 用户点击同意修改数据
/**
* 用户选择同意
*/
onConfirm(){
PreferenceUtil.putPreferenceValue(PREF_KEY,true)
this.jumpIndex()
}
1.3 用户不同意则退出app
这里涉及到一个工具包需在组件中引入该包
// 获取上下文退出app
context = getContext(this) as common.UIAbilityContext
/**
* 用户选择不同意退出app
*/
exitApp(){
// 退出app
this.context.terminateSelf()
}