介绍
本篇Codelab将介绍如何使用基础组件Slider,通过拖动滑块调节应用内字体大小。要求完成以下功能:
- 实现两个页面的UX:主页面和字体大小调节页面。
- 拖动滑块改变字体大小系数,列表页和调节页面字体大小同步变化。往右拖动滑块字体变大,反之变小。
- 字体大小支持持久化存储,再次启动时,应用内字体仍是调节后的字体大小。
最终效果图如图所示:
一、相关概念
- 字体大小调节原理:通过组件Slider滑动,获取滑动数值,将这个值通过首选项进行持久化,页面的字体通过这个值去改变大小。
- 首选项:首选项为应用提供Key-Value键值型的数据处理能力,支持应用持久化轻量级数据,并对其修改和查询。
二、完整实例
gitee源码地址
ps:官网的案例很简单,但是有很多地方值得我们借鉴。
官方对案例解析
<HarmonyOS第一课>保存应用数据
三、零基础实战开发
一、用数组的方法值得借鉴
- 现新建一个bean类
export default class SettingData{settingName:stringsettingImage:Resource
}
- 新建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