• 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的组件,则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![defaultFocus](figures/defaultFocus.png)
182
183第二次按TAB键,焦点切换到tabIndex(1)的容器上,且自动走到其内部的groupDefaultFocus绑定的组件上:
184
185![groupDefaultFocus1](figures/groupDefaultFocus1.png)
186
187第三次按TAB键,焦点切换到tabIndex(2)的容器上,且自动走到其内部的groupDefaultFocus绑定的组件上:
188
189![groupDefaultFocus2](figures/groupDefaultFocus2.png)
190
191第四次按TAB键,焦点切换到tabIndex(3)的容器上,且自动走到其内部的groupDefaultFocus绑定的组件上:
192
193![groupDefaultFocus3](figures/groupDefaultFocus3.png)
194
195点击绑定了focusOnTouch的组件,组件自身获焦:
196
197![focusOnTouch](figures/focusOnTouch.png)
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![requestFocus1](figures/requestFocus1.png)
275
276申请不可获焦的组件获焦:
277
278![requestFocus2](figures/requestFocus2.png)
279
280申请存在且可获焦的组件获焦:
281
282![requestFocus3](figures/requestFocus3.png)