介绍
本篇Codelab将介绍如何使用基础组件Slider,通过拖动滑块调节应用内字体大小。要求完成以下功能:
- 实现两个页面的UX:主页面和字体大小调节页面。
- 拖动滑块改变字体大小系数,列表页和调节页面字体大小同步变化。往右拖动滑块字体变大,反之变小。
- 字体大小支持持久化存储,再次启动时,应用内字体仍是调节后的字体大小。
最终效果图如图所示:
gitee源码地址
ps:官网的案例很简单,但是有很多地方值得我们借鉴。
官方对案例解析
一、用数组的方法值得借鉴
export default class SettingData{
settingName:string
settingImage:Resource
}
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为数组的索引,直接使用就可以获取设定的数据
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 = true
title: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 })
}
}
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 = 16
build() {
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又为什么不需要?
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%')
}
}
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 = 16
build() {
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)
}
}
}
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 = 16
onPageShow(){
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:官网的案例不太友好,我们在官网的页面基础上进行功能及界面简化
我们之前在首页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()
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 = 0
onPageShow(){
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:number
build() {
Column() {
Text(this.contentArr.settingName)
.fontSize(this.changeFontSize)
.fontColor('#182431')
.fontWeight(FontWeight.Medium)
.height(48)
.width('100%')
.textAlign(TextAlign.Center)
}
}
}
看看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 {
...
build() {
Column() {
...
List() {
...
}
SliderLayout({changeFontSize:$changeFontSize})
}
...
}
}
import PreferencesUtil from '../common/database/PreferencesUtil'
@Component
export struct SliderLayout {
@Link changeFontSize:number
build() {
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})
}
}
}
}
运行后效果图如下:
至此,我们发现滑动进度条,页面的大小变了,但是返回页面后再次进入,数据没有保存。
根据官网的文档,我们新建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.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();
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);
}
}
需要在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);
}
...
}
在应用刚启动时,设置字体默认大小
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:number
build() {
...
Slider({
...
.onChange((value:number)=>{
this.changeFontSize = value
PreferencesUtil.saveChangeFontSize(this.changeFontSize)
})
...
}
}
}
}
数据都保存了,我们怎么去使用保存的数据呢?
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 = 0
onPageShow(){
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 = 16
onPageShow(){
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