首选项数据持久化
帝心:全网首发HarmonyOS4.0教程(哔哩哔哩)创作者。致力于推广鸿蒙教程开发。
首选项
简介
本示例使用@ohos.data.preferences 接口,展示了使用首选项持久化存储数据的功能。源码参考
效果预览
| default主题 | Simple主题 | grey主题 |
|---|---|---|
使用说明
1.点击顶部titleBar的右侧切换按钮,弹出主题菜单,选择任意主题则切换相应的主题界面;
2.退出应用再重新进入,显示上一次退出前的主题界面。
开发步骤
1. 准备常量数据
-
三种主题名称组成的数组
-
三种主题数据:图标icon和对应name
-
存储主题数据的时候 要指定首选项对象即文件(数据库)名称
一个项目可以有使用一个首选项对象存数据,也可以使用多个首选项文件分开存不同的数据。建议分门别类设计。 -
存储主题的时候,需要设计一个key值
一个首选项对象(文件)可以存很多个键值对数据。根据key区分。
import { ImageAndName } from "../model/ImageAndName"
export default class DxConstants{
// 三种主题的名称
static readonly THEME_NAMES:string[] = ['default','grey','Simple']
// 三种主题数据
static readonly themeDataArr: ImageAndName[][] = [
[
{ image: "/image/model1/dialer.png", name: "dianhua" },
{ image: "/image/model1/shopping.png", name: "shangcheng" },
{ image: "/image/model1/notes.png", name: "beiwanglu" },
{ image: "/image/model1/settings.png", name: "shezhi" },
{ image: "/image/model1/camera.png", name: "xiangji" },
{ image: "/image/model1/gallery.png", name: "xiangce" },
{ image: "/image/model1/music.png", name: "yinyue" },
{ image: "/image/model1/video.png", name: "shipin" },
],
[
{ image: "/image/model2/simplicityCall.png", name: "dianhua" },
{ image: "/image/model2/simplicityShop.png", name: "shangcheng" },
{ image: "/image/model2/simplicityNotes.png", name: "beiwanglu" },
{ image: "/image/model2/simplicitySetting.png", name: "shezhi" },
{ image: "/image/model2/simplicityCamera.png", name: "xiangji" },
{ image: "/image/model2/simplicityPhotos.png", name: "xiangce" },
{ image: "/image/model2/simplicityMusic.png", name: "yinyue" },
{ image: "/image/model2/simplicityVideo.png", name: "shipin" },
],
[
{ image: "/image/model3/pwcall.png", name: "dianhua" },
{ image: "/image/model3/pwshop.png", name: "shangcheng" },
{ image: "/image/model3/pwnotes.png", name: "beiwanglu" },
{ image: "/image/model3/pwsetting.png", name: "shezhi" },
{ image: "/image/model3/pwcamera.png", name: "xiangji" },
{ image: "/image/model3/pwphotos.png", name: "xiangce" },
{ image: "/image/model3/pwmusic.png", name: "yinyue" },
{ image: "/image/model3/pwvideo.png", name: "shipin" },
]
]
// 存储主题的首选项的 文件(数据库)名称
static readonly PREFERENCES_THEME:string = "theme.db"
// 存储主题的时候 key
static readonly THEME_KEY:string = "themeModel"
}
2. 准备首选项工具类
- 设计成map数据结构,方便存多种首选项文件对象。后期存主题时,使用一个首选项对象,存字体大小时,可以使用另一个。如有其他需要使用不同的首选项对象时,灵活扩展。
- 首选项对象创建需要上下文对象和该文件数据库的name。设计好loadPreference()方法,创建好首选项对象后加入到map中。
- 设计保存数据和获取数据的方法。
既然设计逻辑为该项目有多个首选项对象,那么在 保存/获取 数据的时候就需要确定从 哪个首选项对象 身上 存储/获取 哪个key
// 首选项工具栏,提供首选项增上改查功能
import { preferences } from '@kit.ArkData'
import { Context } from '@ohos.arkui.UIContext'
class PreferencesUtil {
// 准备一个map, 用来存多个首选项对象
preMap: Map<string, preferences.Preferences> = new Map()
// 加载 首选项对象
loadPreference(context: Context, name: string) {
try {
// 该接口 第二个参数 在next修改为配置项 而非字符串
let pre: preferences.Preferences = preferences.getPreferencesSync(context, { name })
// 存到首选项 map中
this.preMap.set(name, pre)
console.log('PreferencesUtil', `加载Preferences【${name}】成功`)
} catch (e) {
console.log('PreferencesUtil', `加载Preferences【${name}】失败`, JSON.stringify(e))
}
}
// 保存数据
putPreferenceVal(preferenceName: string, key: string, value: preferences.ValueType) {
if (!this.preMap.has(preferenceName)) {
console.log('PreferencesUtil', `加载Preferences【${preferenceName}】尚未初始化`)
return
}
try {
// 从数组中获取该首选项对象
let pref = this.preMap.get(preferenceName)
// 写入数据
pref?.putSync(key, value)
// 刷盘
pref?.flush()
console.log('PreferencesUtil', `保存【${preferenceName}】-【${key}】-【${value}】成功`)
} catch (e) {
console.log('PreferencesUtil', `保存【${preferenceName}】-【${key}】-【${value}】失败`, JSON.stringify(e))
}
}
// 获取数据
getPreferenceVal(preferenceName: string, key: string, defaultVal: preferences.ValueType){
if (!this.preMap.has(preferenceName)) {
console.log('PreferencesUtil', `加载Preferences【${preferenceName}】尚未初始化`)
return
}
try {
let pref = this.preMap.get(preferenceName)
let val = pref?.getSync(key, defaultVal)
console.log('PreferencesUtil', `读取【${preferenceName}】-【${key}】-【${val}】成功`)
return val
}catch (e){
console.log('PreferencesUtil', `读取【${preferenceName}】-【${key}】失败`,JSON.stringify(e))
// try和catch都要有返回
return defaultVal
}
}
}
export default new PreferencesUtil()
3. 入口类中创建首选项对象
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
// 初始化首选项
let context = this.context
// 存储主题的 首选项文件放到 map中
PreferencesUtil.loadPreference(context,DxConstants.PREFERENCES_THEME)
}
4. 在UI中使用
- 切换主题:在首页预先设置好几套主体数据,使用preferences.getPreferences获取使用Preferences对象,调用Preferences.get() 读取缓存中的参数,得到当前应该展示哪一套主体。每次点击切换按钮都会调用Preferences.put()来重新修改参数,然后使用 Preferences.flush()保存并刷新文件内容。 源码参考:Index.ets 。
import DxConstants from "../common/DxConstants";
import PreferencesUtil from "../common/PreferencesUtil";
import { ImageAndName } from "../model/ImageAndName";
@Entry
@Component
struct Index {
@StorageProp("info") message: string = ""
// 当前页面展示的数据
@State theme: ImageAndName[] = DxConstants.themeDataArr[0]
@State themeName: string = DxConstants.THEME_KEY[0]
// 页面加载先查看上一次的主题是什么
aboutToAppear(): void {
this.themeName = PreferencesUtil.getPreferenceVal(
DxConstants.PREFERENCES_THEME,
DxConstants.THEME_KEY,
DxConstants.THEME_NAMES[0]
) as string
// 根据 modelName 获取索引值
let index = DxConstants.THEME_NAMES.indexOf(this.themeName)
// 初始化当前模型数组
this.theme = DxConstants.themeDataArr[index]
}
// 修改当前显示模式
changeTheme(index: number) {
// 主题名称
this.themeName = DxConstants.THEME_NAMES[index]
// 主题数组
this.theme = DxConstants.themeDataArr[index]
// 持久化存储
PreferencesUtil.putPreferenceVal(
DxConstants.PREFERENCES_THEME,
DxConstants.THEME_KEY,
DxConstants.THEME_NAMES[index]
)
}
build() {
Column({ space: 30 }) {
Text(this.message).fontColor("#fff50909")
Divider().color(Color.Red)
Row() {
Text("主题:"+this.themeName)
.fontSize(20)
.layoutWeight(5)
.padding({ left: 10 })
.fontColor(Color.White)
.fontWeight(FontWeight.Bold)
Image($r('app.media.change'))
.key('changeBtn')
.id('changeBtn')
.height(30)
.layoutWeight(1)
.objectFit(ImageFit.ScaleDown)
.bindMenu([
{
value: DxConstants.THEME_NAMES[0],
action: () => {
// change and save model0 :default
this.changeTheme(0)
}
},
{
value: DxConstants.THEME_NAMES[1],
action: () => {
// change and save model1 :simplicity
this.changeTheme(1)
}
},
{
value: DxConstants.THEME_NAMES[2],
action: () => {
// change and save model2 :pomelo
this.changeTheme(2)
}
}
])
}
.width('100%')
.height(50)
.backgroundColor('#0D9FFB')
Grid() {
ForEach(this.theme, (item: ImageAndName) => {
GridItem() {
Column() {
Image(item.image)
.width(70)
.height(70)
.padding(10)
.objectFit(ImageFit.Fill)
Text(item.name).fontSize(15)
}
.width(90)
.height(90)
}
}, (item: ImageAndName) => JSON.stringify(item))
}
.rowsGap(10)
.width('100%')
.columnsGap(10)
.layoutWeight(1)
.padding({ top: 20 })
.backgroundColor('#e5e5e5')
.columnsTemplate('1fr 1fr 1fr 1fr')
}
.width('100%')
.height('100%')
.backgroundColor($r('app.color.theme_color'))
}
}
相关权限
不涉及。
依赖
不涉及。
约束与限制
1.本示例仅支持标准系统上运行,支持设备:纯血鸿蒙华为手机、模拟器。
2.HarmonyOS系统:HarmonyOS NEXT Developer。
3.DevEco Studio版本:DevEco Studio NEXT Developer。