1# 焦点控制 2 3自定义组件的走焦效果,可设置组件是否走焦和具体的走焦顺序,tab键或者方向键切换焦点。 4 5> **说明:** 6> 7> 从API Version 8开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 8 9## focusable 10 11focusable(value: boolean) 12 13设置当前组件是否可以获焦。 14 15**系统能力:** SystemCapability.ArkUI.ArkUI.Full 16 17**参数:** 18 19| 参数名 | 类型 | 必填 | 说明 | 20| ------ | ------- | ---- | ------------------------------------------------------------ | 21| value | boolean | 是 | 设置当前组件是否可以获焦。<br/>**说明:**<br/>存在默认交互逻辑的组件例如[Button](ts-basic-components-button.md)、[TextInput](ts-basic-components-textinput.md)等,默认即为可获焦,[Text](ts-basic-components-text.md)、[Image](ts-basic-components-image.md)等组件则默认状态为不可获焦。不可获焦状态下,无法触发[焦点事件](ts-universal-focus-event.md)。 | 22 23## tabIndex<sup>9+</sup> 24 25tabIndex(index: number) 26 27自定义组件tab键走焦能力。 28 29**系统能力:** SystemCapability.ArkUI.ArkUI.Full 30 31**参数:** 32 33| 参数名 | 类型 | 必填 | 说明 | 34| ------ | ------ | ---- | ------------------------------------------------------------ | 35| index | number | 是 | 自定义组件tab键走焦能力。若有配置了tabIndex大于0的组件,则tab键走焦只会在tabIndex大于0的组件内按照tabIndex的值从小到大并循环依次走焦。若没有配置tabIndex大于0的组件,则tabIndex等于0的组件按照组件预设的走焦规则走焦。<br />- tabIndex >= 0:表示元素是可聚焦的,并且可以通过tab键走焦来访问到该元素。<br />- tabIndex < 0(通常是tabIndex = -1):表示元素是可聚焦的,但是不能通过tab键走焦来访问到该元素。<br/>默认值:0 | 36 37## defaultFocus<sup>9+</sup> 38 39defaultFocus(value: boolean) 40 41设置当前组件是否为当前页面上的默认焦点。 42 43**系统能力:** SystemCapability.ArkUI.ArkUI.Full 44 45**参数:** 46 47| 参数名 | 类型 | 必填 | 说明 | 48| ------ | ------- | ---- | ------------------------------------------------------------ | 49| value | boolean | 是 | 设置当前组件是否为当前页面上的默认焦点,仅在初次创建的页面第一次进入时生效。<br/>默认值:false<br/>**说明:** <br/>值为true则表示为默认焦点,值为false无效。<br/>若页面内无任何组件设置defaultFocus(true),页面的默认焦点就是页面的根容器。<br/>若某页面内有多个组件设置了defaultFocus(true),则以组件树深度遍历找到的第一个组件为默认焦点。 | 50 51## groupDefaultFocus<sup>9+</sup> 52 53groupDefaultFocus(value: boolean) 54 55设置当前组件是否为当前组件所在容器获焦时的默认焦点。 56 57**系统能力:** SystemCapability.ArkUI.ArkUI.Full 58 59**参数:** 60 61| 参数名 | 类型 | 必填 | 说明 | 62| ------ | ------- | ---- | ------------------------------------------------------------ | 63| value | boolean | 是 | 设置当前组件是否为当前组件所在容器获焦时的默认焦点,仅在初次创建容器节点第一次获焦时生效。<br/>默认值:false<br/>**说明:** <br/>必须与[tabIndex](#tabindex9)联合使用,当某个容器设置了tabIndex,且容器内某子组件或容器自身设置了groupDefaultFocus(true),当该容器首次TAB键获焦时,会自动将焦点转移至该指定的组件上。若容器内(包含容器本身)有多个组件设置了groupDefaultFocus(true),则以组件树深度遍历找到的第一个组件为最终结果。 | 64 65## focusOnTouch<sup>9+</sup> 66 67focusOnTouch(value: boolean) 68 69设置当前组件是否支持点击获焦能力。 70 71**系统能力:** SystemCapability.ArkUI.ArkUI.Full 72 73**参数:** 74 75| 参数名 | 类型 | 必填 | 说明 | 76| ------ | ------- | ---- | ------------------------------------------------------------ | 77| value | boolean | 是 | 设置当前组件是否支持点击获焦能力。<br/>默认值:false<br/>**说明:** <br/>仅在组件可点击时才能正常获取焦点。 | 78 79## focusControl<sup>9+</sup> 80 81焦点控制模块 82 83### requestFocus<sup>9+</sup> 84 85requestFocus(value: string): boolean 86 87方法语句中可使用的全局接口,调用此接口可以主动让焦点转移至参数指定的组件上。 88 89**参数:** 90 91| 名称 | 类型 | 必填 | 描述 | 92| ----- | ------ | ---- | ---- | 93| value | string | 是 | 目标组件使用接口key(value: string)或id(value: string)绑定的字符串。 | 94 95**返回值:** 96 97| 类型 | 说明 | 98| ------- | ---- | 99| boolean | 返回是否成功给目标组件申请到焦点。若参数指向的目标组件存在,且目标组件可获焦,则返回true,否则返回false。 | 100 101> **说明:** 102> 103> 支持焦点控制的组件:[TextInput](ts-basic-components-textinput.md)、[TextArea](ts-basic-components-textarea.md)、[Search](ts-basic-components-search.md)、[Button](ts-basic-components-button.md)、[Text](ts-basic-components-text.md)、[Image](ts-basic-components-image.md)、[List](ts-container-list.md)、[Grid](ts-container-grid.md)。焦点事件当前仅支持在真机上显示运行效果。 104 105 106## 示例 107 108### 示例1 109 110defaultFocus/groupDefaultFocus/focusOnTouch示例代码: 111 112defaultFocus可以使绑定的组件成为页面创建后首次获焦的焦点。groupDefaultFocus可以使绑定的组件成为tabIndex容器创建后首次获焦的焦点。focusOnTouch可以使绑定的组件点击后立即获焦。 113 114```ts 115// focusTest.ets 116@Entry 117@Component 118struct FocusableExample { 119 @State inputValue: string = '' 120 121 build() { 122 Scroll() { 123 Row({ space: 20 }) { 124 Column({ space: 20 }) { 125 Column({ space: 5 }) { 126 Button('Group1') 127 .width(165) 128 .height(40) 129 .fontColor(Color.White) 130 .focusOnTouch(true) // 该Button组件点击后可获焦 131 Row({ space: 5 }) { 132 Button() 133 .width(80) 134 .height(40) 135 .fontColor(Color.White) 136 Button() 137 .width(80) 138 .height(40) 139 .fontColor(Color.White) 140 .focusOnTouch(true) // 该Button组件点击后可获焦 141 } 142 Row({ space: 5 }) { 143 Button() 144 .width(80) 145 .height(40) 146 .fontColor(Color.White) 147 Button() 148 .width(80) 149 .height(40) 150 .fontColor(Color.White) 151 } 152 }.borderWidth(2).borderColor(Color.Red).borderStyle(BorderStyle.Dashed) 153 .tabIndex(1) // 该Column组件为按TAB键走焦的第一个获焦的组件 154 Column({ space: 5 }) { 155 Button('Group2') 156 .width(165) 157 .height(40) 158 .fontColor(Color.White) 159 Row({ space: 5 }) { 160 Button() 161 .width(80) 162 .height(40) 163 .fontColor(Color.White) 164 Button() 165 .width(80) 166 .height(40) 167 .fontColor(Color.White) 168 .groupDefaultFocus(true) // 该Button组件上级Column组件获焦时获焦 169 } 170 Row({ space: 5 }) { 171 Button() 172 .width(80) 173 .height(40) 174 .fontColor(Color.White) 175 Button() 176 .width(80) 177 .height(40) 178 .fontColor(Color.White) 179 } 180 }.borderWidth(2).borderColor(Color.Green).borderStyle(BorderStyle.Dashed) 181 .tabIndex(2) // 该Column组件为按TAB键走焦的第二个获焦的组件 182 } 183 Column({ space: 5 }) { 184 TextInput({placeholder: 'input', text: this.inputValue}) 185 .onChange((value: string) => { 186 this.inputValue = value 187 }) 188 .width(156) 189 .defaultFocus(true) // 该TextInput组件为页面的初始默认焦点 190 Button('Group3') 191 .width(165) 192 .height(40) 193 .fontColor(Color.White) 194 Row({ space: 5 }) { 195 Button() 196 .width(80) 197 .height(40) 198 .fontColor(Color.White) 199 Button() 200 .width(80) 201 .height(40) 202 .fontColor(Color.White) 203 } 204 Button() 205 .width(165) 206 .height(40) 207 .fontColor(Color.White) 208 Row({ space: 5 }) { 209 Button() 210 .width(80) 211 .height(40) 212 .fontColor(Color.White) 213 Button() 214 .width(80) 215 .height(40) 216 .fontColor(Color.White) 217 } 218 Button() 219 .width(165) 220 .height(40) 221 .fontColor(Color.White) 222 Row({ space: 5 }) { 223 Button() 224 .width(80) 225 .height(40) 226 .fontColor(Color.White) 227 Button() 228 .width(80) 229 .height(40) 230 .fontColor(Color.White) 231 } 232 }.borderWidth(2).borderColor(Color.Orange).borderStyle(BorderStyle.Dashed) 233 .tabIndex(3) // 该Column组件为按TAB键走焦的第三个获焦的组件 234 }.alignItems(VerticalAlign.Top) 235 } 236 } 237} 238``` 239示意图: 240 241首次进入,焦点默认在defaultFocus绑定的TextInput组件上: 242 243 244 245首次按TAB键,焦点切换到tabIndex(1)的容器上,且自动走到其内部的groupDefaultFocus绑定的组件上: 246 247 248 249第二次按TAB键,焦点切换到tabIndex(2)的容器上,且自动走到其内部的groupDefaultFocus绑定的组件上: 250 251 252 253第三次按TAB键,焦点切换到tabIndex(3)的容器上,且自动走到其内部的groupDefaultFocus绑定的组件上: 254 255 256 257点击绑定了focusOnTouch的组件,组件自身获焦,焦点框被清除,再按下Tab键显示焦点框: 258 259 260 261### 示例2 262 263focusControl.requestFocus示例代码: 264 265使用focusControl.requestFocus接口使指定组件获取焦点。 266```ts 267// requestFocus.ets 268import promptAction from '@ohos.promptAction'; 269 270@Entry 271@Component 272struct RequestFocusExample { 273 @State idList: string[] = ['A', 'B', 'C', 'D', 'E', 'F', 'LastPageId'] 274 @State selectId: string = 'LastPageId' 275 276 build() { 277 Column({ space:20 }){ 278 Row({space: 5}) { 279 Button("id: " + this.idList[0] + " focusable(false)") 280 .width(200).height(70).fontColor(Color.White) 281 .id(this.idList[0]) 282 .focusable(false) 283 Button("id: " + this.idList[1]) 284 .width(200).height(70).fontColor(Color.White) 285 .id(this.idList[1]) 286 } 287 Row({space: 5}) { 288 Button("id: " + this.idList[2]) 289 .width(200).height(70).fontColor(Color.White) 290 .id(this.idList[2]) 291 Button("id: " + this.idList[3]) 292 .width(200).height(70).fontColor(Color.White) 293 .id(this.idList[3]) 294 } 295 Row({space: 5}) { 296 Button("id: " + this.idList[4]) 297 .width(200).height(70).fontColor(Color.White) 298 .id(this.idList[4]) 299 Button("id: " + this.idList[5]) 300 .width(200).height(70).fontColor(Color.White) 301 .id(this.idList[5]) 302 } 303 Row({space: 5}) { 304 Select([{value: this.idList[0]}, 305 {value: this.idList[1]}, 306 {value: this.idList[2]}, 307 {value: this.idList[3]}, 308 {value: this.idList[4]}, 309 {value: this.idList[5]}, 310 {value: this.idList[6]}]) 311 .value(this.selectId) 312 .onSelect((index: number) => { 313 this.selectId = this.idList[index] 314 }) 315 Button("RequestFocus") 316 .width(200).height(70).fontColor(Color.White) 317 .onClick(() => { 318 let res = focusControl.requestFocus(this.selectId) // 使选中的this.selectId的组件获焦 319 if (res) { 320 promptAction.showToast({message: 'Request success'}) 321 } else { 322 promptAction.showToast({message: 'Request failed'}) 323 } 324 }) 325 } 326 }.width('100%').margin({ top:20 }) 327 } 328} 329``` 330 331示意图: 332 333按下TAB键,激活焦点态显示。 334申请不存在的组件获焦: 335 336 337 338申请不可获焦的组件获焦: 339 340 341 342申请存在且可获焦的组件获焦: 343 344