• 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>
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)