1# 像素单位转换 2 3在日常应用页面布局设计时,开发者需要知道每个组件的样式及位置,这时就需要了解像素单位及相互转换方法,ArkUI 开发框架提供了4种像素单位供开发者使用,分别是: px 、 vp 、 fp 和 lpx ,框架采用 vp 为基准数据单位,本篇就简单为大家介绍下像素单位的基本知识与像素单位转换API的使用。通过像素转换案例,向开发者讲解了如何使用像素单位设置组件的尺寸、字体的大小以及不同像素单位之间的转换方法。 4 5## 效果呈现 6本例最终效果如下: 7 8 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.ets。 432 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.ets。 471 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.ets。 534 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.ets。 646 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.ets。 705 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)