1e41f4b71Sopenharmony_ci# Supporting Aging-Friendly Design
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci## Basic Concepts
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ciAging-friendly design offers a method to enlarge selected areas or components through a long-press action with a mouse or finger. Specifically, when the system font is larger than 1x, this action on a component with aging-friendly features extracts data from the component within the selected area and presents it in a dialog box. This way, both the component and its internal data (child components) are enlarged, and the entire component is centered on the screen for better visibility.
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ci## Constraints
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ci* Aging-friendly rules
10e41f4b71Sopenharmony_ci
11e41f4b71Sopenharmony_ci  Since components do not automatically enlarge when the system font size is greater than 1x, the aging-friendly feature is necessary to magnify the components.
12e41f4b71Sopenharmony_ci
13e41f4b71Sopenharmony_ci* Aging-friendly operations
14e41f4b71Sopenharmony_ci
15e41f4b71Sopenharmony_ci  Long-pressing a component that supports aging-friendly capabilities triggers a dialog box. The aging-friendly operation ends when the user releases the press. When the system font size is set to be greater than 1x, the component automatically enlarges, and when the system font size returns to 1x, the component returns to its normal state.
16e41f4b71Sopenharmony_ci
17e41f4b71Sopenharmony_ci* Aging-friendly objects
18e41f4b71Sopenharmony_ci
19e41f4b71Sopenharmony_ci  The components that trigger the aging-friendly operation and provide the data.
20e41f4b71Sopenharmony_ci
21e41f4b71Sopenharmony_ci* Aging-friendly dialog box targets
22e41f4b71Sopenharmony_ci
23e41f4b71Sopenharmony_ci  The components capable of receiving and processing the aging-friendly data.
24e41f4b71Sopenharmony_ci
25e41f4b71Sopenharmony_ci* Dialog box restrictions
26e41f4b71Sopenharmony_ci
27e41f4b71Sopenharmony_ci  When users set the system font to more than 2x, the dialog box content, including icons and text, is magnified at a fixed 2x scale.
28e41f4b71Sopenharmony_ci
29e41f4b71Sopenharmony_ci* Combination with other capabilities
30e41f4b71Sopenharmony_ci
31e41f4b71Sopenharmony_ci  Aging-friendly capabilities can be integrated with other features (such as swipe and drag). When the bottom tab bar (**tabBar**) component is activated for aging-friendly features, users can swipe their fingers or use a mouse to trigger aging-friendly features for other child components within the tab bar.
32e41f4b71Sopenharmony_ci
33e41f4b71Sopenharmony_ci## Aging-Friendly Component Adaptation and Activation Methods
34e41f4b71Sopenharmony_ci
35e41f4b71Sopenharmony_ci| Activation Method            | Component                                                    |
36e41f4b71Sopenharmony_ci| -------------------- | ------------------------------------------------------------ |
37e41f4b71Sopenharmony_ci| Long press on the component        | [SideBarContainer](../reference/apis-arkui/arkui-ts/ts-container-sidebarcontainer.md), [Bottom Tab Bar (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-navigation.md#navdestination10), [Tabs](../reference/apis-arkui/arkui-ts/ts-container-tabs.md)|
38e41f4b71Sopenharmony_ci| Default system font enlargement| [Picker](../reference/apis-arkui/arkui-ts/ts-basic-components-datepicker.md), [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)|
39e41f4b71Sopenharmony_ci
40e41f4b71Sopenharmony_ci## Example
41e41f4b71Sopenharmony_ci
42e41f4b71Sopenharmony_ciThis example involves the **SideBarContainer** component, which triggers an aging-friendly dialog box when the control button is long-pressed. The dialog box does not appear if the system font size is at the default 1x setting; it appears only when the system font size is set to greater than 1x.
43e41f4b71Sopenharmony_ci
44e41f4b71Sopenharmony_ci```ts
45e41f4b71Sopenharmony_ciimport { abilityManager, Configuration } from '@kit.AbilityKit';
46e41f4b71Sopenharmony_ciimport { BusinessError } from '@kit.BasicServicesKit';
47e41f4b71Sopenharmony_ci
48e41f4b71Sopenharmony_ci@Entry
49e41f4b71Sopenharmony_ci@Component
50e41f4b71Sopenharmony_cistruct SideBarContainerExample {
51e41f4b71Sopenharmony_ci  @State currentFontSizeScale: number = 1
52e41f4b71Sopenharmony_ci  normalIcon: Resource = $r("app.media.icon")
53e41f4b71Sopenharmony_ci  selectedIcon: Resource = $r("app.media.icon")
54e41f4b71Sopenharmony_ci  @State arr: number[] = [1, 2, 3]
55e41f4b71Sopenharmony_ci  @State current: number = 1
56e41f4b71Sopenharmony_ci  @State title: string = 'Index01';
57e41f4b71Sopenharmony_ci  // Set the font scale.
58e41f4b71Sopenharmony_ci  async setFontScale(scale: number): Promise<void> {
59e41f4b71Sopenharmony_ci    let configInit: Configuration = {
60e41f4b71Sopenharmony_ci      language: 'zh-Ch',
61e41f4b71Sopenharmony_ci      fontSizeScale: scale,
62e41f4b71Sopenharmony_ci    };
63e41f4b71Sopenharmony_ci    // Update the font size.
64e41f4b71Sopenharmony_ci    abilityManager.updateConfiguration(configInit, (err: BusinessError) => {
65e41f4b71Sopenharmony_ci      if (err) {
66e41f4b71Sopenharmony_ci        console.error(`updateConfiguration fail, err: ${JSON.stringify(err)}`);
67e41f4b71Sopenharmony_ci      } else {
68e41f4b71Sopenharmony_ci        this.currentFontSizeScale = scale;
69e41f4b71Sopenharmony_ci        console.log('updateConfiguration success.');
70e41f4b71Sopenharmony_ci      }
71e41f4b71Sopenharmony_ci    });
72e41f4b71Sopenharmony_ci  }
73e41f4b71Sopenharmony_ci
74e41f4b71Sopenharmony_ci  build() {
75e41f4b71Sopenharmony_ci    SideBarContainer(SideBarContainerType.Embed) {
76e41f4b71Sopenharmony_ci      Column() {
77e41f4b71Sopenharmony_ci        ForEach(this.arr, (item: number) => {
78e41f4b71Sopenharmony_ci          Column({ space: 5 }) {
79e41f4b71Sopenharmony_ci            Image(this.current === item ? this.selectedIcon : this.normalIcon).width(64).height(64)
80e41f4b71Sopenharmony_ci            Text("0" + item)
81e41f4b71Sopenharmony_ci              .fontSize(25)
82e41f4b71Sopenharmony_ci              .fontColor(this.current === item ? '#0A59F7' : '#999')
83e41f4b71Sopenharmony_ci              .fontFamily('source-sans-pro,cursive,sans-serif')
84e41f4b71Sopenharmony_ci          }
85e41f4b71Sopenharmony_ci          .onClick(() => {
86e41f4b71Sopenharmony_ci            this.current = item;
87e41f4b71Sopenharmony_ci            this.title = "Index0" + item;
88e41f4b71Sopenharmony_ci          })
89e41f4b71Sopenharmony_ci        }, (item: string) => item)
90e41f4b71Sopenharmony_ci      }.width('100%')
91e41f4b71Sopenharmony_ci      .justifyContent(FlexAlign.SpaceEvenly)
92e41f4b71Sopenharmony_ci      .backgroundColor($r('sys.color.mask_fifth'))
93e41f4b71Sopenharmony_ci
94e41f4b71Sopenharmony_ci      Column() {
95e41f4b71Sopenharmony_ci        Text(this.title)
96e41f4b71Sopenharmony_ci        Button('1x').onClick(() => {
97e41f4b71Sopenharmony_ci          this.setFontScale(1)
98e41f4b71Sopenharmony_ci        }).margin(10)
99e41f4b71Sopenharmony_ci        Button('1.75x').onClick(() => {
100e41f4b71Sopenharmony_ci          this.setFontScale(1.75)
101e41f4b71Sopenharmony_ci        }).margin(10)
102e41f4b71Sopenharmony_ci        Button('2x').onClick(() => {
103e41f4b71Sopenharmony_ci          this.setFontScale(2)
104e41f4b71Sopenharmony_ci        }).margin(10)
105e41f4b71Sopenharmony_ci        Button('3.2x').onClick(() => {
106e41f4b71Sopenharmony_ci          this.setFontScale(3.2)
107e41f4b71Sopenharmony_ci        }).margin(10)
108e41f4b71Sopenharmony_ci      }
109e41f4b71Sopenharmony_ci      .margin({ top: 50, left: 20, right: 30 })
110e41f4b71Sopenharmony_ci    }
111e41f4b71Sopenharmony_ci    .controlButton({
112e41f4b71Sopenharmony_ci      icons: {
113e41f4b71Sopenharmony_ci        hidden: $r('sys.media.ohos_ic_public_drawer_open_filled'),
114e41f4b71Sopenharmony_ci        shown: $r('sys.media.ohos_ic_public_drawer_close')
115e41f4b71Sopenharmony_ci      }
116e41f4b71Sopenharmony_ci    })
117e41f4b71Sopenharmony_ci    .sideBarWidth(150)
118e41f4b71Sopenharmony_ci    .minSideBarWidth(50)
119e41f4b71Sopenharmony_ci    .maxSideBarWidth(300)
120e41f4b71Sopenharmony_ci    .minContentWidth(0)
121e41f4b71Sopenharmony_ci    .onChange((value: boolean) => {
122e41f4b71Sopenharmony_ci      console.info('status:' + value)
123e41f4b71Sopenharmony_ci    })
124e41f4b71Sopenharmony_ci    .divider({ strokeWidth: '1vp', color: Color.Gray, startMargin: '4vp', endMargin: '4vp' })
125e41f4b71Sopenharmony_ci  }
126e41f4b71Sopenharmony_ci}
127e41f4b71Sopenharmony_ci```
128e41f4b71Sopenharmony_ci
129e41f4b71Sopenharmony_ciSwitching system font sizes and long-pressing components with aging-friendly capabilities yields the effects as follows.
130e41f4b71Sopenharmony_ci
131e41f4b71Sopenharmony_ci| System Font at 1x (Before Aging-Friendly Features Are Enabled)| System Font at 1.75x (After Aging-Friendly Features Are Enabled)|
132e41f4b71Sopenharmony_ci| ---------------------------------- | ------------------------------------ |
133e41f4b71Sopenharmony_ci| ![](figures/aging_01.png)          | ![](figures/aging_02.png)            |
134e41f4b71Sopenharmony_ci
135e41f4b71Sopenharmony_ciThe **TextPickerDialog** component triggers an aging-friendly dialog box when the system font is set to greater than 1x, which does not occur at the default 1x setting.
136e41f4b71Sopenharmony_ci
137e41f4b71Sopenharmony_ci```ts
138e41f4b71Sopenharmony_ciimport { abilityManager, Configuration } from '@kit.AbilityKit';
139e41f4b71Sopenharmony_ciimport { BusinessError } from '@kit.BasicServicesKit';
140e41f4b71Sopenharmony_ci
141e41f4b71Sopenharmony_ci@Entry
142e41f4b71Sopenharmony_ci@Component
143e41f4b71Sopenharmony_cistruct TextPickerExample {
144e41f4b71Sopenharmony_ci  private select: number | number[] = 0;
145e41f4b71Sopenharmony_ci  private cascade: TextCascadePickerRangeContent[] = [
146e41f4b71Sopenharmony_ci    {
147e41f4b71Sopenharmony_ci      text: 'Category 1',
148e41f4b71Sopenharmony_ci      children: [{ text: 'Subcategory 1', children: [{ text: 'Subcategory 2' }, { text: 'Subcategory 3' }, { text: 'Subcategory 4' }] },
149e41f4b71Sopenharmony_ci        { text: 'Item 1', children: [{ text: 'Item 2' }, { text: 'Item 3' }, { text: 'Item 4' }] }]
150e41f4b71Sopenharmony_ci    },
151e41f4b71Sopenharmony_ci    {
152e41f4b71Sopenharmony_ci      text: 'Category 2',
153e41f4b71Sopenharmony_ci      children: [{ text: 'Subcategory 1', children: [{ text: 'Subcategory 2' }, { text: 'Subcategory 3' }, { text: 'Subcategory 4' }] },
154e41f4b71Sopenharmony_ci        { text: 'Item 1', children: [{ text: 'Item 2' }, { text: 'Item 3' }, { text: 'Item 4' }] }]
155e41f4b71Sopenharmony_ci    },
156e41f4b71Sopenharmony_ci    {
157e41f4b71Sopenharmony_ci      text: 'Category 3',
158e41f4b71Sopenharmony_ci      children: [{ text: 'Subcategory 1', children: [{ text: 'Subcategory 2' }, { text: 'Subcategory 3' }, { text: 'Subcategory 4' }] },
159e41f4b71Sopenharmony_ci        { text: 'Item 1', children: [{ text: 'Item 2' }, { text: 'Item 3' }, { text: 'Item 4' }] }]
160e41f4b71Sopenharmony_ci    }
161e41f4b71Sopenharmony_ci  ]
162e41f4b71Sopenharmony_ci  @State v: string = '';
163e41f4b71Sopenharmony_ci  @State showTriggered: string = '';
164e41f4b71Sopenharmony_ci  private triggered: string = '';
165e41f4b71Sopenharmony_ci  private maxLines: number = 3;
166e41f4b71Sopenharmony_ci  // Set the font scale.
167e41f4b71Sopenharmony_ci  async setFontScale(scale: number): Promise<void> {
168e41f4b71Sopenharmony_ci    let configInit: Configuration = {
169e41f4b71Sopenharmony_ci      fontSizeScale: scale,
170e41f4b71Sopenharmony_ci    };
171e41f4b71Sopenharmony_ci
172e41f4b71Sopenharmony_ci    abilityManager.updateConfiguration(configInit, (err: BusinessError) => {
173e41f4b71Sopenharmony_ci      if (err) {
174e41f4b71Sopenharmony_ci        console.error(`updateConfiguration fail, err: ${JSON.stringify(err)}`);
175e41f4b71Sopenharmony_ci      } else {
176e41f4b71Sopenharmony_ci        console.log('updateConfiguration success.');
177e41f4b71Sopenharmony_ci      }
178e41f4b71Sopenharmony_ci    });
179e41f4b71Sopenharmony_ci  }
180e41f4b71Sopenharmony_ci
181e41f4b71Sopenharmony_ci  linesNum(max: number): void {
182e41f4b71Sopenharmony_ci    let items: string[] = this.triggered.split('\n').filter(item => item != '');
183e41f4b71Sopenharmony_ci    if (items.length > max) {
184e41f4b71Sopenharmony_ci      this.showTriggered = items.slice(-this.maxLines).join('\n');
185e41f4b71Sopenharmony_ci    } else {
186e41f4b71Sopenharmony_ci      this.showTriggered = this.triggered;
187e41f4b71Sopenharmony_ci    }
188e41f4b71Sopenharmony_ci  }
189e41f4b71Sopenharmony_ci
190e41f4b71Sopenharmony_ci  build() {
191e41f4b71Sopenharmony_ci    Column() {
192e41f4b71Sopenharmony_ci      Button("TextPickerDialog.show:" + this.v)
193e41f4b71Sopenharmony_ci        .onClick(() => {
194e41f4b71Sopenharmony_ci          this.getUIContext().showTextPickerDialog({
195e41f4b71Sopenharmony_ci            range: this.cascade,
196e41f4b71Sopenharmony_ci            selected: this.select,
197e41f4b71Sopenharmony_ci            onAccept: (value: TextPickerResult) => {
198e41f4b71Sopenharmony_ci              this.select = value.index
199e41f4b71Sopenharmony_ci              console.log(this.select + '')
200e41f4b71Sopenharmony_ci              this.v = value.value as string
201e41f4b71Sopenharmony_ci              console.info("TextPickerDialog:onAccept()" + JSON.stringify(value))
202e41f4b71Sopenharmony_ci              if (this.triggered != '') {
203e41f4b71Sopenharmony_ci                this.triggered += `\nonAccept(${JSON.stringify(value)})`;
204e41f4b71Sopenharmony_ci              } else {
205e41f4b71Sopenharmony_ci                this.triggered = `onAccept(${JSON.stringify(value)})`;
206e41f4b71Sopenharmony_ci              }
207e41f4b71Sopenharmony_ci              this.linesNum(this.maxLines);
208e41f4b71Sopenharmony_ci            },
209e41f4b71Sopenharmony_ci            onCancel: () => {
210e41f4b71Sopenharmony_ci              console.info("TextPickerDialog:onCancel()")
211e41f4b71Sopenharmony_ci              if (this.triggered != '') {
212e41f4b71Sopenharmony_ci                this.triggered += `\nonCancel()`;
213e41f4b71Sopenharmony_ci              } else {
214e41f4b71Sopenharmony_ci                this.triggered = `onCancel()`;
215e41f4b71Sopenharmony_ci              }
216e41f4b71Sopenharmony_ci              this.linesNum(this.maxLines);
217e41f4b71Sopenharmony_ci            },
218e41f4b71Sopenharmony_ci            onChange: (value: TextPickerResult) => {
219e41f4b71Sopenharmony_ci              console.info("TextPickerDialog:onChange()" + JSON.stringify(value))
220e41f4b71Sopenharmony_ci              if (this.triggered != '') {
221e41f4b71Sopenharmony_ci                this.triggered += `\nonChange(${JSON.stringify(value)})`;
222e41f4b71Sopenharmony_ci              } else {
223e41f4b71Sopenharmony_ci                this.triggered = `onChange(${JSON.stringify(value)})`;
224e41f4b71Sopenharmony_ci              }
225e41f4b71Sopenharmony_ci              this.linesNum(this.maxLines);
226e41f4b71Sopenharmony_ci            },
227e41f4b71Sopenharmony_ci          })
228e41f4b71Sopenharmony_ci        })
229e41f4b71Sopenharmony_ci        .margin({ top: 60 })
230e41f4b71Sopenharmony_ci
231e41f4b71Sopenharmony_ci      Row() {
232e41f4b71Sopenharmony_ci        Button('1x').onClick(() => {
233e41f4b71Sopenharmony_ci          this.setFontScale(1)
234e41f4b71Sopenharmony_ci        }).margin(10)
235e41f4b71Sopenharmony_ci        Button('1.75x').onClick(() => {
236e41f4b71Sopenharmony_ci          this.setFontScale(1.75)
237e41f4b71Sopenharmony_ci        }).margin(10)
238e41f4b71Sopenharmony_ci
239e41f4b71Sopenharmony_ci        Button('2x').onClick(() => {
240e41f4b71Sopenharmony_ci          this.setFontScale(2)
241e41f4b71Sopenharmony_ci        }).margin(10)
242e41f4b71Sopenharmony_ci        Button('3.2x').onClick(() => {
243e41f4b71Sopenharmony_ci          this.setFontScale(3.2)
244e41f4b71Sopenharmony_ci        }).margin(10)
245e41f4b71Sopenharmony_ci      }.margin({ top: 50 })
246e41f4b71Sopenharmony_ci    }
247e41f4b71Sopenharmony_ci
248e41f4b71Sopenharmony_ci  }
249e41f4b71Sopenharmony_ci}
250e41f4b71Sopenharmony_ci```
251e41f4b71Sopenharmony_ci
252e41f4b71Sopenharmony_ci| System Font at 1x (Before Aging-Friendly Features Are Enabled)| System Font at 1.75x (After Aging-Friendly Features Are Enabled)|
253e41f4b71Sopenharmony_ci| ---------------------------------- | ------------------------------------ |
254e41f4b71Sopenharmony_ci| ![](figures/aging_03.png)          | ![](figures/aging_04.png)            |
255