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