1# 像素单位转换
2
3在日常应用页面布局设计时,开发者需要知道每个组件的样式及位置,这时就需要了解像素单位及相互转换方法,ArkUI 开发框架提供了4种像素单位供开发者使用,分别是: px 、 vp 、 fp 和 lpx ,框架采用 vp 为基准数据单位,本篇就简单为大家介绍下像素单位的基本知识与像素单位转换API的使用。通过像素转换案例,向开发者讲解了如何使用像素单位设置组件的尺寸、字体的大小以及不同像素单位之间的转换方法。
4
5## 效果呈现
6本例最终效果如下:
7
8![Pixel-Convertion](figures/Pixel-Convertion.gif)
9
10
11
12## 运行环境
13本例基于以下环境开发,开发者也可以基于其他适配的版本进行开发:
14- IDE: DevEco Studio 3.1 Release
15- SDK: Ohos_sdk_public 3.2.12.5(API Version 9 Release)
16## 实现思路
17本篇案例主要功能包括:①像素单位基本知识介绍;②像素单位转换相关API的使用。
18* 构建入口页面:该页面包含两个button组件,通过点击按钮事件,实现到详细页面的跳转
19
20* 像素单位介绍页面:
21  * 构建IntroducitonViewModel.ets
22
23    创建自定义接口IntroductionItem,根据IntroductionItem接口参数,创建对象数组INTRODUCE_LIST,向对象数组INTRODUCE_LIST中填充像素单位介绍页面所需参数内容。
24
25  * 构建IntroducitonPage.ets
26
27    通过ForEach循环渲染上一步骤中对象数组中的每个Item;通过if判断组件的显隐,同时添加样式,完成像素介绍页面。
28
29* 像素转换页面:
30  * 构建ConvertionViewModel.ets
31
32    创建自定义接口ConversionItem,根据ConversionItem接口参数,创建对象数组ConversionViewModel,向对象数组ConversionViewModel中填充像素转换页面所需参数内容。
33
34  * 构建ConvertionPage.ets
35
36    通过ForEach循环渲染上一步构建的ConversionViewModel的每个子菜单Item,同时添加样式,构建像素介绍页面。
37
38
39
40## 开发步骤
411. 构建入口页面:该页面包含两个button按钮,通过点击按钮事件,实现到详细页的跳转。
42    具体代码如下:
43    ```ts
44    // entry/src/main/ets/pages/IndexPage.ets
45
46    import router from '@ohos.router';
47    @Entry
48    @Component
49    struct IndexPage {
50        // 定义jumpPage方法,实现路由跳转
51        jumpPage(url: string) {
52            router.pushUrl({ url })
53        }
54
55        build() {
56            Column({ space: 24 }) {
57                Button('像素介绍')
58                    .height('40vp')
59                    .width('100%')
60                    .backgroundColor($r('app.color.blue_background'))
61                    // 点击时回调jumpPage方法,跳转到pages/IntroductionPage页面
62                .onClick(() => this.jumpPage('pages/IntroductionPage'))
63
64                Button('像素转换')
65                    .height('40vp')
66                    .width('100%')
67                    .backgroundColor($r('app.color.blue_background'))
68                    // 点击时回调jumpPage方法,跳转到pages/ConversionPage页面
69                    .onClick(() => this.jumpPage('pages/ConversionPage'))
70            }
71            .backgroundColor($r('app.color.page_background'))
72            .justifyContent(FlexAlign.Center)
73            .padding(24)
74            .width('100%')
75            .height('100%')
76        }
77    }
78
79    ```
80
812. 像素单位介绍页面创建。
82    此页面主要系统介绍像素单位的概念,包含px、vp、lpx以及fp,并在页面中 为Text组件的宽度属性设置不同的像素单位(如px、vp、lpx),fp像素单位则设置为Text组件的字体大小。
83
84    * 从效果图看,此页面由4个功能相同的菜单组成,我们先构建功能菜单。
85    创建IntroducitonViewModel.ets定义每个子功能菜单Item。
86    具体代码如下:
87
88        ```ts
89        // entry/src/main/ets/viewmodel/IntroducitonViewModel.ets
90
91        // 创建自定义接口,定义每个Item中的内容
92        interface IntroductionItem {
93            name: string;
94            title: string;
95            subTitle: string;
96            value: string;
97            smallFontSize: number;
98            largeFontSize: number;
99        }
100
101        // 根据自定义接口IntroductionItem,填充内容
102        const INTRODUCE_LIST: IntroductionItem[] = [
103        {
104            name: 'px',
105            title: '屏幕物理像素单位。',
106            subTitle: null,
107            value: '200px',
108            smallFontSize: 0,
109            largeFontSize: 0
110        },
111        {
112            name: 'vp',
113            title:'屏幕密度相关像素,根据屏幕像素密度转换为屏幕物理像素。',
114            value:'200vp',
115            subTitle:'像素密度为160dpi的设备上1vp=1px,1vp对应的物理屏幕像素=(屏幕像素密度/160)px',
116            smallFontSize: 0,
117            largeFontSize: 0
118        },
119        {
120            name: 'lpx',
121            title:'视窗逻辑像素单位,lpx单位为实际屏幕宽度与逻辑宽度(通过designWidth配置)的比值。',
122            subTitle: null,
123            value: '200lpx',
124            smallFontSize: 0,
125            largeFontSize: 0
126        },
127        {
128            name: 'fp',
129            title:'字体像素,与vp类似,随系统字体大小设置变化。',
130            subTitle:'默认情况下与vp相同,即1vp=1fp,如果用户手动调整了系统字体,scale为缩放比例,设置后的字体大小(单位fp) = 设置前的字体大小 * scale',
131            value: '',
132            smallFontSize: 14,
133            largeFontSize: 24
134        }
135        ];
136
137        // 定义类IntroductionViewModel,获取像素介绍页面的数据
138        class IntroductionViewModel {
139            getIntroductionList() {
140                let introductionItems = INTRODUCE_LIST;
141                return introductionItems;
142        	}
143        }
144
145        let introductionViewModel = new IntroductionViewModel();
146        export default introductionViewModel as IntroductionViewModel;
147
148        ```
149    * 渲染像素单位介绍页面,通过ForEach循环渲染上一步构建的IntroductionViewModel的每个子菜单Item;通过if判断组件的显隐,为显示的组件,添加样式,构建像素介绍页面。
150        具体代码如下:
151
152        ```ts
153        // entry/src/main/ets/pages/IntroducitonPages.ets
154        import IntroductionViewModel from '../viewmodel/IntroductionViewModel';
155
156            interface IntroductionItem {
157                name: string;
158                title: Resource;
159                subTitle: Resource;
160                value: string;
161                smallFontSize: number;
162                largeFontSize: number;
163        	}
164
165            @Extend(Text) function titleTextStyle() {
166                .fontColor($r('app.color.title_font'))
167                .fontFamily('HarmonyHeiTi_Medium')
168                .fontWeight(500)
169        	}
170
171            @Entry
172            @Component
173            struct IntroductionPage {
174                build() {
175                    Column() {
176                        Navigation() {
177                            List({ space: 12 }) {
178                            //通过ForEach循环渲染Item,构建像素介绍页面
179                                ForEach(IntroductionViewModel.getIntroductionList(), (item: IntroductionItem) => {
180                                    //渲染每个Item
181                                    ListItem() {
182                                        Column() {
183                                            Text(item.name)
184                                                .titleTextStyle()
185                                                .fontSize('16fp')
186                                            Text(item.title)
187                                                .titleTextStyle()
188                                                .fontSize('14fp')
189                                                .fontFamily('HarmonyHeiTi')
190                                                .lineHeight('20fp')
191                                                .margin({ top: '8vp'})
192                                                .fontWeight(400)
193                                            // subTitle非空,添加Text组件,显示subTitle内容,同时添加样式;不存在则不显示
194                                            if (item.subTitle) {
195                                                Text(item.subTitle)
196                                                    .titleTextStyle()
197                                                    .opacity(0.6)
198                                                    .lineHeight('16fp')
199                                                    .fontSize('12fp')
200                                                    .fontFamily($r('app.string.HarmonyHeiTi'))
201                                                    .margin({ top: '20vp' })
202                                                    .fontWeight(400)
203                                        }
204
205                                            // value非空,添加Text组件且通过宽度属性设置不同的像素单位
206                                            if (item.value.length > 0) {
207                                                Text(item.value)
208                                                    .titleTextStyle()
209                                                    .fontColor($r('app.color.item_background'))
210                                                    .fontSize('16fp')
211                                                    .textAlign(TextAlign.Center)
212                                                    .backgroundColor($r('app.color.blue_background'))
213                                                    .height('28vp')
214                                                    .width(item.value)
215                                                    .borderRadius('4vp')
216                                                    .margin({ top: '12vp' })
217                                            // value为空,添加两个text组件,使用fp像素单位设置为Text组件的字体大小
218                                            } else {
219                                                Column() {
220                                                    Text($r('app.string.font_desc', item.smallFontSize))
221                                                        .titleTextStyle()
222                                                        .fontSize(item.smallFontSize)
223                                                    Text($r('app.string.font_desc', item.largeFontSize))
224                                                        .titleTextStyle()
225                                                        .fontSize(item.largeFontSize)
226                                                        .margin({ top: '6vp' })
227                                                }
228                                                    .alignItems(HorizontalAlign.Start)
229                                                    .backgroundColor($r('app.color.font_background'))
230                                                    .width('100%')
231                                                    .borderRadius('12vp')
232                                                    .padding('12vp')
233                                                    .margin({ top: '12vp' })
234                                            }
235                                        }
236                                        .alignItems(HorizontalAlign.Start)
237                                        .width('100%')
238                                        .padding('12vp')
239                                        .borderRadius('24vp')
240                                        .backgroundColor('#FFFFFF')
241                                    }
242                                    .padding({
243                                    left: '12vp',
244                                    right: '12vp'
245                                    })
246                                })
247                            }
248                            .width('100%')
249                            .height('100%')
250                        }
251                        .titleMode(NavigationTitleMode.Mini)
252                        .title('像素介绍')
253                    }
254                    .backgroundColor($r('app.color.page_background'))
255                    .width('100%')
256                    .height('100%')
257                }
258            }
259        ```
260
2613. 像素转换页面创建。
262    此页面主要是通过使用像素转换API,实现不同像素单位之间的相互转换功能。
263
264    * 从效果图看,此页面由3个功能相同的菜单组成,我们先构建功能菜单。
265    创建ConversionViewModel.ets定义每个子功能菜单Item。
266    具体代码如下:
267
268        ```ts
269        // entry/src/main/ets/viewmodel/ConversionViewModel.ets
270
271        // 创建自定义接口,定义每个Item中的内容
272        interface ConversionItem {
273            title: string;
274            subTitle: string;
275            value: number;
276            conversionTitle: string;
277            conversionSubTitle: string;
278            conversionValue: number;
279            notice: string;
280        }
281
282        // 定义类ConversionViewModel,获取像素转换页面的数据
283        class ConversionViewModel {
284            getConversionList() {
285                let conversionItems = CONVERSION_LIST;
286                return conversionItems;
287            }
288        }
289
290        // 根据自定义接口ConversionItem,填充内容
291        export const CONVERSION_LIST: ConversionItem[] = [
292        {
293            title: 'vp > px',
294            subTitle: `vp2px(60)`,
295            value: vp2px(60),
296            conversionTitle: 'px > vp',
297            conversionSubTitle: `px2vp(60)`,
298            conversionValue: px2vp(60),
299            notice: null
300        },
301        {
302            title: 'fp > px',
303            subTitle: `fp2px(60)`,
304            value: fp2px(60),
305            conversionTitle: 'px > fp',
306            conversionSubTitle: `px2fp(60})`,
307            conversionValue: px2fp(60),
308            notice: null
309        },
310        {
311            title: 'lpx > px',
312            subTitle: `lpx2px(60)`,
313            value: lpx2px(60),
314            conversionTitle: 'px > lpx',
315            conversionSubTitle: `px2lpx(60)`,
316            conversionValue: px2lpx(60),
317            notice: 'lpx与px之间的转换,需要根据实际情况设置designWidth'
318        }
319        ];
320
321        let conversionViewModel = new ConversionViewModel();
322        export default conversionViewModel as ConversionViewModel;
323
324        ```
325    * 渲染像素单位介绍页面,通过ForEach循环渲染上一步构建的ConversionViewModel的每个子菜单Item,同时添加样式,构建像素介绍页面。
326        具体代码如下:
327
328        ```ts
329        // entry/src/main/ets/pages/ConversionPage.ets
330
331        import ConversionViewModel from '../viewmodel/ConversionViewModel';
332
333        interface ConversionItem {
334            title: string;
335            subTitle: string;
336            value: number;
337            conversionTitle: string;
338            conversionSubTitle: string;
339            conversionValue: number;
340            notice: string;
341        }
342
343        @Extend(Text) function descTextStyle() {
344            .fontColor($r('app.color.title_font'))
345            .fontSize('14fp')
346            .fontFamily($r('app.string.HarmonyHeiTi'))
347            .lineHeight('20fp')
348            .fontWeight(400)
349            .margin({ top: '8vp' })
350        }
351
352        @Extend(Text) function titleTextStyle() {
353            .fontColor($r('app.color.title_font'))
354            .fontSize('16fp')
355            .fontFamily($r('app.string.HarmonyHeiTi_Medium'))
356            .fontWeight(500)
357        }
358
359        @Styles function blueStyle() {
360            .backgroundColor($r('app.color.blue_background'))
361            .height('28vp')
362            .borderRadius('4vp')
363            .margin({ top: '4vp' })
364        }
365
366        @Entry
367        @Component
368        struct ConversionPage {
369            build() {
370                Column() {
371                    Navigation() {
372                        List({ space: 12 }) {
373                        //通过ForEach循环渲染Item,构建像素转换页面
374                            ForEach(ConversionViewModel.getConversionList(), (item: ConversionItem) => {
375                                //渲染每个Item
376                                ListItem() {
377                                    Column() {
378                                        Text(item.title)
379                                            .titleTextStyle()
380                                            .margin({ top: '6vp' })
381                                            Text(item.subTitle)
382                                            .descTextStyle()
383                                            .opacity(0.6)
384                                        Row()
385                                        .blueStyle()
386                                            // 为宽度属性设置不同的像素单位
387                                            .width(item.value)
388                                        Text(item.conversionTitle)
389                                            .titleTextStyle()
390                                            .margin({ top: '18vp' })
391                                        Text(item.conversionSubTitle)
392                                            .descTextStyle()
393                                            .opacity(0.6)
394                                        Row()
395                                            .blueStyle()
396                                            // 为宽度属性设置不同的像素单位
397                                            .width(item.conversionValue)
398                                        if (item.notice) {
399                                            Text(item.notice)
400                                                .descTextStyle()
401                                                .fontColor($r('app.color.notice_font'))
402                                        }
403                                    }
404                                    .alignItems(HorizontalAlign.Start)
405                                    .width('100%')
406                                    .padding('12vp')
407                                    .borderRadius('24vp')
408                                    .backgroundColor('#FFFFFF')
409                                }
410                                .padding({left: '12vp',right: '12vp'})
411                            })
412                        }
413                        .width('100%')
414                        .height('100%')
415                    }
416                    .titleMode(NavigationTitleMode.Mini)
417                    .title('像素转换')
418                }
419                .backgroundColor($r('app.color.page_background'))
420                .width('100%')
421                .height('100%')
422            }
423        }
424
425        ```
426
427
428## 完整代码
429本例完整代码如下:
430
431* 应用主页面:entry/src/main/ets/pages/IndexPage.ets432
433  ```ts
434  import router from '@ohos.router';
435  @Entry
436  @Component
437  struct IndexPage {
438      // 定义jumpPage方法,实现路由跳转
439      jumpPage(url: string) {
440          router.pushUrl({ url })
441      }
442
443      build() {
444          Column({ space: 24 }) {
445          Button('像素介绍')
446              .height('40vp')
447              .width('100%')
448              .backgroundColor($r('app.color.blue_background'))
449              // 点击时回调jumpPage方法,跳转到pages/IntroductionPage页面
450              .onClick(() => this.jumpPage('pages/IntroductionPage'))
451
452          Button('像素转换')
453              .height('40vp')
454              .width('100%')
455              .backgroundColor($r('app.color.blue_background'))
456              // 点击时回调jumpPage方法,跳转到pages/ConversionPage页面
457              .onClick(() => this.jumpPage('pages/ConversionPage'))
458          }
459          .backgroundColor($r('app.color.page_background'))
460          .justifyContent(FlexAlign.Center)
461          .padding(24)
462          .width('100%')
463          .height('100%')
464      }
465  }
466  ```
467
468
469
470* 像素介绍ViewModel:entry/src/main/ets/viewmodel/IntroducitonViewModel.ets471
472  ```ts
473    // 创建自定义接口,定义每个Item中的内容
474    interface IntroductionItem {
475        name: string;
476        title: string;
477        subTitle: string;
478        value: string;
479        smallFontSize: number;
480        largeFontSize: number;
481    }
482
483    // 根据自定义接口IntroductionItem,填充内容
484    const INTRODUCE_LIST: IntroductionItem[] = [
485    {
486        name: 'px',
487        title: '屏幕物理像素单位。',
488        subTitle: null,
489        value: Constants.PIXEL_WIDTH + 'px',
490        smallFontSize: 0,
491        largeFontSize: 0
492    },
493    {
494        name: 'vp',
495        title:'屏幕密度相关像素,根据屏幕像素密度转换为屏幕物理像素。',
496        value: Constants.PIXEL_WIDTH + 'vp',
497        subTitle:'像素密度为160dpi的设备上1vp=1px,1vp对应的物理屏幕像素=(屏幕像素密度/160)px',
498        smallFontSize: 0,
499        largeFontSize: 0
500    },
501    {
502        name: 'lpx',
503        title:'视窗逻辑像素单位,lpx单位为实际屏幕宽度与逻辑宽度(通过designWidth配置)的比值。',
504        subTitle: null,
505        value: Constants.PIXEL_WIDTH + 'lpx',
506        smallFontSize: 0,
507        largeFontSize: 0
508    },
509    {
510        name: 'fp',
511        title:'字体像素,与vp类似,随系统字体大小设置变化。',
512        subTitle:'默认情况下与vp相同,即1vp=1fp,如果用户手动调整了系统字体,scale为缩放比例,设置后的字体大小(单位fp) = 设置前的字体大小 * scale',
513        value: '',
514        smallFontSize: Constants.SMALL_FONT_SIZE,
515        largeFontSize: Constants.LARGE_FONT_SIZE
516    }
517    ];
518
519    // 定义类IntroductionViewModel,获取像素介绍页面的数据
520    class IntroductionViewModel {
521        getIntroductionList() {
522            let introductionItems = INTRODUCE_LIST;
523            return introductionItems;
524    	}
525    }
526
527    let introductionViewModel = new IntroductionViewModel();
528    export default introductionViewModel as IntroductionViewModel;
529  ```
530
531
532
533* 像素介绍页面:entry/src/main/ets/pages/IntroducitonPages.ets534
535  ```ts
536  import IntroductionViewModel from '../viewmodel/IntroductionViewModel';
537
538  interface IntroductionItem {
539      name: string;
540      title: Resource;
541      subTitle: Resource;
542      value: string;
543      smallFontSize: number;
544      largeFontSize: number;
545  }
546
547  @Extend(Text) function titleTextStyle() {
548      .fontColor($r('app.color.title_font'))
549      .fontFamily('HarmonyHeiTi_Medium')
550      .fontWeight(500)
551  }
552
553  @Entry
554  @Component
555  struct IntroductionPage {
556      build() {
557          Column() {
558              Navigation() {
559                  List({ space: 12 }) {
560                  //通过ForEach循环渲染Item,构建像素介绍页面
561                      ForEach(IntroductionViewModel.getIntroductionList(), (item: IntroductionItem) => {
562                          //渲染每个Item
563                          ListItem() {
564                              Column() {
565                                  Text(item.name)
566                                      .titleTextStyle()
567                                      .fontSize('16fp')
568                                  Text(item.title)
569                                      .titleTextStyle()
570                                      .fontSize('14fp')
571                                      .fontFamily('HarmonyHeiTi')
572                                      .lineHeight('20fp')
573                                      .margin({ top: '8vp'})
574                                      .fontWeight(400)
575                                  // subTitle非空,添加Text组件,显示subTitle内容,同时添加样式;不存在则不显示
576                                  if (item.subTitle) {
577                                      Text(item.subTitle)
578                                          .titleTextStyle()
579                                          .opacity(0.6)
580                                          .lineHeight('16fp')
581                                          .fontSize('12fp')
582                                          .fontFamily($r('app.string.HarmonyHeiTi'))
583                                          .margin({ top: '20vp' })
584                                          .fontWeight(400)
585                                  }
586
587                                  // value非空,添加Text组件且通过宽度属性设置不同的像素单位
588                                  if (item.value.length > 0) {
589                                      Text(item.value)
590                                          .titleTextStyle()
591                                          .fontColor($r('app.color.item_background'))
592                                          .fontSize('16fp')
593                                          .textAlign(TextAlign.Center)
594                                          .backgroundColor($r('app.color.blue_background'))
595                                          .height('28vp')
596                                          .width(item.value)
597                                          .borderRadius('4vp')
598                                          .margin({ top: '12vp' })
599                                  // value为空,添加两个text组件,使用fp像素单位设置为Text组件的字体大小
600                                  } else {
601                                      Column() {
602                                          Text($r('app.string.font_desc', item.smallFontSize))
603                                              .titleTextStyle()
604                                              .fontSize(item.smallFontSize)
605                                          Text($r('app.string.font_desc', item.largeFontSize))
606                                              .titleTextStyle()
607                                              .fontSize(item.largeFontSize)
608                                              .margin({ top: '6vp' })
609                                      }
610                                          .alignItems(HorizontalAlign.Start)
611                                          .backgroundColor($r('app.color.font_background'))
612                                          .width('100%')
613                                          .borderRadius('12vp')
614                                          .padding('12vp')
615                                          .margin({ top: '12vp' })
616                                  }
617                              }
618                              .alignItems(HorizontalAlign.Start)
619                              .width('100%')
620                              .padding('12vp')
621                              .borderRadius('24vp')
622                              .backgroundColor('#FFFFFF')
623                          }
624                          .padding({
625                          left: '12vp',
626                          right: '12vp'
627                          })
628                      })
629                  }
630                  .width('100%')
631                  .height('100%')
632              }
633              .titleMode(NavigationTitleMode.Mini)
634              .title('像素介绍')
635          }
636          .backgroundColor($r('app.color.page_background'))
637          .width('100%')
638          .height('100%')
639      }
640  }
641  ```
642
643
644
645* 像素转换ViewModel:entry/src/main/ets/viewmodel/ConversionViewModel.ets646
647  ```ts
648    // 创建自定义接口,定义每个Item中的内容
649    interface ConversionItem {
650        title: string;
651        subTitle: string;
652        value: number;
653        conversionTitle: string;
654        conversionSubTitle: string;
655        conversionValue: number;
656        notice: string;
657    }
658
659    // 定义类ConversionViewModel,获取像素转换页面的数据
660    class ConversionViewModel {
661        getConversionList() {
662            let conversionItems = CONVERSION_LIST;
663            return conversionItems;
664        }
665    }
666
667    // 根据自定义接口ConversionItem,填充内容
668    export const CONVERSION_LIST: ConversionItem[] = [
669    {
670        title: 'vp > px',
671        subTitle: `vp2px(60)`,
672        value: vp2px(60),
673        conversionTitle: 'px > vp',
674        conversionSubTitle: `px2vp(60)`,
675        conversionValue: px2vp(60),
676        notice: null
677    },
678    {
679        title: 'fp > px',
680        subTitle: `fp2px(60)`,
681        value: fp2px(60),
682        conversionTitle: 'px > fp',
683        conversionSubTitle: `px2fp(60})`,
684        conversionValue: px2fp(60),
685        notice: null
686    },
687    {
688        title: 'lpx > px',
689        subTitle: `lpx2px(60)`,
690        value: lpx2px(60),
691        conversionTitle: 'px > lpx',
692        conversionSubTitle: `px2lpx(60)`,
693        conversionValue: px2lpx(60),
694        notice: 'lpx与px之间的转换,需要根据实际情况设置designWidth'
695    }
696    ];
697
698    let conversionViewModel = new ConversionViewModel();
699    export default conversionViewModel as ConversionViewModel;
700  ```
701
702
703
704* 像素转换页面:entry/src/main/ets/pages/ConversionPage.ets705
706  ```ts
707  import ConversionViewModel from '../viewmodel/ConversionViewModel';
708
709  interface ConversionItem {
710      title: string;
711      subTitle: string;
712      value: number;
713      conversionTitle: string;
714      conversionSubTitle: string;
715      conversionValue: number;
716      notice: string;
717  }
718
719  @Extend(Text) function descTextStyle() {
720      .fontColor($r('app.color.title_font'))
721      .fontSize('14fp')
722      .fontFamily($r('app.string.HarmonyHeiTi'))
723      .lineHeight('20fp')
724      .fontWeight(400)
725      .margin({ top: '8vp' })
726  }
727
728  @Extend(Text) function titleTextStyle() {
729      .fontColor($r('app.color.title_font'))
730      .fontSize('16fp')
731      .fontFamily($r('app.string.HarmonyHeiTi_Medium'))
732      .fontWeight(500)
733  }
734
735  @Styles function blueStyle() {
736      .backgroundColor($r('app.color.blue_background'))
737      .height('28vp')
738      .borderRadius('4vp')
739      .margin({ top: '4vp' })
740  }
741
742  @Entry
743  @Component
744  struct ConversionPage {
745      build() {
746          Column() {
747              Navigation() {
748                  List({ space: 12 }) {
749                  //通过ForEach循环渲染Item,构建像素转换页面
750                      ForEach(ConversionViewModel.getConversionList(), (item: ConversionItem) => {
751                          //渲染每个Item
752                          ListItem() {
753                              Column() {
754                                  Text(item.title)
755                                      .titleTextStyle()
756                                      .margin({ top: '6vp' })
757                                      Text(item.subTitle)
758                                      .descTextStyle()
759                                      .opacity(0.6)
760                                  Row()
761                                  .blueStyle()
762                                      // 为宽度属性设置不同的像素单位
763                                      .width(item.value)
764                                  Text(item.conversionTitle)
765                                      .titleTextStyle()
766                                      .margin({ top: '18vp' })
767                                  Text(item.conversionSubTitle)
768                                      .descTextStyle()
769                                      .opacity(0.6)
770                                  Row()
771                                      .blueStyle()
772                                      // 为宽度属性设置不同的像素单位
773                                      .width(item.conversionValue)
774                                  if (item.notice) {
775                                      Text(item.notice)
776                                          .descTextStyle()
777                                          .fontColor($r('app.color.notice_font'))
778                                  }
779                              }
780                              .alignItems(HorizontalAlign.Start)
781                              .width('100%')
782                              .padding('12vp')
783                              .borderRadius('24vp')
784                              .backgroundColor('#FFFFFF')
785                          }
786                          .padding({left: '12vp',right: '12vp'})
787                      })
788                  }
789                  .width('100%')
790                  .height('100%')
791              }
792              .titleMode(NavigationTitleMode.Mini)
793              .title('像素转换')
794          }
795          .backgroundColor($r('app.color.page_background'))
796          .width('100%')
797          .height('100%')
798      }
799  }
800  ```
801
802
803
804 ##  参考
805
806[像素单位](../application-dev/reference/apis-arkui/arkui-ts/ts-pixel-units.md)
807
808[List](../application-dev/reference/apis-arkui/arkui-ts/ts-container-list.md)
809
810[Column](../application-dev/reference/apis-arkui/arkui-ts/ts-container-column.md)
811
812[Text](../application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-text.md)
813
814[Navigation](../application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md)