1# 支持适老化 2<!--Kit: ArkUI--> 3<!--Subsystem: ArkUI--> 4<!--Owner: @liyi0309--> 5<!--Designer: @liyi0309--> 6<!--Tester: @fredyuan912--> 7<!--Adviser: @HelloCrease--> 8 9<!--RP1--> 10 11## 基本概念 12 13适老化提供了一种通过鼠标或手指长按的方法来放大所选区域或组件,即如果系统字体大小大于1倍,当用户使用鼠标或手指长按装配了适老化方法的组件,需要从所选区域的组件中提取数据,并放入另一个弹窗组件中展示。该方法的目的在于使组件和组件内部数据(子组件)放大,同时将整体组件在屏幕中央显示,让用户能够更好的观察该组件。 14 15## 使用约束 16 17* 适老化规则 18 19 由于在系统字体大于1倍时,组件并没有默认放大,需要通过配置[configuration标签](../quick-start/app-configuration-file.md#configuration标签),实现组件放大的适老化功能。 20 21* 适老化操作 22 23 在已经支持适老化能力的组件上长按组件,能够触发弹窗,当用户释放时,适老化操作结束。当设置系统字体大于1倍时,组件自动放大,当系统字体恢复至1倍时组件恢复正常状态。 24 25* 适老化对象 26 27 触发适老化操作并提供数据的组件。 28 29* 适老化弹窗目标 30 31 可接收并处理适老化数据的组件。 32 33* 弹窗限制 34 35 当用户将系统字体设置为2倍以上时,弹窗内容包括icon和文字的放大倍数固定为2倍。 36 37* 联合其他能力 38 39 适老化能力可以适配其他能力(如:滑动拖拽)。底部页签(tabBar)组件在触发适老化时,如果用户滑动手指或鼠标可以触发底部页签其他子组件的适老化功能。 40 41## 适配适老化的组件及触发方式 42 43| 触发方式 | 组件名称 | 44| -------------------- | ------------------------------------------------------------ | 45| 长按组件触发 | [SideBarContainer](../reference/apis-arkui/arkui-ts/ts-container-sidebarcontainer.md), [底部页签(tabBar)](../reference/apis-arkui/arkui-ts/ts-container-tabcontent.md#tabbar9),[Navigation](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md),[NavDestination](../reference/apis-arkui/arkui-ts/ts-basic-components-navdestination.md), [Tabs](../reference/apis-arkui/arkui-ts/ts-container-tabs.md) | 46| 设置系统字体默认放大 | [PickerDialog](arkts-fixes-style-dialog.md#选择器弹窗-pickerdialog), [Button](../reference/apis-arkui/arkui-ts/ts-basic-components-button.md), [Menu](../reference/apis-arkui/arkui-ts/ts-basic-components-menu.md), [Stepper](../reference/apis-arkui/arkui-ts/ts-basic-components-stepper.md), [BindSheet](../reference/apis-arkui/arkui-ts/ts-universal-attributes-sheet-transition.md#bindsheet),[TextInput](../reference/apis-arkui/arkui-ts/ts-basic-components-textinput.md),[TextArea](../reference/apis-arkui/arkui-ts/ts-basic-components-textarea.md),[Search](../reference/apis-arkui/arkui-ts/ts-basic-components-search.md),[SelectionMenu](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-SelectionMenu.md),[Chip](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-Chip.md#chip),[Dialog](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-Dialog.md),[Slider](../reference/apis-arkui/arkui-ts/ts-basic-components-slider.md), [Progress](../reference/apis-arkui/arkui-ts/ts-basic-components-progress.md), [Badge](../reference/apis-arkui/arkui-ts/ts-container-badge.md) | 47 48## 示例 49 50SideBarContainer组件通过长按控制按钮触发适老化弹窗。在系统字体为1倍的情况下,长按控制按钮不能弹窗。在系统字体大于1倍的情况下,长按控制按钮可以弹窗。 51 52```ts 53import { abilityManager, Configuration } from '@kit.AbilityKit'; 54import { BusinessError } from '@kit.BasicServicesKit'; 55 56@Entry 57@Component 58struct SideBarContainerExample { 59 @State currentFontSizeScale: number = 1 60 normalIcon: Resource = $r("app.media.icon") // icon仅作示例,请替换为实际使用的图片。 61 selectedIcon: Resource = $r("app.media.icon") // icon仅作示例,请替换为实际使用的图片。 62 @State arr: number[] = [1, 2, 3] 63 @State current: number = 1 64 @State title: string = 'Index01'; 65 // 设置字体大小 66 async setFontScale(scale: number): Promise<void> { 67 let configInit: Configuration = { 68 language: 'zh-Ch', 69 fontSizeScale: scale, 70 }; 71 // 更新配置-字体大小 72 abilityManager.updateConfiguration(configInit, (err: BusinessError) => { 73 if (err) { 74 console.error(`updateConfiguration fail, err: ${JSON.stringify(err)}`); 75 } else { 76 this.currentFontSizeScale = scale; 77 console.log('updateConfiguration success.'); 78 } 79 }); 80 } 81 82 build() { 83 SideBarContainer(SideBarContainerType.Embed) { 84 Column() { 85 ForEach(this.arr, (item: number) => { 86 Column({ space: 5 }) { 87 Image(this.current === item ? this.selectedIcon : this.normalIcon).width(64).height(64) 88 Text("0" + item) 89 .fontSize(25) 90 .fontColor(this.current === item ? '#0A59F7' : '#999') 91 .fontFamily('source-sans-pro,cursive,sans-serif') 92 } 93 .onClick(() => { 94 this.current = item; 95 this.title = "Index0" + item; 96 }) 97 }, (item: string) => item) 98 }.width('100%') 99 .justifyContent(FlexAlign.SpaceEvenly) 100 .backgroundColor($r('sys.color.mask_fifth')) 101 102 Column() { 103 Text(this.title) 104 Button('1倍').onClick(() => { 105 this.setFontScale(1) 106 }).margin(10) 107 Button('1.75倍').onClick(() => { 108 this.setFontScale(1.75) 109 }).margin(10) 110 Button('2倍').onClick(() => { 111 this.setFontScale(2) 112 }).margin(10) 113 Button('3.2倍').onClick(() => { 114 this.setFontScale(3.2) 115 }).margin(10) 116 } 117 .margin({ top: 50, left: 20, right: 30 }) 118 } 119 .controlButton({ 120 icons: { 121 hidden: $r('sys.media.ohos_ic_public_drawer_open_filled'), 122 shown: $r('sys.media.ohos_ic_public_drawer_close') 123 } 124 }) 125 .sideBarWidth(150) 126 .minSideBarWidth(50) 127 .maxSideBarWidth(300) 128 .minContentWidth(0) 129 .onChange((value: boolean) => { 130 console.info('status:' + value) 131 }) 132 .divider({ strokeWidth: '1vp', color: Color.Gray, startMargin: '4vp', endMargin: '4vp' }) 133 } 134} 135``` 136 137切换系统字体前后长按已经支持适老化能力的组件,有如下效果: 138 139| 系统字体为一倍(适老化能力开启前) | 系统字体为1.75倍(适老化能力开启后) | 140| ---------------------------------- | ------------------------------------ | 141|  |  | 142 143[TextPickerDialog](../reference/apis-arkui/arkui-ts/ts-methods-textpicker-dialog.md)组件通过设置系统字体大小触发适老化弹窗。在系统字体为1倍的情况下,适老化不触发;在系统字体大于1倍的情况下,适老化触发。 144 145```ts 146import { abilityManager, Configuration } from '@kit.AbilityKit'; 147import { BusinessError } from '@kit.BasicServicesKit'; 148 149@Entry 150@Component 151struct TextPickerExample { 152 private select: number | number[] = 0; 153 private cascade: TextCascadePickerRangeContent[] = [ 154 { 155 text: '辽宁省', 156 children: [{ text: '沈阳市', children: [{ text: '沈河区' }, { text: '和平区' }, { text: '浑南区' }] }, 157 { text: '大连市', children: [{ text: '中山区' }, { text: '金州区' }, { text: '长海县' }] }] 158 }, 159 { 160 text: '吉林省', 161 children: [{ text: '长春市', children: [{ text: '南关区' }, { text: '宽城区' }, { text: '朝阳区' }] }, 162 { text: '四平市', children: [{ text: '铁西区' }, { text: '铁东区' }, { text: '梨树县' }] }] 163 }, 164 { 165 text: '黑龙江省', 166 children: [{ text: '哈尔滨市', children: [{ text: '道里区' }, { text: '道外区' }, { text: '南岗区' }] }, 167 { text: '牡丹江市', children: [{ text: '东安区' }, { text: '西安区' }, { text: '爱民区' }] }] 168 } 169 ] 170 @State v: string = ''; 171 @State showTriggered: string = ''; 172 private triggered: string = ''; 173 private maxLines: number = 3; 174 // 设置字体大小 175 async setFontScale(scale: number): Promise<void> { 176 let configInit: Configuration = { 177 fontSizeScale: scale, 178 }; 179 180 abilityManager.updateConfiguration(configInit, (err: BusinessError) => { 181 if (err) { 182 console.error(`updateConfiguration fail, err: ${JSON.stringify(err)}`); 183 } else { 184 console.log('updateConfiguration success.'); 185 } 186 }); 187 } 188 189 linesNum(max: number): void { 190 let items: string[] = this.triggered.split('\n').filter(item => item != ''); 191 if (items.length > max) { 192 this.showTriggered = items.slice(-this.maxLines).join('\n'); 193 } else { 194 this.showTriggered = this.triggered; 195 } 196 } 197 198 build() { 199 Column() { 200 Button("TextPickerDialog.show:" + this.v) 201 .onClick(() => { 202 this.getUIContext().showTextPickerDialog({ 203 range: this.cascade, 204 selected: this.select, 205 onAccept: (value: TextPickerResult) => { 206 this.select = value.index 207 console.log(this.select + '') 208 this.v = value.value as string 209 console.info("TextPickerDialog:onAccept()" + JSON.stringify(value)) 210 if (this.triggered != '') { 211 this.triggered += `\nonAccept(${JSON.stringify(value)})`; 212 } else { 213 this.triggered = `onAccept(${JSON.stringify(value)})`; 214 } 215 this.linesNum(this.maxLines); 216 }, 217 onCancel: () => { 218 console.info("TextPickerDialog:onCancel()") 219 if (this.triggered != '') { 220 this.triggered += `\nonCancel()`; 221 } else { 222 this.triggered = `onCancel()`; 223 } 224 this.linesNum(this.maxLines); 225 }, 226 onChange: (value: TextPickerResult) => { 227 console.info("TextPickerDialog:onChange()" + JSON.stringify(value)) 228 if (this.triggered != '') { 229 this.triggered += `\nonChange(${JSON.stringify(value)})`; 230 } else { 231 this.triggered = `onChange(${JSON.stringify(value)})`; 232 } 233 this.linesNum(this.maxLines); 234 }, 235 }) 236 }) 237 .margin({ top: 60 }) 238 239 Row() { 240 Button('1倍').onClick(() => { 241 this.setFontScale(1) 242 }).margin(10) 243 Button('1.75倍').onClick(() => { 244 this.setFontScale(1.75) 245 }).margin(10) 246 247 Button('2倍').onClick(() => { 248 this.setFontScale(2) 249 }).margin(10) 250 Button('3.2倍').onClick(() => { 251 this.setFontScale(3.2) 252 }).margin(10) 253 }.margin({ top: 50 }) 254 } 255 256 } 257} 258``` 259 260| 系统字体为一倍(适老化能力开启前) | 系统字体为1.75倍(适老化能力开启后) | 261| ---------------------------------- | ------------------------------------ | 262|  |  | 263<!--RP1End-->