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```