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