文档管理中心
问题处理与运维开发与测试问题多设备场景一次开发多端部署折叠屏展开态直接打开应用与折叠后再打开应用字体大小不一致

折叠屏展开态直接打开应用与折叠后再打开应用字体大小不一致

问题现象

折叠屏展开态打开应用和折叠态打开应用再展开,字体大小不一致。

背景知识

  • @State装饰器:被@State装饰的变量称为状态变量,使普通变量具备状态属性。当状态变量改变时,会触发其直接绑定的UI组件渲染更新。
  • 断点开发:可以将窗口宽度及窗口高宽比划分为不同的范围,称之为“断点”。当窗口宽度及窗口高宽比从一个断点变化到另一个断点时,改变页面布局(如将页面内容从单列排布调整为双列排布甚至三列排布等)以获得更好的显示效果。
  • on('windowSizeChange'):可监听窗口尺寸的变化,进行对应的回调操作。

问题定位

  1. 排查页面代码中,文本字体大小是否是状态变量,以及初始化信息,例如下面代码。
    收起
    自动换行
    深色代码主题
    复制
    1. @State textFontSize: Resource | number | string = 15
  2. 排查代码中,是否调用on('windowSizeChange')接口监听窗口的变化修改全局状态变量中的断点信息,例如下面代码。
    收起
    自动换行
    深色代码主题
    复制
    1. windowClass.on('windowSizeChange', (data) => {
    2. let uiContext: UIContext = windowClass.getUIContext()
    3. let widthBp: WidthBreakpoint = uiContext.getWindowWidthBreakpoint();
    4. AppStorage.setOrCreate('widthBp',widthBp)
    5. })
  3. 排查代码中文本字体是否进行了断点适配,并判断md下的值与初始化的值是否相等,例如下面代码。
    收起
    自动换行
    深色代码主题
    复制
    1. // 三个值分别代表sm、md、lg下的值
    2. this.theFontSize = new BreakpointType('14fp', '16fp', '18fp').getValue(widthBp)

分析结论

应用在折叠屏展开态页面初始化时的字体大小与md断点下的值不一致,导致折叠屏展开态打开应用和折叠态打开应用再展开,字体大小不一致。

修改建议

修改代码中页面字体大小初始化逻辑,保证页面字体大小初始化时的值与对应断点下的值一致,这样就能保证折叠屏展开态打开应用和折叠态打开应用再展开,字体大小一致,代码样例如下。

收起
自动换行
深色代码主题
复制
  1. import { window } from '@kit.ArkUI';
  2. import { common } from '@kit.AbilityKit';
  3. export class WidthBreakpointType<T> {
  4. sm: T;
  5. md: T;
  6. lg: T;
  7. constructor(sm: T, md: T, lg: T) {
  8. this.sm = sm;
  9. this.md = md;
  10. this.lg = lg;
  11. }
  12. getValue(widthBp: WidthBreakpoint): T {
  13. if (widthBp === WidthBreakpoint.WIDTH_XS || widthBp === WidthBreakpoint.WIDTH_SM) {
  14. return this.sm;
  15. }
  16. if (widthBp === WidthBreakpoint.WIDTH_MD) {
  17. return this.md;
  18. } else {
  19. return this.lg;
  20. }
  21. }
  22. }
  23. @Entry
  24. @Component
  25. struct TextSizePage {
  26. private message: string = 'Hello World';
  27. // 页面字体大小默认值
  28. @State theFontSize: Resource | number | string = 16;
  29. @StorageProp('widthBp') widthBp: WidthBreakpoint | undefined = AppStorage.get('widthBp');
  30. getWindow(): window.Window {
  31. let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
  32. let windowStage = context.windowStage;
  33. let windowClass = windowStage.getMainWindowSync();
  34. return windowClass;
  35. }
  36. aboutToAppear(): void {
  37. // 按断点类型初始化页面字体大小
  38. if (this.widthBp) {
  39. this.theFontSize = new WidthBreakpointType('10fp', '16fp', '22fp').getValue(this.widthBp);
  40. }
  41. let windowClass: window.Window = this.getWindow();
  42. // 监听窗口尺寸的变化
  43. windowClass.on('windowSizeChange', () => {
  44. let uiContext: UIContext = windowClass.getUIContext();
  45. let widthBp: WidthBreakpoint = uiContext.getWindowWidthBreakpoint();
  46. // 改变应用全局状态变量中widthBp
  47. AppStorage.setOrCreate('widthBp', widthBp);
  48. // 根据窗口变化后的断点,改变页面字体大小
  49. if (this.widthBp) {
  50. this.theFontSize = new WidthBreakpointType('16fp', '22fp', '26fp').getValue(this.widthBp);
  51. }
  52. });
  53. }
  54. build() {
  55. RelativeContainer() {
  56. Text(this.message)
  57. .id('TextSizePageHelloWorld')
  58. .fontSize(this.theFontSize)
  59. .fontWeight(FontWeight.Bold)
  60. .alignRules({
  61. center: { anchor: '__container__', align: VerticalAlign.Center },
  62. middle: { anchor: '__container__', align: HorizontalAlign.Center }
  63. });
  64. }
  65. .height('100%')
  66. .width('100%');
  67. }
  68. }