1# arkui子系统ChangeLog 2 3 4## cl.arkui.1 编译拦截@Extend/@AnimatableExtend参数个数不符合预期 5 6@Extend/@AnimatableExtend装饰器参数有且仅能有一个。 7 8**变更影响** 9 10当@Extend/@AnimatableExtend装饰器参数有多个时,编译报错。 11 12**错误示例:** 13 14```ts 15// xxx.ets 16 17@Extend(Text, Button) // 编译报错: @Extend should have one and only one parameter 18function fancy() { 19 .width(100) 20} 21 22@AnimatableExtend(Text, Polyline) // 编译报错: @AnimatableExtend should have one and only one parameter 23function fancy2() { 24 .height(100) 25} 26 27@Entry 28@Component 29struct Example { 30 build() { 31 Column() { 32 Text('text') 33 .fancy() 34 .fancy2() 35 } 36 } 37} 38``` 39 40**关键接口/组件变更** 41 42不涉及 43 44**适配指导** 45 46@Extend和AnimatableExtend装饰器仅能传一个参数。 47 48参考代码如下: 49```ts 50// xxx.ets 51 52@Extend(Text) 53function fancy() { 54 .width(100) 55} 56 57@AnimatableExtend(Text) 58function fancy2() { 59 .height(100) 60} 61 62@Entry 63@Component 64struct Example { 65 build() { 66 Column() { 67 Text('text') 68 .fancy() 69 .fancy2() 70 } 71 } 72} 73``` 74 75## cl.arkui.2 编译拦截@Link/@ObjectLink成员变量未从父组件传值 76 77子组件的@Link/@ObjectLink成员变量需要从父组件传值。 78 79**变更影响** 80 81子组件的@Link/@ObjectLink当没有从父组件传值时,编译报错。 82 83**错误示例:** 84 85```ts 86// xxx.ets 87 88@Observed 89class Count { 90 message: string = 'count' 91} 92 93@Entry 94@Component 95struct Parent { 96 @State state1: string = 'state1'; 97 @State state2: Count = new Count(); 98 build() { 99 Column() { 100 Child() // 编译报错:Property 'link' in the custom component 'Child' is missing (mandatory to specify). 101 // 编译报错:Property 'objectLink' in the custom component 'Child' is missing (mandatory to specify). 102 } 103 } 104} 105 106@Component 107struct Child { 108 @Link link: string; 109 @ObjectLink objectLink: Count; 110 build() { 111 Column() { 112 Text(this.link) 113 .fontSize(50) 114 Text(this.objectLink.message) 115 .fontSize(50) 116 } 117 } 118} 119``` 120 121**关键接口/组件变更** 122 123不涉及 124 125**适配指导** 126 127子组件的@Link/@ObjectLink成员变量需要从父组件传值。 128 129参考代码如下: 130```ts 131// xxx.ets 132 133@Observed 134class Count { 135 message: string = 'count' 136} 137 138@Entry 139@Component 140struct Parent { 141 @State state1: string = 'state1'; 142 @State state2: Count = new Count(); 143 build() { 144 Column() { 145 Child({link: $state1, objectLink: this.state2}) 146 } 147 } 148} 149 150@Component 151struct Child { 152 @Link link: string; 153 @ObjectLink objectLink: Count; 154 build() { 155 Column() { 156 Text(this.link) 157 .fontSize(50) 158 Text(this.objectLink.message) 159 .fontSize(50) 160 } 161 } 162} 163``` 164## cl.arkui.3 canvas组件onReady事件行为变更 165 166**说明** 167onReady事件在组件创建完成后或组件大小发生变化时触发,并清空画布。 168 169**示例:** 170```ts 171@Entry 172@Component 173struct OnReadyDiff { 174 @State message: string = 'init ' 175 @State isShow: boolean = false 176 @State myHeight: number = 300 177 private settings: RenderingContextSettings = new RenderingContextSettings(true); 178 private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); 179 180 build() { 181 Row() { 182 Column() { 183 Text(this.message) 184 .fontSize(50) 185 .fontWeight(FontWeight.Bold) 186 Button('ChangePosition') 187 .onClick(()=>{ 188 this.isShow = !this.isShow 189 }) 190 if (this.isShow) { 191 Button('new button') 192 .height(200) 193 } 194 Button('ChangeHeight') 195 .onClick(()=>{ 196 this.myHeight = this.myHeight==300?500:300 197 }) 198 199 Canvas(this.context) 200 .width(300) 201 .height(this.myHeight) 202 .backgroundColor('#ffff00') 203 .onReady(() =>{ 204 this.context.fillRect(0, 0, 100, 100) 205 this.message += 'a ' 206 }) 207 Button('draw another') 208 .onClick(()=>{ 209 this.context.fillRect(100, 100, 100, 100) 210 }) 211 } 212 .width('100%') 213 } 214 .height('100%') 215 } 216} 217``` 218 219API version 9:onReady在组件创建完成时触发,位置变化时会触发,组件大小变化时也会触发。 220 221 222 223API version 10及以后:onReady在组件创建完成时触发,在组件位置变化时不会触发,组件大小变化时会触发。 224 225 226 227**变更影响** 228 229onReady事件在组件位置发生变化时行为变更,API version 9及以前会触发,API version 10及以后不会触发。 230 231## cl.arkui.4 Margin属性百分比计算变更 232 233当前margin会计算两次,margin的百分比参照在第一次margin计算之后会减去margin的大小,计算完之后百分比类型margin第二次计算时数值偏小。变更后margin第一次计算的结果为最终值,不进行第二次计算。 234 235**变更影响** 236 237所有设置百分比的margin大小。 238 239**错误示例:** 240 241```ts 242// xxx.ets 243@Entry 244@Component 245struct TextInputExample { 246 @State text: string = '' 247 controller: TextInputController = new TextInputController() 248 249 build() { 250 Column(){ 251 Row().margin({left:"50%"}).width(100).height(100) 252 }.width("100%").height("100%") 253 } 254} 255``` 256 257**关键接口/组件变更** 258 259不涉及 260 261**适配指导** 262 263变更后margin的百分比参照固定为父组件的宽减去父组件的padding且不会减去第一次margin的计算结果,其百分比参照比变更前稍大,建议调整margin百分比的数值。 264 265## cl.arkui.5 ListItem长距离划动接口修改 266 267将ListItem长距离划动接口SwipeActionItem命名中的“Delete”替换为“Action”,同时删除useDefaultDeleteAnimation接口。 268 269**变更影响** 270 271使用OpenHarmony_4.0.9.3以后的SDK版本编译时,需使用变更后接口。 272 273**关键接口/组件变更** 274 275| 变更前接口 | 变更后接口 | 276| ------ | ------------------------------ | 277| deleteAreaDistance | actionAreaDistance | 278| onDelete | onAction | 279| onEnterDeleteArea | onEnterActionArea | 280| onExitDeleteArea | onExitActionArea | 281| useDefaultDeleteAnimation | 删除 | 282 283**适配指导** 284 285在使用OpenHarmony_4.0.9.3及以后的SDK版本时,SwipeActionItem需使用变更后接口。OpenHarmony_4.0.9.2及之前版本,SwipeActionItem仍遵循变更前规则。 286 287参考代码如下: 288 289```ts 290// xxx.ets 291@Entry 292@Component 293struct ListItemExample2 { 294 @State message: string = 'Hello World' 295 @State arr: number[] = [0, 1, 2, 3, 4] 296 @State enterEndDeleteAreaString: string = "not enterEndDeleteArea" 297 @State exitEndDeleteAreaString: string = "not exitEndDeleteArea" 298 299 @Builder itemEnd() { 300 Row() { 301 Button("Delete").margin("4vp") 302 Button("Set").margin("4vp") 303 }.padding("4vp").justifyContent(FlexAlign.SpaceEvenly) 304 } 305 306 build() { 307 Column() { 308 List({ space: 10 }) { 309 ForEach(this.arr, (item) => { 310 ListItem() { 311 Text("item" + item) 312 .width('100%') 313 .height(100) 314 .fontSize(16) 315 .textAlign(TextAlign.Center) 316 .borderRadius(10) 317 .backgroundColor(0xFFFFFF) 318 } 319 .transition({ type: TransitionType.Delete, opacity: 0 }) 320 .swipeAction({ 321 end: { 322 builder: this.itemEnd.bind(this, item), 323 onAction: () => { 324 animateTo({ duration: 1000 }, () => { 325 let index = this.arr.indexOf(item) 326 this.arr.splice(index, 1) 327 }) 328 }, 329 actionAreaDistance: 80, 330 onEnterActionArea: () => { 331 this.enterEndDeleteAreaString = "enterEndDeleteArea" 332 this.exitEndDeleteAreaString = "not exitEndDeleteArea" 333 }, 334 onExitActionArea: () => { 335 this.enterEndDeleteAreaString = "not enterEndDeleteArea" 336 this.exitEndDeleteAreaString = "exitEndDeleteArea" 337 } 338 } 339 }) 340 }, item => item) 341 } 342 Text(this.enterEndDeleteAreaString).fontSize(20) 343 Text(this.exitEndDeleteAreaString).fontSize(20) 344 } 345 .padding(10) 346 .backgroundColor(0xDCDCDC) 347 .width('100%') 348 .height('100%') 349 } 350} 351```