1# ArkUI子系统Changelog 2 3## cl.arkui.1 @ComponentV2自定义组件冻结变更 4 5**访问级别** 6 7公开接口 8 9**变更原因** 10 11当@ComponentV2装饰的子组件设置freezeWhenInactive为true时,父组件没有设置,则子组件的组件冻结功能不生效。 12 13为了确保组件冻结功能生效,需要修改当子组件设置freezeWhenInactive为true,无论父组件是否设置,子组件的组件冻结功能应生效。 14 15**变更影响** 16 17该变更为不兼容变更。 18 19变更前:仅子组件开启了组件冻结,父组件没有开启组件冻结,不会对子组件开启冻结功能。 20 21变更后:仅子组件开启了组件冻结,父组件没有开启组件冻结,子组件会启用组件冻结功能。 22 23**起始API Level** 24 25API 12 26 27**变更发生版本** 28 29从OpenHarmony SDK 5.0.0.56开始。 30 31**变更的接口/组件** 32 33@ComponentV2的freezeWhenInactive接口。 34 35**适配指导** 36 37当子组件使用了组件冻结,父组件没有使用组件冻结的情况下,当组件处于inactive时,子组件组件冻结功能生效。示例如下: 38 39页面1: 40 41```ts 42// Page1.ets 43import { router } from '@kit.ArkUI'; 44 45@ObservedV2 46export class Book { 47 @Trace name: string = "100"; 48 49 constructor(page: string) { 50 this.name = page; 51 } 52} 53 54@Entry 55@ComponentV2 56export struct Page1 { 57 build() { 58 Column() { 59 Child() 60 } 61 } 62} 63 64@ComponentV2({ freezeWhenInactive: true }) 65export struct Child { 66 @Local bookTest: Book = new Book("A Midsummer Night’s Dream"); 67 68 @Monitor("bookTest.name") 69 onMessageChange(monitor: IMonitor) { 70 console.log(`The book name change from ${monitor.value()?.before} to ${monitor.value()?.now}`); 71 } 72 73 textUpdate(): number{ 74 console.log("The text is update"); 75 return 25; 76 } 77 78 build() { 79 Column() { 80 Text(`The book name is ${this.bookTest.name}`).fontSize(this.textUpdate()) 81 Button('go to next page').fontSize(30) 82 .onClick(() => { 83 router.pushUrl({ url: 'pages/Page2' }); 84 setTimeout(() => { 85 this.bookTest = new Book("Jane Austen oPride and Prejudice"); 86 }, 1000); 87 }) 88 } 89 } 90} 91``` 92 93页面2: 94 95```ts 96// Page2.ets 97import { router } from '@kit.ArkUI'; 98 99@Entry 100@ComponentV2 101struct Page2 { 102 build() { 103 Column() { 104 Text(`This is the page`).fontSize(50) 105 Button('Back') 106 .onClick(() => { 107 router.back(); 108 }) 109 } 110 } 111} 112``` 113 114如果开发者不关注组件冻结的功能是否生效,只是调用了其接口,会发现组件冻结能力在该场景下并没有生效,即在跳转到页面2后,改变状态变量`@Local bookTest`,页面1的Child组件还会刷新,其@Monitor也会调用。 115 116trace如下: 117 118 119变更后,修复了上面示例中组件冻结接口不生效的行为,变更后的行为是: 120- 页面1的子组件Child,设置`freezeWhenInactive: true`, 开启了组件冻结功能。 121- 点击Button跳转到页面2,然后延迟1s更新状态变量`bookTest`。在更新`bookTest`的时候,已经跳转到页面2,页面1的组件处于inactive状态,又因为Child组件开启了组件冻结,状态变量`@Local bookTest`将不响应更新,其@Monitor不会调用,状态变量关联的节点不会刷新。 122 123变更后trace如下: 124 125 126如果开发者希望Page1在不可见的时候依旧刷新,和正常触发@Monitor回调,建议不使用组件冻结功能,即不设置`freezeWhenInactive: true`。示例如下: 127 128 129页面1: 130 131```ts 132// Page1.ets 133import { router } from '@kit.ArkUI'; 134 135@ObservedV2 136export class Book { 137 @Trace name: string = "100"; 138 139 constructor(page: string) { 140 this.name = page; 141 } 142} 143 144@Entry 145@ComponentV2 146export struct Page1 { 147 build() { 148 Column() { 149 Child() 150 } 151 } 152} 153 154@ComponentV2 155export struct Child { 156 @Local bookTest: Book = new Book("A Midsummer Night’s Dream"); 157 158 @Monitor("bookTest.name") 159 onMessageChange(monitor: IMonitor) { 160 console.log(`The book name change from ${monitor.value()?.before} to ${monitor.value()?.now}`); 161 } 162 163 textUpdate(): number{ 164 console.log("The text is update"); 165 return 25; 166 } 167 168 build() { 169 Column() { 170 Text(`The book name is ${this.bookTest.name}`).fontSize(this.textUpdate()) 171 Button('go to next page').fontSize(30) 172 .onClick(() => { 173 router.pushUrl({ url: 'pages/Page2' }); 174 setTimeout(() => { 175 this.bookTest = new Book("Jane Austen oPride and Prejudice"); 176 }, 1000); 177 }) 178 } 179 } 180} 181``` 182 183页面2: 184 185```ts 186// Page2.ets 187import { router } from '@kit.ArkUI'; 188 189@Entry 190@ComponentV2 191struct Page2 { 192 build() { 193 Column() { 194 Text(`This is the page`).fontSize(50) 195 Button('Back') 196 .onClick(() => { 197 router.back(); 198 }) 199 } 200 } 201} 202``` 203 204当子组件Child不使用组件冻结功能时,跳转到页面2,修改状态变量将响应更新,@Monitor被调用,状态变量关联的节点将会刷新。 205 206 207## cl.arkui.2 当AttributeModifer的applyNormalAttribute方法中instance参数设置为资源类型数据时更新的行为发生变更 208 209**访问级别** 210 211公开接口 212 213**变更原因** 214 215当开发者使用资源文件作为AttributeModifer的applyNormalAttribute方法中instance对象的入参时,无法通过配置资源文件更新参数,该行为与系统资源的规格不一致。 216 217**变更影响** 218 219该变更为不兼容变更。 220 221运行以下示例时: 222 223```ts 224class MyButtonModifier implements AttributeModifier<ButtonAttribute> { 225 private color?: ResourceColor; 226 private fontColor?: ResourceColor; 227 228 constructor(color: ResourceColor, fontColor: ResourceColor) { 229 this.color = color; 230 this.fontColor = fontColor; 231 } 232 233 applyNormalAttribute(instance: ButtonAttribute): void { 234 // instance为Button的属性对象,设置正常状态下属性值 235 instance.backgroundColor(this.color) 236 .fontColor(this.fontColor) 237 .borderWidth(1) 238 } 239} 240 241@Entry 242@Component 243struct attributeDemo { 244 @State modifier: MyButtonModifier = new MyButtonModifier($r('app.color.backColor'), $r('app.color.fontColor')); 245 246 build() { 247 Row() { 248 Column() { 249 Button("Button") 250 .attributeModifier(this.modifier) 251 }.width("100%") 252 } 253 .height('100%') 254 .backgroundColor(Color.White) 255 } 256} 257``` 258 259```json 260// src/main/resources/base/element/color.json 261{ 262 "color": [ 263 { 264 "name": "start_window_background", 265 "value": "#FFFFFF" 266 }, 267 { 268 "name": "backColor", 269 "value": "#000000" 270 }, 271 { 272 "name": "fontColor", 273 "value": "#FFFFFF" 274 } 275 ] 276} 277``` 278 279```json 280// src/main/resources/dark/element/color.json 281{ 282 "color": [ 283 { 284 "name": "start_window_background", 285 "value": "#000000" 286 }, 287 { 288 "name": "backColor", 289 "value": "#FFFFFF" 290 }, 291 { 292 "name": "fontColor", 293 "value": "#000000" 294 } 295 ] 296} 297``` 298 299| 变更前 | 变更后 | 300| ------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------- | 301| 浅色模式拉起。<br> | 浅色模式拉起。<br> | 302| | 303| 切换深色时,无法使用资源文件触发UI的更新。<br> | 切换深色时,可以使用资源文件触发UI的更新。<br> | 304| | 305 306**起始API Level** 307 308API 11 309 310**变更发生版本** 311 312从OpenHarmony SDK 5.0.0.56开始。 313 314**变更的接口/组件** 315 316common.d.ts文件attributeModifier接口。 317 318**适配指导** 319 320默认行为变更,无需适配,但应注意变更后的行为是否对整体应用逻辑产生影响。 321 322如不期望资源随配置文件更新可以将资源取出后使用。 323 324```ts 325class MyButtonModifier implements AttributeModifier<ButtonAttribute> { 326 public color?: ResourceColor; 327 public fontColor?: ResourceColor; 328 329 constructor(color: ResourceColor, fontColor: ResourceColor) { 330 this.color = color; 331 this.fontColor = fontColor; 332 } 333 334 applyNormalAttribute(instance: ButtonAttribute): void { 335 // instance为Button的属性对象,设置正常状态下属性值 336 instance.backgroundColor(this.color) 337 .fontColor(this.fontColor) 338 .borderWidth(1) 339 } 340} 341 342@Entry 343@Component 344struct attributeDemo { 345 @State modifier: MyButtonModifier = new MyButtonModifier($r('app.color.backColor'), $r('app.color.fontColor')); 346 347 aboutToAppear(): void { 348 // 解析获取资源文件。 349 this.modifier.color = getContext().resourceManager.getColorSync($r('app.color.backColor').id); 350 this.modifier.fontColor = getContext().resourceManager.getColorSync($r('app.color.fontColor').id); 351 } 352 353 build() { 354 Row() { 355 Column() { 356 Button("Button") 357 .attributeModifier(this.modifier) 358 }.width("100%") 359 } 360 .height('100%') 361 .backgroundColor(Color.White) 362 } 363} 364``` 365 366| 变更前 | 变更后 | 367| -------------------------------------------------------- | ------------------------------------------------------ | 368| 浅色模式拉起。<br> | 深色模式拉起。<br> | 369| 切换深色。<br> | 切换浅色。<br> | 370 371## cl.arkui.3 废弃gridSpan和gridOffset属性 372**访问级别** 373 374公开接口 375 376**废弃原因** 377 378gridSpan和gridOffset属性仅设置在gridContaier的子组件上有效,gridContainer组件已废弃。 379 380**废弃影响** 381 382该变更为接口废弃,开发者需使用替代接口。 383 384**废弃发生版本** 385 386从OpenHarmony SDK 5.0.0.56开始。 387 388**废弃的接口/组件** 389 390| 废弃接口 | 替代接口 | 391| :---------------------------: | :----------------------------------------: | 392| gridSpan(value: number): T; | GridCol(option?: GridColOptions)中的span | 393| gridOffset(value: number): T; | GridCol(option?: GridColOptions)中的offset | 394 395**适配指导** 396 397废弃前使用gridSpan、gridOffset属性的栅格。 398 399```ts 400// xxx.ets 401@Entry 402@Component 403struct GridContainerExample1 { 404 build() { 405 Column() { 406 Text('gridSpan,gridOffset').fontSize(15).fontColor(0xCCCCCC).width('90%') 407 GridContainer() { 408 Row() { 409 Row() { 410 Text('Left').fontSize(25) 411 } 412 .gridSpan(1) 413 .height("100%") 414 .backgroundColor(0x66bbb2cb) 415 416 Row() { 417 Text('Center').fontSize(25) 418 } 419 .gridSpan(2) 420 .gridOffset(1) 421 .height("100%") 422 .backgroundColor(0x66b6c5d1) 423 424 Row() { 425 Text('Right').fontSize(25) 426 } 427 .gridSpan(1) 428 .gridOffset(3) 429 .height("100%") 430 .backgroundColor(0x66bbb2cb) 431 }.height(200) 432 } 433 } 434 } 435} 436``` 437 438使用GridRow容器,并且子组件为GridCol。GridCol构造中设置span(对应废弃的gridSpan)、offset(对应废弃的gridOffset)属性的栅格。 439```ts 440// xxx.ets 441@Entry 442@Component 443struct GridRowExample { 444 @State bgColors: Color[] = [Color.Red, Color.Orange, Color.Yellow, Color.Green, Color.Pink, Color.Grey, Color.Blue, Color.Brown] 445 @State currentBp: string = 'unknown' 446 447 build() { 448 Column() { 449 GridRow({ 450 columns: 5, 451 gutter: { x: 5, y: 10 }, 452 breakpoints: { value: ["400vp", "600vp", "800vp"], 453 reference: BreakpointsReference.WindowSize }, 454 direction: GridRowDirection.Row 455 }) { 456 GridCol({ span: { xs: 1, sm: 2, md: 3, lg: 4 }, offset: 0, order: 0 }) { 457 Text('Left').fontSize(25) 458 }.borderColor(color).borderWidth(2) 459 GridCol({ span: { xs: 1, sm: 2, md: 3, lg: 4 }, offset: 1, order: 0 }) { 460 TText('Center').fontSize(25) 461 }.borderColor(color).borderWidth(2) 462 GridCol({ span: { xs: 1, sm: 2, md: 3, lg: 4 }, offset: 2, order: 0 }) { 463 Text('Right').fontSize(25) 464 }.borderColor(color).borderWidth(2) 465 }.width("100%").height("100%") 466 .onBreakpointChange((breakpoint) => { 467 this.currentBp = breakpoint 468 }) 469 }.width('80%').margin({ left: 10, top: 5, bottom: 5 }).height(200) 470 .border({ color: '#880606', width: 2 }) 471 } 472} 473``` 474 475## cl.arkui.4 Chip与ChipGroup组件布局重构 476 477**访问级别** 478 479公开接口 480 481**变更原因** 482 483原来的布局逻辑未考虑像素取整情况,导致部分界面显示异常。因此发起布局重构,重构后会因为像素取整导致组件的整体宽度可能差1px。 484 485**变更影响** 486 487该变更为不兼容变更。 488 489| 变更前 | 变更后 | 490| -------------------------------------------------------------------------- | ---------------------------------------------------------------------- | 491| 组件布局过程中不会进行像素取整 <br> | 组件布局过程中会进行像素取整<br> | 492 493变更后可能影响自动化UI测试结果,产生像素级偏差。 494 495**起始API Level** 496 497API 12 498 499**变更发生版本** 500 501从OpenHarmony SDK 5.0.0.56开始。 502 503**变更的接口/组件** 504 505Chip与ChipGroup组件。 506 507**适配指导** 508 509默认效果变更,无需适配,但应注意变更后的默认效果是否符合开发者预期,如不符合则应自定义修改效果控制变量以达到预期。 510 511