• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 检查页面布局
2<!--Kit: ArkUI-->
3<!--Subsystem: ArkUI-->
4<!--Owner: @pengzhiwen3-->
5<!--Designer: @lmleon-->
6<!--Tester: @fredyuan0912-->
7<!--Adviser: @HelloCrease-->
8
9inspector用于检查页面布局,通过inspector双向定位功能帮助开发者在DevEco Studio中快速定位组件、修改属性和调试组件,以提高开发效率。
10
11ArkUI获取当前显示页面中所有组件的信息,包括组件树的父子结构、尺寸、位置、样式、属性和状态。获取组件树信息后,生成并展示为Inspector组件树。DevEco Studio的使用具体可以参考[Inspector调试能力](ui-inspector-profiler.md#inspector调试能力)。
12
13inspector针对UI组件的布局或绘制送显完成,还提供了注册与取消监听函数的C API接口,具体使用可以参考[监听组件布局和绘制送显事件](ndk-inspector-component-observer.md)。
14
15## 使用约束
16
171. 不支持动效类组件的控件树实时刷新功能。
18
192. 支持获取组件的属性和样式,但不支持获取controller和Builder对象。
20
213. 不支持获取组件的方法、事件。
22
23## UIContext查询组件树和组件信息能力
24
25ArkUI提供@ohos.arkui.UIContext(UIContext)扩展能力,通过[getFilteredInspectorTree](../reference/apis-arkui/arkts-apis-uicontext-uicontext.md#getfilteredinspectortree12)获取组件树及组件属性,通过[getFilteredInspectorTreeById](../reference/apis-arkui/arkts-apis-uicontext-uicontext.md#getfilteredinspectortreebyid12)获取指定的组件及其子组件的属性。支持设置过滤条件进行查询。
26
27下述示例,展示了getFilteredInspectorTree和getFilteredInspectorTreeById的基本用法。
28
29```ts
30import { UIContext } from '@kit.ArkUI';
31
32@Entry
33@Component
34struct ComponentPage {
35  loopConsole(inspectorStr: string, i: string) {
36    console.info(`InsTree ${i}| type: ${JSON.parse(inspectorStr).$type}, ID: ${JSON.parse(inspectorStr).$ID}`);
37    if (JSON.parse(inspectorStr).$children) {
38      i += '-';
39      for (let index = 0; index < JSON.parse(inspectorStr).$children.length; index++) {
40        this.loopConsole(JSON.stringify(JSON.parse(inspectorStr).$children[index]), i);
41      }
42    }
43  }
44
45  build() {
46    Column() {
47      Text("Hello World")
48        .fontSize(20)
49        .id("TEXT")
50      Button('content').onClick(() => {
51        const uiContext: UIContext = this.getUIContext();
52        let inspectorStr = uiContext.getFilteredInspectorTree(['content']);
53        console.info(`InsTree : ${inspectorStr}`);
54        inspectorStr = JSON.stringify(JSON.parse(inspectorStr));
55        this.loopConsole(inspectorStr, '-');
56      })
57      Button('isLayoutInspector').onClick(() => {
58        const uiContext: UIContext = this.getUIContext();
59        let inspectorStr = uiContext.getFilteredInspectorTree(['isLayoutInspector']);
60        console.info(`InsTree : ${inspectorStr}`);
61        inspectorStr = JSON.stringify(JSON.parse(inspectorStr).content);
62        this.loopConsole(inspectorStr, '-');
63      })
64      Button('getFilteredInspectorTreeById').onClick(() => {
65        const uiContext: UIContext = this.getUIContext();
66        try {
67          let inspectorStr = uiContext.getFilteredInspectorTreeById('TEXT', 1, ["id", "src"]);
68          console.info(`result1: ${inspectorStr}`);
69          inspectorStr = JSON.stringify(JSON.parse(inspectorStr)['$children'][0]);
70          console.info(`result2: ${inspectorStr}`);
71          inspectorStr = uiContext.getFilteredInspectorTreeById('TEXT', 1, ["src"]);
72          inspectorStr = JSON.stringify(JSON.parse(inspectorStr)['$children'][0]);
73          console.info(`result3: ${inspectorStr}`);
74        } catch(e) {
75          console.error(`getFilteredInspectorTreeById error: ${e}`);
76        }
77      })
78
79    }
80    .width('100%')
81    .height('100%')
82  }
83}
84```
85
86## 布局回调
87
88通过[@ohos.arkui.arkui.inspector(布局回调)](../reference/apis-arkui/js-apis-arkui-inspector.md)提供注册组件布局和组件绘制完成的回调通知能力。
89
90下述示例,展示了布局回调的基本用法。
91
92```ts
93import { inspector } from '@kit.ArkUI'
94
95@Entry
96@Component
97struct ImageExample {
98  build() {
99    Column() {
100      Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start }) {
101        Row({ space: 5 }) {
102          // 可以替换成本地存在的图片
103          Image($r('app.media.startIcon'))
104            .width(110)
105            .height(110)
106            .border({ width: 1 })
107            .id('IMAGE_ID')
108        }
109      }
110    }.height(320).width(360).padding({ right: 10, top: 10 })
111  }
112
113  listener:inspector.ComponentObserver = this.getUIContext().getUIInspector().createComponentObserver('IMAGE_ID')
114
115  aboutToAppear() {
116    let onLayoutComplete:()=>void=():void=>{
117      // 补充待实现的功能
118    }
119    let onDrawComplete:()=>void=():void=>{
120      // 补充待实现的功能
121    }
122    let onDrawChildrenComplete:()=>void=():void=>{
123      // 补充待实现的功能
124    }
125    let FuncLayout = onLayoutComplete // 绑定当前js对象
126    let FuncDraw = onDrawComplete // 绑定当前js对象
127    let FuncDrawChildren = onDrawChildrenComplete // 绑定当前js对象
128    let OffFuncLayout = onLayoutComplete // 绑定当前js对象
129    let OffFuncDraw = onDrawComplete // 绑定当前js对象
130    let OffFuncDrawChildren = onDrawChildrenComplete // 绑定当前js对象
131
132    this.listener.on('layout', FuncLayout)
133    this.listener.on('draw', FuncDraw)
134    this.listener.on('drawChildren', FuncDrawChildren)
135
136    // 通过句柄向对应的查询条件取消注册回调,由开发者自行决定在何时调用。
137    // this.listener.off('layout', OffFuncLayout)
138    // this.listener.off('draw', OffFuncDraw)
139    // this.listener.off('drawChildren', OffFuncDrawChildren)
140  }
141}
142```
143
144## 组件标识属性的扩展能力
145
146通过getInspectorByKey、getInspectorTree、sendEventByKey提供组件标识属性扩展能力,具体如下:
147- [getInspectorByKey](../reference/apis-arkui/arkui-ts/ts-universal-attributes-component-id.md#getinspectorbykey9),获取指定id的组件的所有属性。
148- [getInspectorTree](../reference/apis-arkui/arkui-ts/ts-universal-attributes-component-id.md#getinspectortree9),获取组件树及组件属性。
149- [sendEventByKey](../reference/apis-arkui/arkui-ts/ts-universal-attributes-component-id.md#sendeventbykey9),给指定id的组件发送事件。
150
151下述示例,展示了getInspectorByKey、getInspectorTree和sendEventByKey的基本用法。
152
153```ts
154@Entry
155@Component
156struct ComponentPage {
157  build() {
158    Column() {
159      Text("Hello World")
160        .fontSize(20)
161        .id("TEXT")
162        .onClick(() => {
163          console.info(`Text is clicked`);
164        })
165      Button('getInspectorByKey').onClick(() => {
166        let result = getInspectorByKey("TEXT");
167        console.info(`result is ${result}`);
168      })
169      Button('getInspectorTree').onClick(() => {
170        let result = getInspectorTree();
171        console.info(`result is ${JSON.stringify(result)}`);
172      })
173      Button('sendEventByKey').onClick(() => {
174        sendEventByKey("TEXT", 10, "");
175      })
176    }
177    .width('100%')
178    .height('100%')
179  }
180}
181```