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