HarmonyOS官网案例解析——保存应用数据

介绍

本篇Codelab将介绍如何使用基础组件Slider,通过拖动滑块调节应用内字体大小。要求完成以下功能:

  1. 实现两个页面的UX:主页面和字体大小调节页面。
  2. 拖动滑块改变字体大小系数,列表页和调节页面字体大小同步变化。往右拖动滑块字体变大,反之变小。
  3. 字体大小支持持久化存储,再次启动时,应用内字体仍是调节后的字体大小。

最终效果图如图所示:

https://gitee.com/runitwolf/sloop-pic-go/raw/master/image/202312212240377.gif

一、相关概念

  • 字体大小调节原理:通过组件Slider滑动,获取滑动数值,将这个值通过首选项进行持久化,页面的字体通过这个值去改变大小。
  • 首选项:首选项为应用提供Key-Value键值型的数据处理能力,支持应用持久化轻量级数据,并对其修改和查询。

二、完整实例

gitee源码地址

ps:官网的案例很简单,但是有很多地方值得我们借鉴。

官方对案例解析

<HarmonyOS第一课>保存应用数据

三、零基础实战开发

一、用数组的方法值得借鉴

  1. 现新建一个bean类
export default class SettingData{settingName:stringsettingImage:Resource
}
  1. 新建HomeViewModel.etx
import SettingData from './SettingData'export class HomeViewModel {settingArr: SettingData[] = []initSettingData(): SettingData[] {if (this.settingArr.length === 0) {let settingData = new SettingData()settingData.settingName = '显示和亮度'settingData.settingImage = $r('app.media.ic_display_and_brightness')this.settingArr.push(settingData)settingData = new SettingData();settingData.settingName = '声音';settingData.settingImage = $r('app.media.ic_voice');this.settingArr.push(settingData);settingData = new SettingData();settingData.settingName = '应用管理';settingData.settingImage = $r('app.media.ic_app_management');this.settingArr.push(settingData);settingData = new SettingData();settingData.settingName = '存储';settingData.settingImage = $r('app.media.ic_storage');this.settingArr.push(settingData);settingData = new SettingData();settingData.settingName = '隐私';settingData.settingImage = $r('app.media.ic_privacy');this.settingArr.push(settingData);settingData = new SettingData();settingData.settingName = '设置字体大小';settingData.settingImage = $r('app.media.ic_setting_the_font_size');this.settingArr.push(settingData);}return this.settingArr}
}
export default new HomeViewModel()

在index.ets中直接使用即可使用方法如下

 settingArr = HomeViewModel.initSettingData();//settingArr[x],x为数组的索引,直接使用就可以获取设定的数据

1."标题"页面实现

import { TitleBarComponent } from '../view/TitleBarComponent'@Entry
@Component
struct Index {build() {Column() {TitleBarComponent({ isBack: false, title: '设置' })}.width('100%').height('100%')}
}
import router from '@ohos.router'
@Component
export struct TitleBarComponent {isBack:boolean = truetitle:string = ''build() {Row() {if (this.isBack){Image($r('app.media.ic_public_back')).width(24).height(24).margin({ right: 4 }).onClick(() => {router.back()})}Text(this.title).fontColor(Color.Black).fontSize($r('sys.float.ohos_id_text_size_headline8')).fontWeight(FontWeight.Medium).margin({ left: 8 })}.width('100%').height('7.2%').padding({ left: 16 })}
}

在这里插入图片描述

2."显示和亮度"页面实现

import SettingItemComponent from '../view/SettingItemComponent'
import { TitleBarComponent } from '../view/TitleBarComponent'
import HomeViewModel from '../viewModel/HomeViewModel'
import SettingData from '../viewModel/SettingData'@Entry
@Component
struct Index {settingArr: SettingData[] = HomeViewModel.initSettingData()@State changeFontSize: number = 16build() {Column() {...//显示和亮度Row() {SettingItemComponent({setting: this.settingArr[0],changeFontSize: this.changeFontSize,itemClick: () => {//TODO}})}.blockBackground('1.5%')}.backgroundColor('#f1f3f5').width('100%').height('100%')}
}@Extend(Row) function blockBackground (marginTop: string) {.backgroundColor(Color.White).borderRadius(24).margin({ top: marginTop }).width('93.3%').padding({ top: 4, bottom: 4 })
}

思考题:这里的changeFontSize变量为什么需要用@State进行修饰,而settingArr又为什么不需要?

3."声音"页面实现

import SettingItemComponent from '../view/SettingItemComponent'
import { TitleBarComponent } from '../view/TitleBarComponent'
import HomeViewModel from '../viewModel/HomeViewModel'
import SettingData from '../viewModel/SettingData'@Entry
@Component
struct Index {build() {Column() {TitleBarComponent({ isBack: false, title: '设置' })...//声音Row() {SettingItemComponent({setting: this.settingArr[1],changeFontSize: this.changeFontSize,itemClick: () => {//TODO}})}.blockBackground('1.5%')}.backgroundColor('#f1f3f5').width('100%').height('100%')}
}

4.“应用管理”、"存储"等列表页面实现

import SettingItemComponent from '../view/SettingItemComponent'
import { TitleBarComponent } from '../view/TitleBarComponent'
import HomeViewModel from '../viewModel/HomeViewModel'
import SettingData from '../viewModel/SettingData'@Entry
@Component
struct Index {settingArr: SettingData[] = HomeViewModel.initSettingData()@State changeFontSize: number = 16build() {Column() {...Row(){this.SettingItems()}.blockBackground('1.5%')}...}@Builder SettingItems(){List(){ForEach(this.settingArr.splice(2,6),(item:SettingData,index:number)=>{ListItem(){SettingItemComponent({setting:item,changeFontSize:this.changeFontSize,itemClick:()=>{//TODO}})}}, (item:SettingData,index:number)=>JSON.stringify(item)+index)}}
}

5."设置字体大小"点击事件跳转

import router from '@ohos.router'
import PreferencesUtil from '../common/database/PreferencesUtil'
import SettingItemComponent from '../view/SettingItemComponent'
import { TitleBarComponent } from '../view/TitleBarComponent'
import HomeViewModel from '../viewModel/HomeViewModel'
import SettingData from '../viewModel/SettingData'@Entry
@Component
struct Index {settingArr: SettingData[] = HomeViewModel.initSettingData()@State changeFontSize: number = 16onPageShow(){PreferencesUtil.getChangeFontSize().then((value)=>{this.changeFontSize = value})}build() {....@Builder SettingItems(){List(){ForEach(this.settingArr.splice(2,6),(item:SettingData,index:number)=>{ListItem(){SettingItemComponent({setting:item,changeFontSize:this.changeFontSize,itemClick:()=>{if (index === 3) {router.pushUrl({url:"pages/SetFontSizePage"})}}})}}, (item:SettingData,index:number)=>JSON.stringify(item)+index)}}
}

在pages目录下新建SetFontSizePage子组件

import  PreferencesUtil  from '../common/database/PreferencesUtil'
import { ItemComponent } from '../view/ItemComponent'
import { SliderLayout } from '../view/SliderLayout'
import { TitleBarComponent } from '../view/TitleBarComponent'
import HomeViewModel from '../viewModel/HomeViewModel'
import SettingData from '../viewModel/SettingData'@Entry
@Component
struct SetFontSizePage {build() {Column() {TitleBarComponent({ title: '字体大小设置' })}.width('100%').height('100%')}
}

ps:官网的案例不太友好,我们在官网的页面基础上进行功能及界面简化

6.SetFontSizePage页面创建数据

我们之前在首页HomeViewModel模型下创建过数据,我们沿用HomeViewModel模型,继续创建想要的数据

import SettingData from './SettingData'export class HomeViewModel {...fontSizeArr: SettingData[] = []...initFontSizeData():SettingData[]{this.fontSizeArr = new Array();let fontSizeArr = new SettingData()fontSizeArr.settingName = '11111111111111111111'this.fontSizeArr.push(fontSizeArr)fontSizeArr = new SettingData()fontSizeArr.settingName = '22222222222222222222'this.fontSizeArr.push(fontSizeArr)fontSizeArr = new SettingData()fontSizeArr.settingName = '33333333333333333333'this.fontSizeArr.push(fontSizeArr)fontSizeArr = new SettingData()fontSizeArr.settingName = '44444444444444444444'this.fontSizeArr.push(fontSizeArr)return this.fontSizeArr}
}
export default new HomeViewModel()

7.写SetFontSizePage中list页面

import  PreferencesUtil  from '../common/database/PreferencesUtil'
import { ItemComponent } from '../view/ItemComponent'
import { SliderLayout } from '../view/SliderLayout'
import { TitleBarComponent } from '../view/TitleBarComponent'
import HomeViewModel from '../viewModel/HomeViewModel'
import SettingData from '../viewModel/SettingData'@Entry
@Component
struct SetFontSizePage {contentArr: SettingData[] = HomeViewModel.initFontSizeData()@State changeFontSize: number = 0onPageShow(){PreferencesUtil.getChangeFontSize().then((value)=>{this.changeFontSize = value})}build() {Column() {TitleBarComponent({ title: '字体大小设置' })List() {ForEach(this.contentArr, (item: SettingData, index: number) => {ListItem() {ItemComponent({ contentArr: item, changeFontSize: this.changeFontSize })}}, (item: SettingData, index: number) => JSON.stringify(item) + index)}}.width('100%').height('100%')}
}
import SettingData from '../viewmodel/SettingData'
@Component
export struct ItemComponent {contentArr: SettingData@Prop changeFontSize:numberbuild() {Column() {Text(this.contentArr.settingName).fontSize(this.changeFontSize).fontColor('#182431').fontWeight(FontWeight.Medium).height(48).width('100%').textAlign(TextAlign.Center)}}
}

看看list的效果图:

8.写SetFontSizePage进度条

import  PreferencesUtil  from '../common/database/PreferencesUtil'
import { ItemComponent } from '../view/ItemComponent'
import { SliderLayout } from '../view/SliderLayout'
import { TitleBarComponent } from '../view/TitleBarComponent'
import HomeViewModel from '../viewModel/HomeViewModel'
import SettingData from '../viewModel/SettingData'@Entry
@Component
struct SetFontSizePage {...build() {Column() {...List() {...}SliderLayout({changeFontSize:$changeFontSize})}...}
}
import PreferencesUtil from '../common/database/PreferencesUtil'
@Component
export struct SliderLayout {@Link changeFontSize:numberbuild() {Column() {Text('文字大小').fontSize(14).fontColor('#182431').fontWeight(FontWeight.Medium)Row(){Text('A').fontColor('#182431').fontSize(20).fontWeight(FontWeight.Medium).textAlign(TextAlign.End).width('12.5%').padding({right:9})Slider({value:this.changeFontSize,min:14,max:22,step:2,style:SliderStyle.InSet}).showSteps(true).width('75%').onChange((value:number)=>{this.changeFontSize = value})Text('A').fontColor('#182431').fontSize(20).fontWeight(FontWeight.Medium).width('12.5%').padding({left:9})}}}
}

运行后效果图如下:
在这里插入图片描述

至此,我们发现滑动进度条,页面的大小变了,但是返回页面后再次进入,数据没有保存。

四、保存应用数据

<HarmonyOS第一课>保存应用数据(官网文档)

根据官网的文档,我们新建PreferencesUtil工具类

import dataPreferences from '@ohos.data.preferences';
import { GlobalContext } from '../utils/GlobalContext';
import Logger from '../utils/Logger';const TAG = '[PreferencesUtil]';
const PREFERENCES_NAME = 'myPreferences';
const KEY_APP_FONT_SIZE = 'appFontSize';/*** The PreferencesUtil provides preferences of create, save and query.*/
export class PreferencesUtil {createFontPreferences(context: Context) {let fontPreferences: Function = (() => {let preferences: Promise<dataPreferences.Preferences> = dataPreferences.getPreferences(context, PREFERENCES_NAME);return preferences;});GlobalContext.getContext().setObject('getFontPreferences', fontPreferences);}saveDefaultFontSize(fontSize: number) {let getFontPreferences: Function = GlobalContext.getContext().getObject('getFontPreferences') as Function;getFontPreferences().then((preferences: dataPreferences.Preferences) => {preferences.has(KEY_APP_FONT_SIZE).then(async (isExist: boolean) => {Logger.info(TAG, 'preferences has changeFontSize is ' + isExist);if (!isExist) {await preferences.put(KEY_APP_FONT_SIZE, fontSize);preferences.flush();}}).catch((err: Error) => {Logger.error(TAG, 'Has the value failed with err: ' + err);});}).catch((err: Error) => {Logger.error(TAG, 'Get the preferences failed, err: ' + err);});}saveChangeFontSize(fontSize: number) {let getFontPreferences: Function = GlobalContext.getContext().getObject('getFontPreferences') as Function;getFontPreferences().then(async (preferences: dataPreferences.Preferences) => {await preferences.put(KEY_APP_FONT_SIZE, fontSize);preferences.flush();}).catch((err: Error) => {Logger.error(TAG, 'put the preferences failed, err: ' + err);});}async getChangeFontSize() {let fontSize: number = 0;let getFontPreferences: Function = GlobalContext.getContext().getObject('getFontPreferences') as Function;fontSize = await (await getFontPreferences()).get(KEY_APP_FONT_SIZE, fontSize);return fontSize;}async deleteChangeFontSize() {let getFontPreferences: Function = GlobalContext.getContext().getObject('getFontPreferences') as Function;const preferences: dataPreferences.Preferences = await getFontPreferences();let deleteValue = preferences.delete(KEY_APP_FONT_SIZE);deleteValue.then(() => {Logger.info(TAG, 'Succeeded in deleting the key appFontSize.');}).catch((err: Error) => {Logger.error(TAG, 'Failed to delete the key appFontSize. Cause: ' + err);});}
}export default new PreferencesUtil();
export class GlobalContext {private constructor() { }private static instance: GlobalContext;private _objects = new Map<string, Object>();public static getContext(): GlobalContext {if (!GlobalContext.instance) {GlobalContext.instance = new GlobalContext();}return GlobalContext.instance;}getObject(value: string): Object | undefined {return this._objects.get(value);}setObject(key: string, objectClass: Object): void {this._objects.set(key, objectClass);}
}

1.使用前提

需要在entryAbility的onCreate方法获取首选项实例

import UIAbility from '@ohos.app.ability.UIAbility';
import hilog from '@ohos.hilog';
import window from '@ohos.window';
import Logger from '../common/utils/Logger';
import { GlobalContext } from '../common/utils/GlobalContext';
import PreferencesUtil from '../common/database/PreferencesUtil'export default class EntryAbility extends UIAbility {onCreate(want, launchParam) {PreferencesUtil.createFontPreferences(this.context);}...
}

2.保存数据

在应用刚启动时,设置字体默认大小

import UIAbility from '@ohos.app.ability.UIAbility';
import hilog from '@ohos.hilog';
import window from '@ohos.window';
import Logger from '../common/utils/Logger';
import { GlobalContext } from '../common/utils/GlobalContext';
import PreferencesUtil from '../common/database/PreferencesUtil'export default class EntryAbility extends UIAbility {onCreate(want, launchParam) {...// 设置字体默认大小PreferencesUtil.saveDefaultFontSize(16);}...
}

在滑动进度条后,保存进度条设置的字体大小

import PreferencesUtil from '../common/database/PreferencesUtil'
@Component
export struct SliderLayout {@Link changeFontSize:numberbuild() {...Slider({....onChange((value:number)=>{this.changeFontSize = valuePreferencesUtil.saveChangeFontSize(this.changeFontSize)})...}}}
}

3.获取保存的数据

数据都保存了,我们怎么去使用保存的数据呢?

import  PreferencesUtil  from '../common/database/PreferencesUtil'
import { ItemComponent } from '../view/ItemComponent'
import { SliderLayout } from '../view/SliderLayout'
import { TitleBarComponent } from '../view/TitleBarComponent'
import HomeViewModel from '../viewModel/HomeViewModel'
import SettingData from '../viewModel/SettingData'@Entry
@Component
struct SetFontSizePage {...@State changeFontSize: number = 0onPageShow(){PreferencesUtil.getChangeFontSize().then((value)=>{this.changeFontSize = value})}}
import router from '@ohos.router'
import PreferencesUtil from '../common/database/PreferencesUtil'
import SettingItemComponent from '../view/SettingItemComponent'
import { TitleBarComponent } from '../view/TitleBarComponent'
import HomeViewModel from '../viewModel/HomeViewModel'
import SettingData from '../viewModel/SettingData'@Entry
@Component
struct Index {...@State changeFontSize: number = 16onPageShow(){PreferencesUtil.getChangeFontSize().then((value)=>{this.changeFontSize = value})}...
}
...

效果图:
在这里插入图片描述

至此,大功告成~~~撒花

至此,所有功能已全部完成。

代码链接:https://gitee.com/runitwolf/set-app-font-size

typora笔记链接:https://gitee.com/runitwolf/set-app-font-size/blob/master/%E5%BA%94%E7%94%A8%E5%86%85%E5%AD%97%E4%BD%93%E5%A4%A7%E5%B0%8F%E8%B0%83%E8%8A%82.md

CSDN typora笔记链接 :https://download.csdn.net/download/qq_36067302/88671288

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/315373.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue3+echarts可视化——记录我的2023编程之旅

文章目录 ⭐前言⭐2023我在csdn的旅途痕迹&#x1f496;node系列文章&#x1f496;vue3系列文章&#x1f496;python系列文章&#x1f496;react系列文章&#x1f496;js拖拽相关文章&#x1f496;小程序系列文章&#x1f496;uniapp系列文章 ⭐可视化布局&#x1f496; git 数…

Windows使用IIS服务搭建WebDAV站点结合内网穿透公网访问

文章目录 1. 安装IIS必要WebDav组件2. 客户端测试3. cpolar内网穿透3.1 打开Web-UI管理界面3.2 创建隧道3.3 查看在线隧道列表3.4 浏览器访问测试 4. 安装Raidrive客户端4.1 连接WebDav服务器4.2 连接成功4.2 连接成功总结&#xff1a; 自己用Windows Server搭建了家用NAS主机&…

FPGA项目(14)——基于FPGA的数字秒表设计

1.功能设计 设计内容及要求: 1.秒表最大计时范围为99分59. 99秒 2.6位数码管显示&#xff0c;分辨率为0.01秒 3.具有清零、启动计时、暂停及继续计时等功能 4.控制操作按键不超过二个。 2.设计思路 所采用的时钟为50M&#xff0c;先对时钟进行分频&#xff0c;得到100HZ频率…

FusionAccess配置Lite AD

1、Lite AD的安装及配置 Lite AD流程&#xff1a; &#xff08;1&#xff09;创建一个新的Windows 10&#xff0c;安装tools&#xff0c;再安装ITA组件&#xff08;安装Lite AD会自动安装VAG/VLB&#xff09; &#xff08;2&#xff09;创建一个新的Windows 10&#xff0c;安…

跑腿配送系统技术探析

概述 跑腿配送系统是一种基于现代科技的服务平台&#xff0c;通过智能化的技术手段&#xff0c;实现用户需求的快速响应和高效配送。本文将探讨该系统的核心技术原理&#xff0c;以及在实际开发中的一些代码示例。 技术原理 1. 用户请求与任务分配 跑腿配送系统的第一步是…

健康元有中国顶级BigPharma的样子

《多肽链》原创出品 作者&#xff5c;严睿 无需赘言&#xff0c;创新药已然是中国医药行业长周期运行的最强主脉。 在经历了一二级市场的资本寒冬和疫情扰动后&#xff0c;“冷调整”让中国创新药行业重归理性&#xff0c;市场环境也随着医疗改革影响的边际递减&#xff0c;…

大模型通向AGI,腾讯云携手业界专家探索创新应用新风向

引言 一年过去&#xff0c;ChatGPT 引发的 AGI 热潮丝毫未减。只是相对于最初推出时掀起的全民大模型热&#xff0c;如今关于该如何落地的讨论更多了起来。 随着算力、数据库、大数据等底层技术的发展&#xff0c;大模型的建设与在各个领域的应用正在加速推进&#xff0c;那么…

Afuzz:一款功能强大的自动化Web路径模糊测试工具

关于Afuzz Afuzz是一款功能强大的自动化Web路径模糊测试工具&#xff0c;该工具专为Web安全专家和漏洞奖励Hunter设计&#xff0c;可以帮助我们以自动化的形式扫描和收集目标Web应用程序中的页面、语言和相关统计分析等数据。 功能介绍 1、Afuzz可以通过自动化的形式检测目标…

Flutter 中使用 ICON

Flutter Icon URL &#xff1a; https://fonts.google.com/icons&#xff1a; 在Flutter中使用 Icon 步骤如下&#xff1a; 导入图标库 在Dart 文件中导入 material.dart 包&#xff0c;该包包含了 Flutter 的图标库。 import package:flutter/material.dart;使用图标组件 …

QT登录功能开发

登录功能 1选择无按钮的dialog 2登录函数 #include <QApplication> #include <QDialog> #include <QFormLayout> #include <QLineEdit> #include <QPushButton> #include <QMessageBox>class LoginDialog : public QDialog { public:Log…

反转链表、链表的中间结点、合并两个有序链表【LeetCode刷题日志】

一、反转链表 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 思路一&#xff1a;翻转单链表指针方向 这里解释一下三个指针的作用&#xff1a; n1&#xff1…

C#核心学习(面向对象)

目录 封装构造函数基本概念&#xff1a;写法&#xff1a;特殊写法注意&#xff1a; 析构函数基本语法 垃圾回收机制&#xff08;GC&#xff0c;Garbage Collector&#xff09;回收算法C# 中内存回收原理自动回收步骤注意 手动回收&#xff1a; 成员属性基本概念基本语法注意&am…