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 | 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 52```ts 53// focusTest.ets 54@Entry 55@Component 56struct FocusableExample { 57 @State inputValue: string = '' 58 59 build() { 60 Scroll() { 61 Row({ space: 20 }) { 62 Column({ space: 20 }) { 63 Column({ space: 5 }) { 64 Button('Group1') 65 .width(165) 66 .height(40) 67 .fontColor(Color.White) 68 .focusOnTouch(true) // 该Button组件点击后可获焦 69 Row({ space: 5 }) { 70 Button() 71 .width(80) 72 .height(40) 73 .fontColor(Color.White) 74 Button() 75 .width(80) 76 .height(40) 77 .fontColor(Color.White) 78 .focusOnTouch(true) // 该Button组件点击后可获焦 79 } 80 Row({ space: 5 }) { 81 Button() 82 .width(80) 83 .height(40) 84 .fontColor(Color.White) 85 Button() 86 .width(80) 87 .height(40) 88 .fontColor(Color.White) 89 } 90 }.borderWidth(2).borderColor(Color.Red).borderStyle(BorderStyle.Dashed) 91 .tabIndex(1) // 该Column组件为按TAB键走焦的第一个获焦的组件 92 Column({ space: 5 }) { 93 Button('Group2') 94 .width(165) 95 .height(40) 96 .fontColor(Color.White) 97 Row({ space: 5 }) { 98 Button() 99 .width(80) 100 .height(40) 101 .fontColor(Color.White) 102 Button() 103 .width(80) 104 .height(40) 105 .fontColor(Color.White) 106 .groupDefaultFocus(true) // 该Button组件上级Column组件获焦时获焦 107 } 108 Row({ space: 5 }) { 109 Button() 110 .width(80) 111 .height(40) 112 .fontColor(Color.White) 113 Button() 114 .width(80) 115 .height(40) 116 .fontColor(Color.White) 117 } 118 }.borderWidth(2).borderColor(Color.Green).borderStyle(BorderStyle.Dashed) 119 .tabIndex(2) // 该Column组件为按TAB键走焦的第二个获焦的组件 120 } 121 Column({ space: 5 }) { 122 TextInput({placeholder: 'input', text: this.inputValue}) 123 .onChange((value: string) => { 124 this.inputValue = value 125 }) 126 .width(156) 127 .defaultFocus(true) // 该TextInput组件为页面的初始默认焦点 128 Button('Group3') 129 .width(165) 130 .height(40) 131 .fontColor(Color.White) 132 Row({ space: 5 }) { 133 Button() 134 .width(80) 135 .height(40) 136 .fontColor(Color.White) 137 Button() 138 .width(80) 139 .height(40) 140 .fontColor(Color.White) 141 } 142 Button() 143 .width(165) 144 .height(40) 145 .fontColor(Color.White) 146 Row({ space: 5 }) { 147 Button() 148 .width(80) 149 .height(40) 150 .fontColor(Color.White) 151 Button() 152 .width(80) 153 .height(40) 154 .fontColor(Color.White) 155 } 156 Button() 157 .width(165) 158 .height(40) 159 .fontColor(Color.White) 160 Row({ space: 5 }) { 161 Button() 162 .width(80) 163 .height(40) 164 .fontColor(Color.White) 165 Button() 166 .width(80) 167 .height(40) 168 .fontColor(Color.White) 169 } 170 }.borderWidth(2).borderColor(Color.Orange).borderStyle(BorderStyle.Dashed) 171 .tabIndex(3) // 该Column组件为按TAB键走焦的第三个获焦的组件 172 }.alignItems(VerticalAlign.Top) 173 } 174 } 175} 176``` 177示意图: 178 179首次按下TAB键,焦点切换到defaultFocus绑定的组件上: 180 181 182 183第二次按TAB键,焦点切换到tabIndex(1)的容器上,且自动走到其内部的groupDefaultFocus绑定的组件上: 184 185 186 187第三次按TAB键,焦点切换到tabIndex(2)的容器上,且自动走到其内部的groupDefaultFocus绑定的组件上: 188 189 190 191第四次按TAB键,焦点切换到tabIndex(3)的容器上,且自动走到其内部的groupDefaultFocus绑定的组件上: 192 193 194 195点击绑定了focusOnTouch的组件,组件自身获焦: 196 197 198 199### 示例2 200 201focusControl.requestFocus示例代码: 202 203使用focusContrl.requestFocus接口使指定组件获取焦点。 204```ts 205// requestFocus.ets 206import promptAction from '@ohos.promptAction'; 207 208@Entry 209@Component 210struct RequestFocusExample { 211 @State idList: string[] = ['A', 'B', 'C', 'D', 'E', 'F', 'LastPageId'] 212 @State selectId: string = 'LastPageId' 213 214 build() { 215 Column({ space:20 }){ 216 Row({space: 5}) { 217 Button("id: " + this.idList[0] + " focusable(false)") 218 .width(200).height(70).fontColor(Color.White) 219 .key(this.idList[0]) 220 .focusable(false) 221 Button("id: " + this.idList[1]) 222 .width(200).height(70).fontColor(Color.White) 223 .key(this.idList[1]) 224 } 225 Row({space: 5}) { 226 Button("id: " + this.idList[2]) 227 .width(200).height(70).fontColor(Color.White) 228 .key(this.idList[2]) 229 Button("id: " + this.idList[3]) 230 .width(200).height(70).fontColor(Color.White) 231 .key(this.idList[3]) 232 } 233 Row({space: 5}) { 234 Button("id: " + this.idList[4]) 235 .width(200).height(70).fontColor(Color.White) 236 .key(this.idList[4]) 237 Button("id: " + this.idList[5]) 238 .width(200).height(70).fontColor(Color.White) 239 .key(this.idList[5]) 240 } 241 Row({space: 5}) { 242 Select([{value: this.idList[0]}, 243 {value: this.idList[1]}, 244 {value: this.idList[2]}, 245 {value: this.idList[3]}, 246 {value: this.idList[4]}, 247 {value: this.idList[5]}, 248 {value: this.idList[6]}]) 249 .value(this.selectId) 250 .onSelect((index: number) => { 251 this.selectId = this.idList[index] 252 }) 253 Button("RequestFocus") 254 .width(200).height(70).fontColor(Color.White) 255 .onClick(() => { 256 let res = focusControl.requestFocus(this.selectId) // 使选中的this.selectId的组件获焦 257 if (res) { 258 promptAction.showToast({message: 'Request success'}) 259 } else { 260 promptAction.showToast({message: 'Request failed'}) 261 } 262 }) 263 } 264 }.width('100%').margin({ top:20 }) 265 } 266} 267``` 268 269示意图: 270 271按下TAB键,激活焦点态显示。 272申请不存在的组件获焦: 273 274 275 276申请不可获焦的组件获焦: 277 278 279 280申请存在且可获焦的组件获焦: 281 282