1# ArkUI子系统Changelog
2
3## cl.arkui.1 @Component和@ComponentV2修饰的自定义组件使用@Observed或者@ObservedV2修饰的类增加相关校验
4
5**访问级别**
6
7公开接口
8
9**变更原因**
10
11该变更为不兼容变更。
12
131.在@Component修饰的自定义组件中通过@State、@Prop、@Link、@Provide、@Consume、@StorageLink、@StorageProp、LocalStorageLink、@LocalStorageProp修饰并使用@ObservedV2修饰的变量类型时,进行校验并输出错误信息。
14
15简化示例如下:
16
17```ts
18@ObservedV2
19class TmpA{}
20
21@Entry
22@Component
23struct testTmp {
24  @State value_string: TmpA = new TmpA()
25  build() {
26    Column(){
27
28    }
29  }
30}
31```
32
332.在@ComponentV2修饰的自定义组件中通过@Param、@Local、@Event、@Provider()、@Consumer()修饰并使用@Observed修饰的类时,进行校验并输出错误信息。
34
35简化示例如下:
36
37```ts
38@Observed
39class TmpA{}
40
41@Entry
42@ComponentV2
43struct testTmp {
44  @Param value_string: TmpA = new TmpA()
45  build() {
46    Column(){
47
48    }
49  }
50}
51```
52
533.以上的变量类型联合使用时,也会进行校验并输出错误信息。
54
55示例如下:
56
57```ts
58@ObservedV2
59class TmpA{}
60
61@Observed
62class TmpB{}
63
64@Entry
65@Component
66struct testTmp {
67  @State value_string: TmpA | TmpB = new TmpA()
68  build() {
69    Column(){
70
71    }
72  }
73}
74```
75
76**变更影响**
77
78变更前无报错。
79
80变更后报错:
81
821.The type of the @State property can not be a class decorated with @ObservedV2.
83
842.The type of the @Param property can not be a class decorated with @Observed.
85
863.The type of the @State property can not be a class decorated with @ObservedV2.
87
88**起始API Level**
89
90不涉及API变更
91
92**变更发生版本**
93
94从OpenHarmony SDK 5.0.0.31开始。
95
96**适配指导**
97
98如果开发者不按规范使用对应范式,则需按日志提示信息进行修改。
99
100## cl.arkui.2 bindContentCover动效参数变更
101
102**访问级别**
103
104公开接口
105
106**变更原因**
107
108为满足应用述求和UX规格,全模态动效参数改为与半模态一致。
109
110**变更影响**
111
112该变更为不兼容变更。
113
114变更前,全模态动效参数为interpolatingSpring(velocity:n, mass:1, stiffness:100, damping:20),动效时长约为1200ms。
115
116变更后,全模态动效参数为interpolatingSpring(velocity:n, mass:1, stiffness:328, damping:36),动效时长约为800ms。
117
118**起始API Level**
119
12011
121
122**变更发生版本**
123
124从OpenHarmony SDK 5.0.0.31开始。
125
126**变更的接口/组件**
127
128bindContentCover组件
129
130**适配指导**
131
132默认行为变更,无需适配,但应注意变更后的默认效果是否符合开发者预期,如不符合则自定义修改效果控制变量以达到预期,可通过[transition](../../../application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-modal-transition.md#contentcoveroptions)接口自定义动效。
133
134## cl.arkui.3 @ohos.arkui.advanced.SubHeader删除SymbolRenderingStrategy和SymbolEffectStrategy。
135
136**访问级别**
137
138公开接口
139
140**变更原因**
141
142SymbolGlyph中已定义SymbolRenderingStrategy和SymbolEffectStrategy,避免重复枚举定义。减少开发者引用工作量。
143
144**变更影响**
145
146该变更为不兼容变更。
147
148变更前,引用@ohos.arkui.advanced.SubHeader中SymbolRenderingStrategy和SymbolEffectStrategy,运行时报错:
149
1501.Eerror message:the requested module '@ohos.arkui.advanced.SubHeader' does not provide an export name 'SymbolRenderingStrategy' and 'SymbolEffectStrategy'.
151
152变更后,引用@ohos.arkui.advanced.SubHeader中SymbolRenderingStrategy和SymbolEffectStrategy,编译期报错:
153
1541.Module '@ohos.arkui.advanced.SubHeader' has no exported member 'SymbolRenderingStrategy' and 'SymbolEffectStrategy'.
155
156**起始API Level**
157
15812
159
160**变更发生版本**
161
162从OpenHarmony SDK 5.0.0.31开始。
163
164**适配指导**
165
166如果开发者不按规范使用对应范式,则需按编译提示信息进行修改。参考API文档,删除引用SubHeader中SymbolRenderingStrategy和SymbolEffectStrategy,自动引用SymbolGlyph中SymbolRenderingStrategy和SymbolEffectStrategy。
167适配示例:
168
169```ts
170import { promptAction, OperationType, SubHeader } from '@kit.ArkUI'
171
172@Entry
173@Component
174struct SubHeaderExample {
175  build() {
176    Column() {
177      SubHeader({
178        icon: $r('sys.symbol.ohos_wifi'),
179        iconSymbolOptions: {
180          effectStrategy: SymbolEffectStrategy.HIERARCHICAL,
181          renderingStrategy: SymbolRenderingStrategy.MULTIPLE_COLOR,
182          fontColor: [Color.Blue, Color.Grey, Color.Green],
183        },
184        secondaryTitle: '标题',
185        operationType: OperationType.BUTTON,
186        operationItem: [{ value: '操作',
187          action: () => {
188            promptAction.showToast({ message: 'demo' })
189          }
190        }]
191      })
192    }
193  }
194}
195```
196
197## cl.arkui.4 bindSheet支持嵌套滚动
198
199**访问级别**
200
201公开接口
202
203**变更原因**
204
205为满足应用诉求,半模态面板嵌套滚动组件,且在滚动组件上设置嵌套模式时,需要实现联动效果。
206
207**变更影响**
208
209该变更为不兼容变更。
210
211单挡位模式下半模态仅可设置一档高度。多挡位模式下半模态可以设置三档高度,内容位于半模态面板顶部时,通过上下滑动可以自由切换挡位。
212
213API version 12之前,半模态面板嵌套滚动组件,且在滚动组件上设置嵌套模式时,无法实现联动。内容位于顶部,多档位时上下滑动无法切换挡位,单挡位时下滑无法关闭半模态。
214
215API version 12及以后,半模态面板嵌套滚动组件,且在滚动组件上设置嵌套模式时,可以实现联动。内容位于顶部,多档位时上下滑动可以切换挡位;单挡位时下滑可以关闭半模态。
216
217在滚动组件上设置嵌套的情况下:
218| 多挡位变更前 | 多挡位变更后 |
219|---------|---------|
220| 无法通过上下滑动切换挡位,在最低档下滑无法关闭半模态<br>![Alt text](figures/NestedScroll_detents_Before.gif) |可以通过上下滑动切换挡位,在最低档下滑可以关闭半模态<br>![Alt text](figures/NestedScroll_detents_After.gif)|
221
222| 单挡位变更前 | 单挡位变更后 |
223|---------|---------|
224| 无法通过下滑关闭半模态<br>![Alt text](figures/NestedScroll_Before.gif) |可以通过下滑关闭半模态<br>![Alt text](figures/NestedScroll_After.gif) |
225
226**起始API Level**
227
22811
229
230**变更发生版本**
231
232从OpenHarmony SDK 5.0.0.31开始。
233
234**变更的接口/组件**
235
236bindSheet组件
237
238**适配指导**
239
240需要开发者主动适配。例如,在半模态面板中嵌套List组件场景,@Builder内容可以参考如下示例。
241
242```ts
243private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
244@Builder
245myBuilder() {
246  Column() {
247    List({ space: 20, initialIndex: 0 }) {
248        ForEach(this.arr, (item: number) => {
249          ListItem() {
250            Text('' + item)
251              .width('100%')
252              .height(100)
253              .fontSize(16)
254              .textAlign(TextAlign.Center)
255              .borderRadius(10)
256              .backgroundColor(0xFFFFFF)
257          }
258        }, (item: string) => item)
259      }
260      .listDirection(Axis.Vertical) // 排列方向
261      .edgeEffect(EdgeEffect.None)
262      .nestedScroll({
263        scrollForward: NestedScrollMode.PARENT_FIRST,
264        scrollBackward: NestedScrollMode.SELF_FIRST
265      }) // 嵌套模式
266      .backgroundColor(Color.Gray)
267      .width('90%')
268      .height('100%')
269  }
270}
271```
272
273## cl.arkui.5 RichEditor长按交互调整
274
275**访问级别**
276
277公开接口
278
279**变更原因**
280
281为满足应用述求和UX规格,RichEditor组件长按交互效果需要进行调整。
282
283**变更影响**
284
285该变更为不兼容性变更。
286
287变更前,长按文本内容,直接触发选词,展示选中背板、手柄以及文本选择菜单。
288
289变更后,长按文本内容不松手,触发选词并展示选中背板,继续拖动变更选中区域,松手后展示手柄及文本选择菜单。如果不继续拖动,则松手时直接展示手柄和文本选择菜单。
290| 变更前                                 | 变更后                               |
291| -------------------------------------- | ------------------------------------ |
292| ![alt text](RichEditor_LongPress_Before.gif) | ![alt text](RichEditor_LongPress_After.gif) |
293
294**起始API Level**
295
296不涉及API变更
297
298**变更发生版本**
299
300从OpenHarmony SDK 5.0.0.31开始。
301
302**变更的接口/组件**
303
304RichEditor组件
305
306**适配指导**
307
308默认行为变更,无需适配,但应注意变更后的默认效果是否符合开发者预期,如不符合则自定义修改事件效果以达到预期。
309
310## cl.arkui.6 TextTimer的onTimer回调频率与参数单位调整
311
312**访问级别**
313
314公开接口
315
316**变更原因**
317
318调整onTimer回调频率与参数的单位,使其符合文档描述。
319
320**变更影响**
321
322该变更为不兼容性变更。
323
324TextTimer的format属性用于自定义时间格式。其中,毫秒可使用S、SS和SSS关键字表示,分别代表100ms、10ms和1ms。
325
326变更前,当TextTimer的format属性包含毫秒时,TextTimer的文本发生变化,便会几毫秒触发一次onTimer事件,且回调参数utc和elapsedTime的单位为毫秒。
327
328变更后,TextTimer的文本发生变化时,onTimer事件的触发时间与回调参数utc和elapsedTime的单位随format属性的自定义时间格式变化。format为mm:ss.S时,100ms回调一次onTimer事件,回调参数的单位为100ms。format为mm:ss.SS时,10ms回调一次onTimer事件,回调参数的单位为10ms。format为mm:ss.SSS时,与变更前保持一致。
329
330**起始API Level**
331
33211
333
334**变更发生版本**
335
336从OpenHarmony SDK 5.0.0.31开始。
337
338**变更的接口/组件**
339
340textTimer组件的onTimer接口
341
342**适配指导**
343
344需要开发者主动适配,调整回调参数的数量级。
345
346```ts
347@Entry
348@Component
349struct TextTimerExample {
350  textTimerController: TextTimerController = new TextTimerController();
351  build() {
352    Column(){
353      TextTimer({isCountDown: true, count: 30000, controller: this.textTimerController})
354        .format('mm:ss.SS')
355        .fontSize(50)
356        .onTimer((utc: number, elapsedTime: number) => {
357          // 如果开发者需改回变更前的效果,可以将utc、elapsedTime乘10
358          console.info('textTimer countDown utc is:' + utc * 10 + ',elapsedTime is:' + elapsedTime * 10)
359        })
360
361      TextTimer({isCountDown: true, count: 30000, controller: this.textTimerController})
362        .format('mm:ss.S')
363        .fontSize(50)
364        .onTimer((utc: number, elapsedTime: number) => {
365          // 如果开发者需改回变更前的效果,可以将utc、elapsedTime乘100
366          console.info('textTimer countDown utc is:' + utc * 100 + ',elapsedTime is:' + elapsedTime * 100)
367        })
368    }
369  }
370}
371```
372
373## cl.arkui.7 滚动类组件(List、Grid、WaterFlow、Scroll)Friction接口默认值变更
374
375**访问级别**
376
377公开接口
378
379**变更原因**
380
381为了优化功耗,将滚动类组件(List、Grid、WaterFlow、Scroll)friction接口默认值改为0.75。
382
383**变更影响**
384
385该变更为不兼容变更。
386
387变更前,滚动类组件(List、Grid、WaterFlow、Scroll)的friction接口默认值为0.7。
388
389变更后,滚动类组件(List、Grid、WaterFlow、Scroll)的friction接口默认值为0.75。相较变更之前,用同样力度抛滑,抛滑时间更短、抛滑距离更近。
390
391**起始API Level**
392
39310
394
395**变更发生版本**
396
397从OpenHarmony SDK 5.0.0.31开始。
398
399**变更的接口/组件**
400
401滚动类组件(List、Grid、WaterFlow、Scroll)的friction接口。
402
403**适配指导**
404
405开发者如果需要使用变更之前的抛滑效果,可以将friction接口的参数设置为0.7。
406
407```ts
408@Entry
409@Component
410struct FrictionExample {
411  build() {
412    List() {
413      ForEach([1, 2, 3, 4, 5], (item: number) => {
414        ListItem() {
415          Text('' + item)
416            .width('100%').height(200).fontSize(16)
417            .textAlign(TextAlign.Center).borderRadius(10).backgroundColor(0xFFFFFF)
418        }
419      }, (item: string) => item)
420    }
421    .height(500)
422    .friction(0.7)
423  }
424}
425```
426## cl.arkui.8 ListItem卡片样式行为变更
427
428**访问级别**
429
430公开接口
431
432**变更原因**
433
434原本ListItem在LazyForEach下使用时,ListItem设置卡片样式不生效,需要整该为能够生效。
435
436**变更影响**
437
438该变更为不兼容变更。
439
440变更前:ListItem在LazyForEach下使用时,卡片样式设置不生效。<br>变更后:ListItem在LazyForEach下使用时,卡片样式设置可以生效。
441
442```ts
443// Basic implementation of IDataSource to handle data listener
444abstract class BasicDataSource<T> implements IDataSource {
445  private listeners: DataChangeListener[] = []
446
447  public totalCount(): number {
448    return 0
449  }
450  abstract getData(index: number): T;
451
452  registerDataChangeListener(listener: DataChangeListener): void {
453    if (this.listeners.indexOf(listener) < 0) {
454      this.listeners.push(listener)
455    }
456  }
457  unregisterDataChangeListener(listener: DataChangeListener): void {
458   const pos = this.listeners.indexOf(listener);
459   if (pos >= 0) {
460     this.listeners.splice(pos, 1)
461   }
462  }
463
464  notifyDataReload(): void {
465    this.listeners.forEach(listener => {
466      listener.onDataReloaded()
467    })
468  }
469  notifyDataAdd(index: number): void {
470    this.listeners.forEach(listener => {
471      listener.onDataAdd(index)
472    })
473  }
474  notifyDataChange(index: number): void {
475    this.listeners.forEach(listener => {
476      listener.onDataChange(index)
477    })
478  }
479  notifyDataDelete(index: number): void {
480    this.listeners.forEach(listener => {
481      listener.onDataDelete(index)
482    })
483  }
484  notifyDataMove(from: number, to: number): void {
485    this.listeners.forEach(listener => {
486      listener.onDataMove(from, to)
487    })
488  }
489}
490
491class MyDataSource<T> extends BasicDataSource<T> {
492  public dataArray: T[] = [];
493
494  public totalCount(): number {
495    return this.dataArray.length
496  }
497  public getData(index: number): T {
498    return this.dataArray[index]
499  }
500
501  public addData(index: number, data: T): void {
502    this.dataArray.splice(index, 0, data)
503    this.notifyDataAdd(index)
504  }
505  public popFirstData(): void {
506    this.dataArray.shift()
507    this.notifyDataDelete(0)
508  }
509  public pushData(data: T): void {
510    this.dataArray.push(data)
511    this.notifyDataAdd(this.dataArray.length - 1)
512  }
513  public popData(): void {
514    this.dataArray.pop()
515    this.notifyDataDelete(this.dataArray.length)
516  }
517}
518
519@Entry
520@Component
521struct Index {
522  arr:MyDataSource<number> = new MyDataSource<number>();
523  aboutToAppear(): void {
524    for (let i = 0; i < 10; i++) {
525      this.arr.pushData(i)
526    }
527  }
528
529  build() {
530    List() {
531      ListItemGroup({ style: ListItemGroupStyle.CARD }) {
532        LazyForEach(this.arr, (item: number) => {
533          ListItem({ style: ListItemStyle.CARD }) {
534            Text("item" + item.toString())
535          }
536        })
537      }
538    }.backgroundColor("#DCDCDC")
539    .height("100%")
540  }
541}
542```
543| 变更前效果 | 变更后效果 |
544| ---- | ---- |
545| ![](./figures/list_item_card_style_before.png) | ![](./figures/list_item_card_style_after.png) |
546
547**起始API Level**
548
54910
550
551**变更发生版本**
552
553从OpenHarmony SDK 5.0.0.31 版本开始。
554
555**变更的接口/组件**
556
557涉及的组件:ListItem组件ListItemStyle接口。
558
559**适配指导**
560
561如果ListItem在LazyForEach下使用,设置了卡片样式没有生效,变更后生效卡片样式导致显示界面变化,可以删除卡片样式的设置。
562
563如下代码变更前设置卡片样式不生效,变更后生效卡片样式导致显示界面变化。
564```ts
565build() {
566  List() {
567    ListItemGroup({ style: ListItemGroupStyle.CARD }) {
568      LazyForEach(this.arr, (item: number) => {
569        ListItem({ style: ListItemStyle.CARD }) {
570          Text("item" + item.toString())
571            .height(64)
572        }
573      })
574    }
575  }.backgroundColor("#DCDCDC")
576  .height("100%")
577}
578```
579删除ListItem卡片样式可以恢复变更前效果。
580```ts
581build() {
582  List() {
583    ListItemGroup({ style: ListItemGroupStyle.CARD }) {
584      LazyForEach(this.arr, (item: number) => {
585        ListItem() {
586          Text("item" + item.toString())
587            .height(64)
588        }
589      })
590    }
591  }.backgroundColor("#DCDCDC")
592  .height("100%")
593}
594```