智能客服
你问我答,随时在线为你解决问题
在应用开发中,字体是用户界面的核心视觉元素之一,也是构建良好用户体验的关键要素之一,直接影响应用界面的美观性、可读性和用户体验。
ArkUI提供了全面的字体控制能力,如自定义设置字体大小和字重;支持通过registerFont()方法注册TTF和OTF自定义字体文件,或下载字体文件到沙箱内注册使用,实现字体的动态切换;支持省略号、自动缩放和换行控制等多种文本内容溢出处理策略,使开发者能够精细调整应用中的字体表现,满足应用多样化的设计需求。
本文将介绍以下字体设置场景的实现:
场景描述
在字体设置中,点击选择字体列表中的某个字体后,页面的字体样式会发生变化。在退出应用重新进入后,默认显示退出前选择的字体样式。

实现原理
registerFont()方法可以在字体管理器中注册自定义字体,支持注册TTF格式和OTF格式的字体文件。
preferences (用户首选项)则为应用提供了处理Key-Value键值型数据的能力,支持应用持久化轻量级数据,以及数据的修改和查询。
开发步骤
export class PreferenceUtils {
preference?: preferences.Preferences;
// Get Preferences instance
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 failed. code: ${error.code}, message:${err.message}`);
}
}
// ...
// Save Font
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 failed. code: ${error.code}, message:${err.message}`);
}
}
// Get Font
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 failed. code: ${error.code}, message:${err.message}`);
}
return textFont;
}
}
export default new PreferenceUtils();export default class EntryAbility extends UIAbility {
onCreate(_want: Want, _launchParam: AbilityConstant.LaunchParam): void {
// Get preference instance
PreferenceUtils.getTextFontPreference(this.context);
// ...
}
// ...
}在使用时,需要通过UIContext中的getFont()方法获取当前UI上下文关联的Font对象,再通过该对象调用registerFont()方法注册字体。
// Register font
export function registerMyFont(uiContext: UIContext) {
try {
// Register HarmonyOS Italic font through registrant Font
uiContext.getFont().registerFont({
familyName: $r('app.string.HarmonyOS_Italic'),
familySrc: $rawfile('HarmonyOS_SansItalic.ttf')
});
// Register HarmonyOS Condensed font through registrant Font
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 failed. code: ${error.code}, message:${err.message}`);
}
}@StorageLink('fontOffset') fontOffset: string = '';
// ...
aboutToAppear() {
// ...
// Get font data from preferences
this.fontOffset = PreferenceUtils.getFont();
// Register font
registerMyFont(this.getUIContext());
}MenuItem({
content: item === '' ? $r('app.string.system_default') : item,
endIcon: this.fontOffset === item ? $r('app.media.checkmark') : ''
})
.onChange(() => {
this.fontOffset = item;
PreferenceUtils.saveModifyFont(item);
})// Example Text Content
Column() {
Text($r('app.string.preview_text'))
// ...
.fontFamily(this.fontOffset)
}
.width('100%')
.padding(12)
.margin({ top: 35 })
.backgroundColor('#FFF')
.borderRadius(16)场景描述
在应用设置页面的字体设置中,点击选择系统默认字体,首页和设置页顶部的字体样式变为系统默认。退出并重新进入应用后,仍会显示系统默认字体。

实现原理
系统默认字体为无衬线字体HarmonyOS Sans,当fontFamily属性被显式设置为空字符串时,实际生效字体与不设置fontFamily时的效果一致,会回退到默认字体,字体样式、字重等其它属性可正常应用。
开发步骤
Menu() {
ForEach(this.menuItemArr, (item: string) => {
MenuItem({
content: item === '' ? $r('app.string.system_default') : item,
endIcon: this.fontOffset === item ? $r('app.media.checkmark') : ''
})
.onChange(() => {
this.fontOffset = item;
PreferenceUtils.saveModifyFont(item);
})
}, (item: string) => item)
}
// ...Text($r('app.string.preview_text'))
// ...
.fontFamily(this.fontOffset)场景描述
在设置页面中,点击打开Toggle按钮,使页面字体大小跟随系统设置发生变化。此时,自定义字体大小和字重的Slider将被禁用,无法滑动或点击。

实现原理
在应用的app.json5配置文件中,configuration标签是用于标识应用字体大小跟随系统变更的配置文件。当configuration的fontSizeScale属性取值为followSystem,且字体大小fontSize属性使用fp为像素单位时,在改变系统设置中的字体大小缩放比例后,应用中的字体也会相应变化。
开发步骤
fontSizeScale属性取值(默认为nonFollowSystem不跟随系统):
{
"configuration": {
"fontSizeScale": "followSystem",
"fontSizeMaxScale": "2"
}
} {
"app": {
"bundleName": "com.example.textdisplayfont",
"vendor": "example",
"versionCode": 1000000,
"versionName": "1.0.0",
"icon": "$media:layered_image",
"label": "$string:app_name",
"configuration": "$profile:configuration"
}
}Toggle({ type: ToggleType.Switch, isOn: this.toggleState })
.onChange((isOn: boolean) => {
this.toggleState = isOn;
})当toggleState为true时,表示跟随系统,Slider不可点击或滑动;为false时,表示不跟随系统,Slider可以点击或滑动。
Slider({
min: -4,
max: 4,
value: this.fontSizeOffset,
style: SliderStyle.InSet
})
.width('90%')
.margin({ top: 12 })
.enabled(!this.toggleState)场景描述
在设置页中点击关闭Toggle按钮,通过Slider组件可以调整页面字体大小。在系统设置中调整字体大小,页面字体不会发生变化。

实现原理
在应用的app.json5配置文件中,通过configuration标签标识了应用字体跟随系统设置,当字体大小fontSize属性使用屏幕物理像素单位px时,页面字体大小将不再受系统设置的影响。
开发步骤
// Convert fp to px
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 failed. code: ${error.code}, message:${err.message}`);
}
return pxVal + pxStr;
}Text($r('app.string.setting'))
.width('100%')
.fontWeight(700)
.fontSize(this.toggleState ? 26 : fp2pxUtil(26))// System environment change information
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();
// Register to monitor changes in the system environment
callbackId = appContext.on('environment', envCallback);