Harmonyos之字体设置功能
概述
字体大小适配是我们app在适配过程中比较常用的一个适配项, 这里我们学习下在鸿蒙项目适配中是如何实现 ,自定义字体显示文本、自定义字体恢复为系统字体、字体大小跟随系统设置、字体大小不跟随系统设置等功能。
PreferenceUtils(工具类)
const TAG = 'PreferenceUtils';
const TEXT_FONT_SIZE = 'textFontSize';
const TEXT_FONT_WEIGHT = 'textFontWeight';
const TEXT_FONT = 'textFont';
export class PreferenceUtils {
preference?: preferences.Preferences;
// 创建PreferenceUtils实例
getTextFontPreference(context: Context) {
try {
this.preference = preferences.getPreferencesSync(context, { name: 'TextFontPreference' });
hilog.info(0x0000, TAG, 'create preference success');
} catch (err) {
let error = err as BusinessError;
hilog.error(0x0000, TAG, `create preference faile. code: ${error.code}, message:${err.message}`);
}
}
// 保存修改的字体大小
saveModifyFontSize(fontValue: number) {
try {
this.preference?.putSync(TEXT_FONT_SIZE, fontValue);
this.preference?.flush((err: BusinessError) => {
if (err) {
hilog.error(0x0000, TAG, `Failed to flush. code:${err.code}, message:${err.message}`);
return;
}
})
} catch (err) {
let error = err as BusinessError;
hilog.error(0x0000, TAG,
`putSync or flush fontSize preference data faile. code: ${error.code}, message:${err.message}`);
}
}
// 获取当前缓存的字体大小
getFontSize(): number {
let textFontSize: number = 0;
try {
textFontSize = this.preference?.getSync(TEXT_FONT_SIZE, 0) as number;
} catch (err) {
let error = err as BusinessError;
hilog.error(0x0000, TAG, `getSync fontSize preference data faile. code: ${error.code}, message:${err.message}`);
}
return textFontSize;
}
// 保存修改的字体粗细
saveModifyFontWeight(fontValue: number) {
try {
this.preference?.putSync(TEXT_FONT_WEIGHT, fontValue);
this.preference?.flush((err: BusinessError) => {
if (err) {
hilog.error(0x0000, TAG, `Failed to flush. code:${err.code}, message:${err.message}`);
return;
}
hilog.info(0x0000, TAG, 'Succeeded in flushing.');
})
} catch (err) {
let error = err as BusinessError;
hilog.error(0x0000, TAG,
`putSync or flush fontWeight preference data faile. code: ${error.code}, message:${err.message}`);
}
}
// 获取当前缓存的字体粗细
getFontWeight(): number {
let textFontWeight: number = 0;
try {
textFontWeight = this.preference?.getSync(TEXT_FONT_WEIGHT, 400) as number;
} catch (err) {
let error = err as BusinessError;
hilog.error(0x0000, TAG, `getSync fontWeight preference data faile. code: ${error.code}, message:${err.message}`);
}
return textFontWeight;
}
// [EndExclude GetFont]
// 保存 修改的字体
saveModifyFont(textFont: string) {
try {
this.preference?.putSync(TEXT_FONT, textFont);
this.preference?.flush((err: BusinessError) => {
if (err) {
hilog.error(0x0000, TAG, `Failed to flush. code:${err.code}, message:${err.message}`);
return;
}
hilog.info(0x0000, TAG, 'Succeeded in flushing.');
})
} catch (err) {
let error = err as BusinessError;
hilog.error(0x0000, TAG,
`putSync or flush font preference data faile. code: ${error.code}, message:${err.message}`);
}
}
// 获取当前使用的字体
getFont(): string {
let textFont: string = '';
try {
textFont = this.preference?.getSync(TEXT_FONT, '') as string;
} catch (err) {
let error = err as BusinessError;
hilog.error(0x0000, TAG, `getSync font preference data faile. code: ${error.code}, message:${err.message}`);
}
return textFont;
}
}
export default new PreferenceUtils();
字体适配步骤
监听系统环境变量改变
API: ApplicationContext.on('environment')
监听系统环境变量
首先我们在EntryAbility
中的onCreate
方法中,需要如下操作
// 字体对象类型
export interface FontType {
fontSizeScale: number | undefined,
fontWeightScale: number | undefined
}
// 字体对象
let envFont: FontType = {
fontSizeScale: 0,
fontWeightScale: 0,
};
onCreate(_want: Want, _launchParam: AbilityConstant.LaunchParam): void {
// 获取字体缓存对象
PreferenceUtils.getTextFontPreference(this.context);
// 创建一个监听系统环境变量变化的回调,获取系统字体大小和字体粗细的初始化大小
let envCallback: EnvironmentCallback = {
onConfigurationUpdated(config) {
// 字体大小
envFont.fontSizeScale = config.fontSizeScale; // Font size scaling ratio
// 字体粗细
envFont.fontWeightScale = config.fontWeightScale; // Font thickness scaling ratio
},
onMemoryLevel(level) {
hilog.info(DOMAIN, TAG, `onMemoryLevel level: ${level}`);
}
}
// 获取应用级别的上下文对象
let appContext = this.context.getApplicationContext();
.// 注册对系统环境变化的监听。使用callback异步回调。仅支持主线程调用
callbackId = appContext.on('environment', envCallback);
// 创建一个全局缓存对象, 字体对象
AppStorage.setOrCreate('envFont', envFont);
// 设置应用的深浅模式
this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
}
在EntryAbility销毁时, 需要注销监听:
onDestroy(): void {
let appContext = this.context.getApplicationContext();
appContext.off(‘environment’, callbackId, (error, data) => {
if (error) {
hilog.error(DOMAIN, TAG, unregisterEnvironmentCallback fail, err: ${JSON.stringify(error)}
);
}
hilog.info(DOMAIN, TAG, unregisterEnvironmentCallback success, data: ${JSON.stringify(data)}
);
});
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy');
}
设置页功能
初始化
('fontOffset') fontOffset: string = '';
aboutToAppear() {
// 获取全局缓存的字体对象
this.envFont = AppStorage.get('envFont');
// 获取当前使用的字体
this.fontOffset = PreferenceUtils.getFont();
// 注册自定义的字体
registerMyFont(this.getUIContext());
}
// 创建一个全局函数来注册自定义的字体
export function registerMyFont(uiContext: UIContext) {
try {
// 注册自定义的字体
uiContext.getFont().registerFont({
familyName: $r('app.string.HarmonyOS_Italic'),
familySrc: $rawfile('HarmonyOS_SansItalic.ttf')
});
// 注册自定义的字体
uiContext.getFont().registerFont({
familyName: $r('app.string.HarmonyOS_Condensed'),
familySrc: $rawfile('HarmonyOS_Condensed.ttf')
});
} catch (err) {
let error = err as BusinessError;
hilog.error(0x0000, TAG, `registerFont faile. code: ${error.code}, message:${err.message}`);
}
}
字体大小跟随系统
export function fp2pxUtil(fp: number): string {
const pxStr: string = 'px';
let pxVal: number = 0;
let displayClass: display.Display | null = null;
try {
displayClass = display.getDefaultDisplaySync();
pxVal = fp * (displayClass.densityDPI / 160);
} catch (err) {
let error = err as BusinessError;
hilog.error(0x0000, TAG, `get densityDPI faile. code: ${error.code}, message:${err.message}`);
}
return pxVal + pxStr;
}
//使用地方:
.font({ size: this.toggleState ? 14 : fp2pxUtil(14), weight: 500 })
修改字体大小
调用工具类方法缓存设置的字体大小、字体粗细、字体等信息, 然后通过StorageLink
来设置其他页面变化
('fontOffset') fontOffset: string = '';
('toggleState') toggleState: boolean = false;
('fontSizeOffset') fontSizeOffset: number = 0;
('fontWeightOffset') fontWeightOffset: number = 400;
// 字体大小
Slider({
min: -4,
max: 4,
value: this.fontSizeOffset,
style: SliderStyle.InSet
})
.width('90%')
.margin({ top: 12 })
.enabled(!this.toggleState)
// [Start Write_FontSize_Data]
.onChange((data: number) => {
this.fontSizeOffset = data;
PreferenceUtils.saveModifyFontSize(data);
})
// 字体粗细
Slider({
min: 100,
max: 900,
step: 100,
value: this.fontWeightOffset,
style: SliderStyle.InSet
})
.width('100%')
.stepSize(5)
.showSteps(true)
.margin({ top: 12 })
.enabled(!this.toggleState)
.onChange((data: number) => {
this.fontWeightOffset = data;
PreferenceUtils.saveModifyFontWeight(data);
})
像字体适配、颜色适配,其实我们可以封装一个主题对应, 统一通过这个主题对象来修改变化