1# ArkUI Animation/Interaction Event Development (ArkTS)
2
3
4## What should I do if the onBlur and onFocus callbacks cannot be triggered? (API version 9)
5
6**Symptom**
7
8The **onBlur** and **onFocus** callbacks of the focus event cannot be triggered.
9
10**Solution**
11
12Check the trigger device. By default, the focus event (and the **onBlur** and **onFocus** callbacks) can be triggered only by the Tab button and arrow buttons on the connected keyboard. To enable the focus event to be triggered by a touch, add the **focusOnTouch** attribute for the target component.
13
14**Reference**
15
16[Focus Control](../reference/apis-arkui/arkui-ts/ts-universal-attributes-focus.md)
17
18
19## How do I disable the scroll event of a Grid nested in the Scroll? (API version 9)
20
21Implement nested scrolling of the containers, by using the **onScrollFrameBegin** event and the **scrollBy** method.
22
23**Reference**
24
25[Scroll](../reference/apis-arkui/arkui-ts/ts-container-scroll.md#example-2).
26
27
28## How do I enable a component to rotate continuously? (API version 9)
29
30You can use [property animation](../reference/apis-arkui/arkui-ts/ts-animatorproperty.md) to that effect.
31
32
33## How do I scroll a list with the keyboard? (API version 9)
34
35**Solution**
36
37Use either of the following:
38
39- Add **focusable(true)** to the list item to enable it to obtain focus.
40
41- Nest a focusable component, for example, **Button**, at the outer layer of each item.
42
43
44## Why is the click event not triggered for the focused component upon the press of the Enter key after keyboard navigation? (API version 9)
45
46By default, the built-in click event of the component and the custom **onClick** click event are bound to the space bar instead of the Enter key.
47
48
49## How do I block event bubbling when a button is nested in multi-layer components? (API version 9)
50
51You can bind the button to the **stopPropagation** parameter.
52
53
54## How do I disable the page transition effect when the router or navigator is used for page transition? (API version 9)
55
561. Define the **pageTransition** method for the current and target pages, by following instructions in [Example](../reference/apis-arkui/arkui-ts/ts-page-transition-animation.md#example).
57
582. Set the **duration** parameter of both **PageTransitionEnter** and **PageTransitionExit** to **0**.
59
60
61## How do I fix misidentification of the pan gesture where container nesting is involved? (API version 9)
62
63The pan gesture requires a minimum 5 vp movement distance of a finger on the screen. You can set the **distance** parameter in **PanGesture** to **1** so that the pan gesture can be more easily recognized.
64
65**Reference**
66
67[PanGesture](../reference/apis-arkui/arkui-ts/ts-basic-gestures-pangesture.md)
68
69
70## Can I use the fontFamily attribute to set different fonts? (API version 9)
71
72No. Currently, only the default font, HarmonyOS Sans, is supported.
73
74
75## How do I implement a text input box that shows a soft keyboard when touched and hides the soft keyboard when a button is touched? (API version 9)
76
77Use **focusControl** for the **TextInput** component to control its focus. The **TextInput** component shows a soft keyboard when it gains focus and hides the soft keyboard when it loses focus.
78
79**Example**
80
81```
82build() {
83  Column() {
84    TextInput()
85    Button(`hide`)
86      .key('button')
87      .onClick(()=>{
88        focusControl.requestFocus('button')
89      })
90  }
91}
92```
93
94
95## How do I implement a button that only responds to the bound onClick event, but not the onTouch event bound to the button's parent component? (API version 9)
96
97Bind the **onTouch** event to the **Button** component and use **stopPropagation()** in the event to prevent the event from bubbling up to the parent component.
98
99**Example**
100
101```
102build() {
103  Row() {
104    Button ("Click Me")
105      .width(100)
106      .width(100)
107      .backgroundColor('#f00')
108      .onClick(()=>{
109        console.log("Button onClick")
110      })
111      .onTouch((e) => {
112        console.log("Button onTouch")
113        e.stopPropagation()
114      })
115  }
116  .onTouch(() => {
117    console.log("Row onTouch")
118  })
119}
120```
121
122
123## Why is the menu bound to a component not displayed when the component is right-clicked? (API version 9)
124
125**Solution**
126
127Currently, the menu is displayed when the bound component is clicked or long pressed.
128
129
130## How do I prevent the TextInput component from bringing up the default keyboard? (API version 9)
131
132Set the **focusable** attribute of the **TextInput** component to **false**. In this way, the component is not focusable and therefore will not bring up the keyboard.
133
134
135## How do I implement the slide up and slide down effect for page transition? (API version 9)
136
137
138
139
140
141**Solution**
142
143You can use the **pageTransition** API to implement the page transition effect. Specifically, set the **slide** attribute in **PageTransitionEnter** and **PageTransitionExit** to **SlideEffect.Bottom**. In this way, the page slides in and out from the bottom.
144
145**Example**
146
147```
148// Index.ets
149@Entry
150@Component
151struct PageTransition1 {
152  build() {
153    Stack({alignContent: Alignment.Bottom}) {
154      Navigator({ target: 'pages/Page1'}) {
155        Image($r('app.media.ic_banner01')).width('100%').height(200) // Save the image in the media folder.
156      }
157    }.height('100%').width('100%')
158  }
159  pageTransition() {
160    PageTransitionEnter({ duration: 500, curve: Curve.Linear }).slide(SlideEffect.Bottom)
161    PageTransitionExit({ duration: 500, curve: Curve.Ease }).slide(SlideEffect.Bottom)
162  }
163}
164```
165
166```
167// Page1.ets
168@Entry
169@Component
170struct PageTransition2 {
171  build() {
172    Stack({alignContent: Alignment.Bottom}) {
173      Navigator({ target: 'pages/Index'}) {
174        Image($r('app.media.ic_banner02')).width('100%').height(200) // Save the image in the media folder.
175      }
176    }.height('100%').width('100%')
177  }
178  pageTransition() {
179    PageTransitionEnter({ duration: 500, curve: Curve.Linear }).slide(SlideEffect.Bottom)
180    PageTransitionExit({ duration: 500, curve: Curve.Ease }).slide(SlideEffect.Bottom)
181  }
182}
183```
184
185**Reference**
186
187[Page Transition](../reference/apis-arkui/arkui-ts/ts-page-transition-animation.md)
188
189## How do I configure custom components to slide in and out from the bottom? (API version 9)
190
191**Symptom**
192
193Custom components A and B need to deliver the following effects: When custom component A, displayed at the bottom of the screen by default, is touched, it is hidden, and custom component B slides in from the bottom; when custom component B is touched, it is hidden, and custom component A slides in from the bottom.
194
195**Solution**
196
197You can use the **transition** attribute to create component transition animations. Set the **type** parameter to specify the component transition type, which can be component addition, component deletion, or both. Set the **translate** parameter to specify the translation of the component during transition. **NOTE**<br>The **transition** attribute must work with **animateTo**. The animation duration, curve, and delay follow the settings in **animateTo**.
198
199**Example**
200
201```
202@Entry
203@Component
204struct ComponentTransition {
205  @State flag: boolean = true;
206
207  build() {
208    Stack({alignContent: Alignment.Bottom}) {
209        if (this.flag) {
210          ComponentChild1({ flag: $flag })
211            .transition({ type: TransitionType.Insert,translate: { x: 0, y: 200 } })
212        }
213        if (!this.flag) {
214          ComponentChild2({ flag: $flag })
215            .transition({ type: TransitionType.Insert, translate: { x: 0, y: 200 } })
216        }
217    }.height('100%').width('100%')
218  }
219}
220
221@Component
222struct ComponentChild1 {
223  @Link flag: boolean
224
225  build() {
226    Column() {
227      Image($r('app.media.ic_banner01'))
228        .width('100%')
229        .height(200)
230        .onClick(() => {
231          animateTo({ duration: 1000 }, () => {
232            this.flag = !this.flag;
233          })
234        })
235    }
236  }
237}
238
239@Component
240struct ComponentChild2 {
241  @Link flag: boolean
242
243  build() {
244    Column() {
245      Image($r('app.media.ic_banner02'))
246        .width('100%')
247        .height(200)
248        .onClick(() => {
249          animateTo({ duration: 1000 }, () => {
250            this.flag = !this.flag;
251          })
252        })
253    }
254  }
255}
256```
257
258**Reference**
259
260[Enter/Exit Transition](../ui/arkts-enter-exit-transition.md)
261
262
263## What should I do if the Files application does not respond to touches? (API version 10)
264
265**Symptom**
266
267When the Files application icon is touched and held for 200 ms to 500 ms, the application does not respond.
268
269**Cause Analysis**
270
271An error occurs with the drag gesture recognition logic. As a result, when the application icon is touched and held for a specific period of time, the gesture recognizer enters the pending state and stops responding.
272
273**Solution**
274
275Long press the Files application icon or a blank area.
276
277## How do I customize event transfer between parent and child components? (API version 10)
278
279**Solution**
280
2811. When processing a touch event, the system conducts hit testing - from the parent component to its children - to determine the component that needs to respond to the event. Subsequent gesture recognition and competition are performed based on the test result.
282
2832. You can set the **hitTestBehavior** attribute to specify how a component behaves during hit testing.
284
2853. Intervention on gesture recognition and competition results may be refined with custom events and custom gesture judgment.
286
287**Reference**
288
2891. [Hit Test Control](../reference/apis-arkui/arkui-ts/ts-universal-attributes-hit-test-behavior.md)
290
2912. [Custom Event Dispatch](../reference/apis-arkui/arkui-ts/ts-universal-attributes-on-child-touch-test.md)
292
2933.[Custom Gesture Judgment](../reference/apis-arkui/arkui-ts/ts-gesture-customize-judge.md)
294
295## How do I enable a list to automatically rearrange the layout after one of the list items is dragged? (API version 10)
296
297**Solution**
298
2991. Configure the list or list items to be draggable, and register the **onDragStart** callback.
300
3012. Set **visibility** of the dragged item to **HIDDEN** in the **onDragStart** callback.
302
3032. Register the **onDragMove** callback on the list or list item to listen for the movement during dragging.
304
3053. During the dragging, use the **event** parameter of **onDragMove** to obtain the coordinates of the drag points.
306
3074. Calculate the distance between the drag point coordinates and the item middle line. When the drag point and middle line overlap, enable the space filling animation.
308
3095. Use the **componentUtils** API to obtain the item layout information.
310
3116. The space filling animation uses **animateTo** to change the index in the data source and trigger the list sorting animation.
312
3137. The drop animation can be customized.
314
315 **Example**
316
317```ts
318// Record the dragged item when the dragging is started.
319  .onDragStart((event?: DragEvent, extraParams?: string) => {
320    this.dragIndex = Number(item.data)
321    this.dragItem = item
322  })
323  // Execute the space filling animation when the dragged item enters a valid drop target.
324  .onDragEnter((event?: DragEvent, extraParams?: string) => {
325    if (Number(item.data) != this.dragIndex) {
326      let current = this.dataSource.findIndex((element) => element.data === this.dragItem.data)
327      let index = this.dataSource.findIndex((element) => element.data === item.data)
328      animateTo({
329        curve: curves.interpolatingSpring(0, 1, 400, 38)
330      }, () => {
331        this.dataSource.splice(current, 1)
332        this.dataSource.splice(index, 0, this.dragItem)
333      })
334    }
335  })
336   // Implement a custom drop animation on the dragged item when it is dropped on a valid drop target.
337  .onDrop((dragEvent: DragEvent) => {
338    dragEvent.useCustomDropAnimation = true;
339    // Obtain the drop target.
340    let downLocation = getInspectorByKey(item.data)
341    let currentLocation = dragEvent.getPreviewRect()
342    this.dragItem.scale = 1.05
343    animateTo({
344      curve: curves.interpolatingSpring(14, 1, 170, 17)
345    }, () => {
346      this.dragItem.scale = 1
347    })
348  })
349```
350