1e41f4b71Sopenharmony_ci# Embedding ArkTS Components
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci
4e41f4b71Sopenharmony_ciArkUI on the native side offers a subset of ArkTS features, excluding certain capabilities such as declarative UI syntax, custom struct components, and advanced UI components.
5e41f4b71Sopenharmony_ci
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ciFor scenarios requiring ArkTS-specific features, ArkUI provides a mechanism to embed ArkTS components using [ComponentContent](../reference/apis-arkui/js-apis-arkui-ComponentContent.md). This involves encapsulating ArkTS components and passing them to the native side, where they are converted into **ArkUI_NodeHandle** objects through the [OH_ArkUI_GetNodeHandleFromNapiValue](../reference/apis-arkui/_ark_u_i___native_module.md#oh_arkui_getnodehandlefromnapivalue) API for component mounting.
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ci
10e41f4b71Sopenharmony_ci> **NOTE**
11e41f4b71Sopenharmony_ci>
12e41f4b71Sopenharmony_ci> - **ArkUI_NodeHandle** objects obtained from **OH_ArkUI_GetNodeHandleFromNapiValue** are for child component parameters only, such as the second parameter of the [addChild](../reference/apis-arkui/_ark_u_i___native_node_a_p_i__1.md#addchild) API. Using such objects in other scenarios, such as setting attributes with [setAttribute](../reference/apis-arkui/_ark_u_i___native_node_a_p_i__1.md#setattribute), will not take effect and will return an error code.
13e41f4b71Sopenharmony_ci> 
14e41f4b71Sopenharmony_ci> - To modify ArkTS components on the native side, construct update data using Node-APIs, and then call the [update](../reference/apis-arkui/js-apis-arkui-ComponentContent.md#update) API of **ComponentContent**.
15e41f4b71Sopenharmony_ci> 
16e41f4b71Sopenharmony_ci> - During the process of [building custom components](ndk-build-custom-components.md), functions such as **measureNode** cannot be used to call components within the ArkTS module.
17e41f4b71Sopenharmony_ci
18e41f4b71Sopenharmony_ci
19e41f4b71Sopenharmony_ciThe following example introduces the ArkTS **Refresh** component based on the [Integrating with ArkTS Pages](ndk-access-the-arkts-page.md) section.
20e41f4b71Sopenharmony_ci
21e41f4b71Sopenharmony_ci
22e41f4b71Sopenharmony_ci**Figure 1** Mounting a text list to a Refresh component
23e41f4b71Sopenharmony_ci
24e41f4b71Sopenharmony_ci![refresh_text_list](figures/refresh_text_list.gif)
25e41f4b71Sopenharmony_ci
26e41f4b71Sopenharmony_ci
27e41f4b71Sopenharmony_ci1. Register the ArkTS component creation function to the native side for it to call, and use the **ComponentContent** capability to encapsulate the creation function.
28e41f4b71Sopenharmony_ci   ```ts
29e41f4b71Sopenharmony_ci   // MixedModule.ets
30e41f4b71Sopenharmony_ci   // Create ArkTS components using the ComponentContent capability.
31e41f4b71Sopenharmony_ci   
32e41f4b71Sopenharmony_ci   import { NodeContent,  UIContext, RefreshModifier, ComponentContent } from '@kit.ArkUI';
33e41f4b71Sopenharmony_ci   
34e41f4b71Sopenharmony_ci   // Define the data object for interaction between the native side and ArkTS.
35e41f4b71Sopenharmony_ci   interface NativeRefreshAttribute {
36e41f4b71Sopenharmony_ci     isRefreshing: boolean;
37e41f4b71Sopenharmony_ci     width?: number;
38e41f4b71Sopenharmony_ci     height?: number;
39e41f4b71Sopenharmony_ci     backgroundColor?: number;
40e41f4b71Sopenharmony_ci     refreshOffset?: number;
41e41f4b71Sopenharmony_ci     pullToRefresh?: boolean
42e41f4b71Sopenharmony_ci     onRefreshing?: () => void;
43e41f4b71Sopenharmony_ci     onOffsetChange?: (offset: number) => void;
44e41f4b71Sopenharmony_ci   }
45e41f4b71Sopenharmony_ci   
46e41f4b71Sopenharmony_ci   // Define the format of the input parameters for the @Builder function.
47e41f4b71Sopenharmony_ci   interface RefreshAttribute {
48e41f4b71Sopenharmony_ci     isRefreshing: boolean;
49e41f4b71Sopenharmony_ci     // Optimize attribute settings for performance with Modifier.
50e41f4b71Sopenharmony_ci     modifier?: RefreshModifier;
51e41f4b71Sopenharmony_ci     slot?: NodeContent;
52e41f4b71Sopenharmony_ci     onRefreshing?: () => void;
53e41f4b71Sopenharmony_ci     onOffsetChange?: (offset: number) => void;
54e41f4b71Sopenharmony_ci   }
55e41f4b71Sopenharmony_ci   
56e41f4b71Sopenharmony_ci   // ComponentContent encapsulates the ArkTS component dependency on the global @Builder function. You can nest @Component decorated custom components within the @Builder function when needed.
57e41f4b71Sopenharmony_ci   // The @Builder function provides a way of passing parameters, making it convenient to update parameters later through the update API of ComponentContent.
58e41f4b71Sopenharmony_ci   @Builder
59e41f4b71Sopenharmony_ci   function mixedRefresh(attribute: RefreshAttribute) {
60e41f4b71Sopenharmony_ci     Refresh({ refreshing: attribute.isRefreshing }) {
61e41f4b71Sopenharmony_ci       // As a container component, Refresh needs to use the ContentSlot mechanism to reserve a place for child components.
62e41f4b71Sopenharmony_ci       ContentSlot(attribute.slot)
63e41f4b71Sopenharmony_ci     }.attributeModifier(attribute.modifier)
64e41f4b71Sopenharmony_ci     .onRefreshing(() => {
65e41f4b71Sopenharmony_ci       console.info("on onRefreshing");
66e41f4b71Sopenharmony_ci       if (attribute.onRefreshing) {
67e41f4b71Sopenharmony_ci         console.info("on native onRefreshing");
68e41f4b71Sopenharmony_ci         attribute.onRefreshing();
69e41f4b71Sopenharmony_ci       }
70e41f4b71Sopenharmony_ci     })
71e41f4b71Sopenharmony_ci     .onOffsetChange((value: number) => {
72e41f4b71Sopenharmony_ci       console.info("on offset change: " + value);
73e41f4b71Sopenharmony_ci       if (attribute.onOffsetChange) {
74e41f4b71Sopenharmony_ci         console.info("on native onOffsetChange");
75e41f4b71Sopenharmony_ci         attribute.onOffsetChange(value);
76e41f4b71Sopenharmony_ci       }
77e41f4b71Sopenharmony_ci     })
78e41f4b71Sopenharmony_ci   }
79e41f4b71Sopenharmony_ci   
80e41f4b71Sopenharmony_ci   // Define the return value of the creation function for interaction between the ArkTS side and the native side.
81e41f4b71Sopenharmony_ci   interface MixedModuleResult {
82e41f4b71Sopenharmony_ci     // Define the encapsulated object for the Refresh construction function, used by the native side to convert to an ArkUI_NodeHandle object.
83e41f4b71Sopenharmony_ci     content?: ComponentContent<RefreshAttribute>;
84e41f4b71Sopenharmony_ci     // As a container component, Refresh needs to use the ContentSlot mechanism to mount child components from the native side.
85e41f4b71Sopenharmony_ci     childSlot?: NodeContent;
86e41f4b71Sopenharmony_ci   }
87e41f4b71Sopenharmony_ci   
88e41f4b71Sopenharmony_ci   // Provide an entry function for creating ArkTS components.
89e41f4b71Sopenharmony_ci   export function createMixedRefresh(value: NativeRefreshAttribute): MixedModuleResult {
90e41f4b71Sopenharmony_ci     console.info("createMixedRefresh");
91e41f4b71Sopenharmony_ci     // Use the AppStorage object to maintain the UI context object when the ability starts.
92e41f4b71Sopenharmony_ci     let uiContent = AppStorage.get<UIContext>("context");
93e41f4b71Sopenharmony_ci     let modifier = new RefreshModifier();
94e41f4b71Sopenharmony_ci     if (value.width) {
95e41f4b71Sopenharmony_ci       modifier.width(value.width)
96e41f4b71Sopenharmony_ci     }
97e41f4b71Sopenharmony_ci     if (value.height) {
98e41f4b71Sopenharmony_ci       modifier.height(value.height)
99e41f4b71Sopenharmony_ci     }
100e41f4b71Sopenharmony_ci     if (value.backgroundColor) {
101e41f4b71Sopenharmony_ci       modifier.backgroundColor(value.backgroundColor)
102e41f4b71Sopenharmony_ci     }
103e41f4b71Sopenharmony_ci     if (value.pullToRefresh) {
104e41f4b71Sopenharmony_ci       modifier.pullToRefresh(value.pullToRefresh)
105e41f4b71Sopenharmony_ci     }
106e41f4b71Sopenharmony_ci     if (value.refreshOffset) {
107e41f4b71Sopenharmony_ci       modifier.refreshOffset(value.refreshOffset)
108e41f4b71Sopenharmony_ci     }
109e41f4b71Sopenharmony_ci     // Create a NodeContent slot object for mounting Refresh child components.
110e41f4b71Sopenharmony_ci     let nodeSlot = new NodeContent();
111e41f4b71Sopenharmony_ci     // Create the Refresh component using ComponentContent and encapsulate it.
112e41f4b71Sopenharmony_ci     let content = new ComponentContent<RefreshAttribute>(uiContent!, wrapBuilder<[RefreshAttribute]>(mixedRefresh),
113e41f4b71Sopenharmony_ci       {
114e41f4b71Sopenharmony_ci         isRefreshing: value.isRefreshing,
115e41f4b71Sopenharmony_ci         modifier: modifier,
116e41f4b71Sopenharmony_ci         slot: nodeSlot,
117e41f4b71Sopenharmony_ci         onRefreshing: value.onRefreshing,
118e41f4b71Sopenharmony_ci         onOffsetChange: value.onOffsetChange
119e41f4b71Sopenharmony_ci       });
120e41f4b71Sopenharmony_ci     // Pass the encapsulated object of the Refresh component and its child component slot object to the native side.
121e41f4b71Sopenharmony_ci     return { content: content, childSlot: nodeSlot };
122e41f4b71Sopenharmony_ci   }
123e41f4b71Sopenharmony_ci   
124e41f4b71Sopenharmony_ci   // Define the update function for the Refresh component for updating by the native side.
125e41f4b71Sopenharmony_ci   // In the update scenario, you need to return the encapsulated object of the Refresh component and its child component slot object to prevent the component from being re-created.
126e41f4b71Sopenharmony_ci   export function updateMixedRefresh(refresh: ComponentContent<RefreshAttribute>, childSlot: NodeContent,
127e41f4b71Sopenharmony_ci     value: NativeRefreshAttribute): void {
128e41f4b71Sopenharmony_ci     let modifier = new RefreshModifier();
129e41f4b71Sopenharmony_ci     if (value.width) {
130e41f4b71Sopenharmony_ci       modifier.width(value.width)
131e41f4b71Sopenharmony_ci     }
132e41f4b71Sopenharmony_ci     if (value.height) {
133e41f4b71Sopenharmony_ci       modifier.height(value.height)
134e41f4b71Sopenharmony_ci     }
135e41f4b71Sopenharmony_ci     if (value.backgroundColor) {
136e41f4b71Sopenharmony_ci       modifier.backgroundColor(value.backgroundColor)
137e41f4b71Sopenharmony_ci     }
138e41f4b71Sopenharmony_ci     if (value.pullToRefresh) {
139e41f4b71Sopenharmony_ci       modifier.pullToRefresh(value.pullToRefresh)
140e41f4b71Sopenharmony_ci     }
141e41f4b71Sopenharmony_ci     if (value.refreshOffset) {
142e41f4b71Sopenharmony_ci       modifier.refreshOffset(value.refreshOffset)
143e41f4b71Sopenharmony_ci     }
144e41f4b71Sopenharmony_ci     // Call the update API of ComponentContent to update.
145e41f4b71Sopenharmony_ci     refresh.update({
146e41f4b71Sopenharmony_ci       isRefreshing: value.isRefreshing,
147e41f4b71Sopenharmony_ci       modifier: modifier,
148e41f4b71Sopenharmony_ci       slot: childSlot,
149e41f4b71Sopenharmony_ci       onRefreshing: value.onRefreshing,
150e41f4b71Sopenharmony_ci       onOffsetChange: value.onOffsetChange
151e41f4b71Sopenharmony_ci     })
152e41f4b71Sopenharmony_ci   }
153e41f4b71Sopenharmony_ci   
154e41f4b71Sopenharmony_ci   ```
155e41f4b71Sopenharmony_ci
156e41f4b71Sopenharmony_ci2. Register the creation and update functions with the native side.
157e41f4b71Sopenharmony_ci   ```ts
158e41f4b71Sopenharmony_ci   // entry.ets
159e41f4b71Sopenharmony_ci   import nativeNode from 'libentry.so';
160e41f4b71Sopenharmony_ci   import { NodeContent } from '@kit.ArkUI';
161e41f4b71Sopenharmony_ci   import { createMixedRefresh, updateMixedRefresh } from './MixedModule'
162e41f4b71Sopenharmony_ci   
163e41f4b71Sopenharmony_ci   @Entry
164e41f4b71Sopenharmony_ci   @Component
165e41f4b71Sopenharmony_ci   struct Index {
166e41f4b71Sopenharmony_ci     private rootSlot = new NodeContent();
167e41f4b71Sopenharmony_ci     @State @Watch('changeNativeFlag') showNative: boolean = false;
168e41f4b71Sopenharmony_ci   
169e41f4b71Sopenharmony_ci     aboutToAppear(): void {
170e41f4b71Sopenharmony_ci       // Set the UI context.
171e41f4b71Sopenharmony_ci       AppStorage.setOrCreate<UIContext>("context", this.getUIContext());
172e41f4b71Sopenharmony_ci       // Set the builder function for mixed mode.
173e41f4b71Sopenharmony_ci       nativeNode.registerCreateMixedRefreshNode(createMixedRefresh);
174e41f4b71Sopenharmony_ci       nativeNode.registerUpdateMixedRefreshNode(updateMixedRefresh);
175e41f4b71Sopenharmony_ci     }
176e41f4b71Sopenharmony_ci   
177e41f4b71Sopenharmony_ci     changeNativeFlag(): void {
178e41f4b71Sopenharmony_ci       if (this.showNative) {
179e41f4b71Sopenharmony_ci         // Create and mount the NativeModule component.
180e41f4b71Sopenharmony_ci         nativeNode.createNativeRoot(this.rootSlot)
181e41f4b71Sopenharmony_ci       } else {
182e41f4b71Sopenharmony_ci         // Destroy the NativeModule component.
183e41f4b71Sopenharmony_ci         nativeNode.destroyNativeRoot()
184e41f4b71Sopenharmony_ci       }
185e41f4b71Sopenharmony_ci     }
186e41f4b71Sopenharmony_ci   
187e41f4b71Sopenharmony_ci     build() {
188e41f4b71Sopenharmony_ci       Column() {
189e41f4b71Sopenharmony_ci         Button(this.showNative ? "HideNativeUI" : "ShowNativeUI").onClick(() => {
190e41f4b71Sopenharmony_ci           this.showNative = !this.showNative
191e41f4b71Sopenharmony_ci         })
192e41f4b71Sopenharmony_ci         Row() {
193e41f4b71Sopenharmony_ci           // ArkTS inserts the native component.
194e41f4b71Sopenharmony_ci           ContentSlot(this.rootSlot)
195e41f4b71Sopenharmony_ci         }.layoutWeight(1)
196e41f4b71Sopenharmony_ci       }
197e41f4b71Sopenharmony_ci       .width('100%')
198e41f4b71Sopenharmony_ci       .height('100%')
199e41f4b71Sopenharmony_ci     }
200e41f4b71Sopenharmony_ci   }
201e41f4b71Sopenharmony_ci   ```
202e41f4b71Sopenharmony_ci
203e41f4b71Sopenharmony_ci   ```cpp
204e41f4b71Sopenharmony_ci   // native_init.cpp
205e41f4b71Sopenharmony_ci   #include "ArkUIMixedRefresh.h"
206e41f4b71Sopenharmony_ci   #include "NativeEntry.h"
207e41f4b71Sopenharmony_ci   #include "napi/native_api.h"
208e41f4b71Sopenharmony_ci   
209e41f4b71Sopenharmony_ci   EXTERN_C_START
210e41f4b71Sopenharmony_ci   static napi_value Init(napi_env env, napi_value exports) {
211e41f4b71Sopenharmony_ci       napi_property_descriptor desc[] = {
212e41f4b71Sopenharmony_ci           {"createNativeRoot", nullptr, NativeModule::CreateNativeRoot, nullptr, nullptr, nullptr, napi_default, nullptr},
213e41f4b71Sopenharmony_ci           // Register the mixed mode creation function.
214e41f4b71Sopenharmony_ci           {"registerCreateMixedRefreshNode", nullptr, NativeModule::ArkUIMixedRefresh::RegisterCreateRefresh, nullptr,
215e41f4b71Sopenharmony_ci            nullptr, nullptr, napi_default, nullptr},
216e41f4b71Sopenharmony_ci           // Register the mixed mode update function.
217e41f4b71Sopenharmony_ci           {"registerUpdateMixedRefreshNode", nullptr, NativeModule::ArkUIMixedRefresh::RegisterUpdateRefresh, nullptr,
218e41f4b71Sopenharmony_ci            nullptr, nullptr, napi_default, nullptr},
219e41f4b71Sopenharmony_ci           {"destroyNativeRoot", nullptr, NativeModule::DestroyNativeRoot, nullptr, nullptr, nullptr, napi_default,
220e41f4b71Sopenharmony_ci            nullptr}};
221e41f4b71Sopenharmony_ci       napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
222e41f4b71Sopenharmony_ci       return exports;
223e41f4b71Sopenharmony_ci   }
224e41f4b71Sopenharmony_ci   EXTERN_C_END
225e41f4b71Sopenharmony_ci   
226e41f4b71Sopenharmony_ci   static napi_module demoModule = {
227e41f4b71Sopenharmony_ci       .nm_version = 1,
228e41f4b71Sopenharmony_ci       .nm_flags = 0,
229e41f4b71Sopenharmony_ci       .nm_filename = nullptr,
230e41f4b71Sopenharmony_ci       .nm_register_func = Init,
231e41f4b71Sopenharmony_ci       .nm_modname = "entry",
232e41f4b71Sopenharmony_ci       .nm_priv = ((void *)0),
233e41f4b71Sopenharmony_ci       .reserved = {0},
234e41f4b71Sopenharmony_ci   };
235e41f4b71Sopenharmony_ci   
236e41f4b71Sopenharmony_ci   extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }
237e41f4b71Sopenharmony_ci   ```
238e41f4b71Sopenharmony_ci
239e41f4b71Sopenharmony_ci3. The native side saves the creation and update functions through the Node-API for subsequent calls.
240e41f4b71Sopenharmony_ci   ```c
241e41f4b71Sopenharmony_ci   // ArkUIMixedRefresh.h
242e41f4b71Sopenharmony_ci   // Mixed mode interaction class.
243e41f4b71Sopenharmony_ci   
244e41f4b71Sopenharmony_ci   #ifndef MYAPPLICATION_ARKUIMIXEDREFRESH_H
245e41f4b71Sopenharmony_ci   #define MYAPPLICATION_ARKUIMIXEDREFRESH_H
246e41f4b71Sopenharmony_ci   
247e41f4b71Sopenharmony_ci   #include "ArkUIMixedNode.h"
248e41f4b71Sopenharmony_ci   
249e41f4b71Sopenharmony_ci   #include <optional>
250e41f4b71Sopenharmony_ci   
251e41f4b71Sopenharmony_ci   #include <arkui/native_node_napi.h>
252e41f4b71Sopenharmony_ci   #include <js_native_api_types.h>
253e41f4b71Sopenharmony_ci   
254e41f4b71Sopenharmony_ci   namespace NativeModule {
255e41f4b71Sopenharmony_ci   
256e41f4b71Sopenharmony_ci   class ArkUIMixedRefresh : public ArkUIMixedNode {
257e41f4b71Sopenharmony_ci   public:
258e41f4b71Sopenharmony_ci       static napi_value RegisterCreateRefresh(napi_env env, napi_callback_info info);
259e41f4b71Sopenharmony_ci       static napi_value RegisterUpdateRefresh(napi_env env, napi_callback_info info);
260e41f4b71Sopenharmony_ci   };
261e41f4b71Sopenharmony_ci   
262e41f4b71Sopenharmony_ci   } // namespace NativeModule
263e41f4b71Sopenharmony_ci   
264e41f4b71Sopenharmony_ci   #endif // MYAPPLICATION_ARKUIMIXEDREFRESH_H
265e41f4b71Sopenharmony_ci   ```
266e41f4b71Sopenharmony_ci
267e41f4b71Sopenharmony_ci   ```cpp
268e41f4b71Sopenharmony_ci   // ArkUIMixedRefresh.cpp
269e41f4b71Sopenharmony_ci   // Mixed mode interaction class.
270e41f4b71Sopenharmony_ci   
271e41f4b71Sopenharmony_ci   #include "ArkUIMixedRefresh.h"
272e41f4b71Sopenharmony_ci   #include <hilog/log.h>
273e41f4b71Sopenharmony_ci   
274e41f4b71Sopenharmony_ci   namespace NativeModule {
275e41f4b71Sopenharmony_ci   namespace {
276e41f4b71Sopenharmony_ci   napi_env g_env;
277e41f4b71Sopenharmony_ci   napi_ref g_createRefresh;
278e41f4b71Sopenharmony_ci   napi_ref g_updateRefresh;
279e41f4b71Sopenharmony_ci   } // namespace
280e41f4b71Sopenharmony_ci   
281e41f4b71Sopenharmony_ci   napi_value ArkUIMixedRefresh::RegisterCreateRefresh(napi_env env, napi_callback_info info) {
282e41f4b71Sopenharmony_ci       size_t argc = 1;
283e41f4b71Sopenharmony_ci       napi_value args[1] = {nullptr};
284e41f4b71Sopenharmony_ci   
285e41f4b71Sopenharmony_ci       napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
286e41f4b71Sopenharmony_ci   
287e41f4b71Sopenharmony_ci       g_env = env;
288e41f4b71Sopenharmony_ci       napi_ref refer;
289e41f4b71Sopenharmony_ci       // Save the reference after creation to prevent it from being released.
290e41f4b71Sopenharmony_ci       napi_create_reference(env, args[0], 1, &refer);
291e41f4b71Sopenharmony_ci   
292e41f4b71Sopenharmony_ci       g_createRefresh = refer;
293e41f4b71Sopenharmony_ci       return nullptr;
294e41f4b71Sopenharmony_ci   }
295e41f4b71Sopenharmony_ci   
296e41f4b71Sopenharmony_ci   napi_value ArkUIMixedRefresh::RegisterUpdateRefresh(napi_env env, napi_callback_info info) {
297e41f4b71Sopenharmony_ci       size_t argc = 1;
298e41f4b71Sopenharmony_ci       napi_value args[1] = {nullptr};
299e41f4b71Sopenharmony_ci   
300e41f4b71Sopenharmony_ci       napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
301e41f4b71Sopenharmony_ci   
302e41f4b71Sopenharmony_ci       g_env = env;
303e41f4b71Sopenharmony_ci       napi_ref refer;
304e41f4b71Sopenharmony_ci       // Save the reference after creation to prevent it from being released.
305e41f4b71Sopenharmony_ci       napi_create_reference(env, args[0], 1, &refer);
306e41f4b71Sopenharmony_ci   
307e41f4b71Sopenharmony_ci       g_updateRefresh = refer;
308e41f4b71Sopenharmony_ci       return nullptr;
309e41f4b71Sopenharmony_ci   }
310e41f4b71Sopenharmony_ci   
311e41f4b71Sopenharmony_ci   } // namespace NativeModule
312e41f4b71Sopenharmony_ci   ```
313e41f4b71Sopenharmony_ci
314e41f4b71Sopenharmony_ci4. Abstract the base class of components in mixed mode for general logic management.
315e41f4b71Sopenharmony_ci   ```c
316e41f4b71Sopenharmony_ci   // ArkUIMixedNode.h
317e41f4b71Sopenharmony_ci   // Base class for mixed mode.
318e41f4b71Sopenharmony_ci   
319e41f4b71Sopenharmony_ci   #ifndef MYAPPLICATION_ARKUIMIXEDNODE_H
320e41f4b71Sopenharmony_ci   #define MYAPPLICATION_ARKUIMIXEDNODE_H
321e41f4b71Sopenharmony_ci   
322e41f4b71Sopenharmony_ci   #include <js_native_api.h>
323e41f4b71Sopenharmony_ci   #include <js_native_api_types.h>
324e41f4b71Sopenharmony_ci   
325e41f4b71Sopenharmony_ci   #include "ArkUIBaseNode.h"
326e41f4b71Sopenharmony_ci   #include "NativeModule.h"
327e41f4b71Sopenharmony_ci   
328e41f4b71Sopenharmony_ci   namespace NativeModule {
329e41f4b71Sopenharmony_ci   
330e41f4b71Sopenharmony_ci   // Wrap ArkTS Node
331e41f4b71Sopenharmony_ci   class ArkUIMixedNode : public ArkUIBaseNode {
332e41f4b71Sopenharmony_ci   public:
333e41f4b71Sopenharmony_ci       ArkUIMixedNode(ArkUI_NodeHandle handle, napi_env env, napi_ref componentContent)
334e41f4b71Sopenharmony_ci           : ArkUIBaseNode(handle), env_(env), componentContent_(componentContent) {}
335e41f4b71Sopenharmony_ci   
336e41f4b71Sopenharmony_ci       // In the base class destructor, the object on the ArkTS side in mixed mode needs to be released.
337e41f4b71Sopenharmony_ci       ~ArkUIMixedNode() override { napi_delete_reference(env_, componentContent_); }
338e41f4b71Sopenharmony_ci   
339e41f4b71Sopenharmony_ci   protected:
340e41f4b71Sopenharmony_ci       napi_env env_;
341e41f4b71Sopenharmony_ci       napi_ref componentContent_;
342e41f4b71Sopenharmony_ci   };
343e41f4b71Sopenharmony_ci   
344e41f4b71Sopenharmony_ci   } // namespace NativeModule
345e41f4b71Sopenharmony_ci   
346e41f4b71Sopenharmony_ci   #endif // MYAPPLICATION_ARKUIMIXEDNODE_H
347e41f4b71Sopenharmony_ci   ```
348e41f4b71Sopenharmony_ci
349e41f4b71Sopenharmony_ci5. Implement the encapsulation object for the **Refresh** component in mixed mode.
350e41f4b71Sopenharmony_ci   ```c
351e41f4b71Sopenharmony_ci   // ArkUIMixedRefresh.h
352e41f4b71Sopenharmony_ci   // The encapsulation object of Refresh in mixed mode on the native side.
353e41f4b71Sopenharmony_ci   
354e41f4b71Sopenharmony_ci   #ifndef MYAPPLICATION_ARKUIMIXEDREFRESH_H
355e41f4b71Sopenharmony_ci   #define MYAPPLICATION_ARKUIMIXEDREFRESH_H
356e41f4b71Sopenharmony_ci   
357e41f4b71Sopenharmony_ci   #include "ArkUIMixedNode.h"
358e41f4b71Sopenharmony_ci   #include "ArkUIBaseNode.h"
359e41f4b71Sopenharmony_ci   
360e41f4b71Sopenharmony_ci   #include <optional>
361e41f4b71Sopenharmony_ci   
362e41f4b71Sopenharmony_ci   #include <arkui/native_node_napi.h>
363e41f4b71Sopenharmony_ci   #include <js_native_api_types.h>
364e41f4b71Sopenharmony_ci   
365e41f4b71Sopenharmony_ci   namespace NativeModule {
366e41f4b71Sopenharmony_ci   
367e41f4b71Sopenharmony_ci   // Define the interaction data structure between the native side and the ArkTS side.
368e41f4b71Sopenharmony_ci   struct NativeRefreshAttribute {
369e41f4b71Sopenharmony_ci       std::optional<bool> isRefreshing;
370e41f4b71Sopenharmony_ci       std::optional<float> width;
371e41f4b71Sopenharmony_ci       std::optional<float> height;
372e41f4b71Sopenharmony_ci       std::optional<uint32_t> backgroundColor;
373e41f4b71Sopenharmony_ci       std::optional<float> refreshOffset;
374e41f4b71Sopenharmony_ci       std::optional<bool> pullToRefresh;
375e41f4b71Sopenharmony_ci       std::function<void()> onRefreshing;
376e41f4b71Sopenharmony_ci       std::function<void(float)> onOffsetChange;
377e41f4b71Sopenharmony_ci   };
378e41f4b71Sopenharmony_ci   
379e41f4b71Sopenharmony_ci   class ArkUIMixedRefresh : public ArkUIMixedNode {
380e41f4b71Sopenharmony_ci   public:
381e41f4b71Sopenharmony_ci       // Call the ArkTS method to create the Refresh component.
382e41f4b71Sopenharmony_ci       static const std::shared_ptr<ArkUIMixedRefresh> Create(const NativeRefreshAttribute &attribute);
383e41f4b71Sopenharmony_ci   
384e41f4b71Sopenharmony_ci       ArkUIMixedRefresh(ArkUI_NodeHandle handle, ArkUI_NodeContentHandle contentHandle, napi_env env,
385e41f4b71Sopenharmony_ci                         napi_ref componentContent, napi_ref nodeContent)
386e41f4b71Sopenharmony_ci           : ArkUIMixedNode(handle, env, componentContent), contentHandle_(contentHandle), nodeContent_(nodeContent) {}
387e41f4b71Sopenharmony_ci   
388e41f4b71Sopenharmony_ci       ArkUIMixedRefresh() : ArkUIMixedNode(nullptr, nullptr, nullptr) {}
389e41f4b71Sopenharmony_ci   
390e41f4b71Sopenharmony_ci       ~ArkUIMixedRefresh() override { napi_delete_reference(env_, nodeContent_); } // Release the placeholder component slot object for the child node.
391e41f4b71Sopenharmony_ci   
392e41f4b71Sopenharmony_ci       void SetWidth(float width) { attribute_.width = width; }
393e41f4b71Sopenharmony_ci   
394e41f4b71Sopenharmony_ci       void SetHeight(float height) { attribute_.height = height; }
395e41f4b71Sopenharmony_ci   
396e41f4b71Sopenharmony_ci       void SetBackgroundColor(uint32_t color) { attribute_.backgroundColor = color; }
397e41f4b71Sopenharmony_ci   
398e41f4b71Sopenharmony_ci       void SetRefreshState(bool isRefreshing) { attribute_.isRefreshing = isRefreshing; }
399e41f4b71Sopenharmony_ci   
400e41f4b71Sopenharmony_ci       void SetPullToRefresh(bool pullToRefresh) { attribute_.pullToRefresh = pullToRefresh; }
401e41f4b71Sopenharmony_ci   
402e41f4b71Sopenharmony_ci       void SetRefreshOffset(float offset) { attribute_.refreshOffset = offset; }
403e41f4b71Sopenharmony_ci   
404e41f4b71Sopenharmony_ci       void SetRefreshCallback(const std::function<void()> &callback) { attribute_.onRefreshing = callback; }
405e41f4b71Sopenharmony_ci   
406e41f4b71Sopenharmony_ci       void SetOnOffsetChange(const std::function<void(float)> &callback) { attribute_.onOffsetChange = callback; }
407e41f4b71Sopenharmony_ci   
408e41f4b71Sopenharmony_ci       // To avoid frequent cross-language communication, cache property events on the native side and notify in batches.
409e41f4b71Sopenharmony_ci       void FlushMixedModeCmd();
410e41f4b71Sopenharmony_ci   
411e41f4b71Sopenharmony_ci       static napi_value RegisterCreateRefresh(napi_env env, napi_callback_info info);
412e41f4b71Sopenharmony_ci       static napi_value RegisterUpdateRefresh(napi_env env, napi_callback_info info);
413e41f4b71Sopenharmony_ci   
414e41f4b71Sopenharmony_ci   protected:
415e41f4b71Sopenharmony_ci       void OnAddChild(const std::shared_ptr<ArkUIBaseNode> &child) override {
416e41f4b71Sopenharmony_ci           assert(contentHandle_);
417e41f4b71Sopenharmony_ci           // Use NodeContent to mount the component (can be a transformation object of ArkTS on the native side through ComponentContent, or a pure native component) under the ArkTS component.
418e41f4b71Sopenharmony_ci           OH_ArkUI_NodeContent_AddNode(contentHandle_, child->GetHandle());
419e41f4b71Sopenharmony_ci       }
420e41f4b71Sopenharmony_ci   
421e41f4b71Sopenharmony_ci       void OnRemoveChild(const std::shared_ptr<ArkUIBaseNode> &child) override {
422e41f4b71Sopenharmony_ci           assert(contentHandle_);
423e41f4b71Sopenharmony_ci           // Use NodeContent to remove the component.
424e41f4b71Sopenharmony_ci           OH_ArkUI_NodeContent_RemoveNode(contentHandle_, child->GetHandle());
425e41f4b71Sopenharmony_ci       }
426e41f4b71Sopenharmony_ci   
427e41f4b71Sopenharmony_ci       void OnInsertChild(const std::shared_ptr<ArkUIBaseNode> &child, int32_t index) override {
428e41f4b71Sopenharmony_ci           assert(contentHandle_);
429e41f4b71Sopenharmony_ci           // Use NodeContent to insert the component.
430e41f4b71Sopenharmony_ci           OH_ArkUI_NodeContent_InsertNode(contentHandle_, child->GetHandle(), index);
431e41f4b71Sopenharmony_ci       }
432e41f4b71Sopenharmony_ci   
433e41f4b71Sopenharmony_ci   private:
434e41f4b71Sopenharmony_ci       // Use the Node-API to create the data structure on the ArkTS side.
435e41f4b71Sopenharmony_ci       static napi_value CreateRefreshAttribute(const NativeRefreshAttribute &attribute, void *userData);
436e41f4b71Sopenharmony_ci   
437e41f4b71Sopenharmony_ci       ArkUI_NodeContentHandle contentHandle_;
438e41f4b71Sopenharmony_ci       napi_ref nodeContent_;
439e41f4b71Sopenharmony_ci       NativeRefreshAttribute attribute_;
440e41f4b71Sopenharmony_ci   };
441e41f4b71Sopenharmony_ci   
442e41f4b71Sopenharmony_ci   } // namespace NativeModule
443e41f4b71Sopenharmony_ci   
444e41f4b71Sopenharmony_ci   #endif // MYAPPLICATION_ARKUIMIXEDREFRESH_H
445e41f4b71Sopenharmony_ci   ```
446e41f4b71Sopenharmony_ci
447e41f4b71Sopenharmony_ci   Related implementation class description:
448e41f4b71Sopenharmony_ci
449e41f4b71Sopenharmony_ci   ```c
450e41f4b71Sopenharmony_ci   #include "ArkUIMixedRefresh.h"
451e41f4b71Sopenharmony_ci   #include <hilog/log.h>
452e41f4b71Sopenharmony_ci   
453e41f4b71Sopenharmony_ci   namespace NativeModule {
454e41f4b71Sopenharmony_ci   namespace {
455e41f4b71Sopenharmony_ci   napi_env g_env;
456e41f4b71Sopenharmony_ci   napi_ref g_createRefresh;
457e41f4b71Sopenharmony_ci   napi_ref g_updateRefresh;
458e41f4b71Sopenharmony_ci   } // namespace
459e41f4b71Sopenharmony_ci   
460e41f4b71Sopenharmony_ci   // Use the Node-API to create the data structure for interaction with the ArkTS side, used for the creation and update of the Refresh component.
461e41f4b71Sopenharmony_ci   napi_value ArkUIMixedRefresh::CreateRefreshAttribute(const NativeRefreshAttribute &attribute, void *userData) {
462e41f4b71Sopenharmony_ci       napi_property_descriptor desc[] = {
463e41f4b71Sopenharmony_ci           {"width", nullptr, nullptr, nullptr, nullptr, nullptr, napi_default, userData},
464e41f4b71Sopenharmony_ci           {"height", nullptr, nullptr, nullptr, nullptr, nullptr, napi_default, userData},
465e41f4b71Sopenharmony_ci           {"backgroundColor", nullptr, nullptr, nullptr, nullptr, nullptr, napi_default, userData},
466e41f4b71Sopenharmony_ci           {"pullToRefresh", nullptr, nullptr, nullptr, nullptr, nullptr, napi_default, userData},
467e41f4b71Sopenharmony_ci           {"isRefreshing", nullptr, nullptr, nullptr, nullptr, nullptr, napi_default, userData},
468e41f4b71Sopenharmony_ci           {"refreshOffset", nullptr, nullptr, nullptr, nullptr, nullptr, napi_default, userData},
469e41f4b71Sopenharmony_ci           {"onRefreshing", nullptr, nullptr, nullptr, nullptr, nullptr, napi_default, userData},
470e41f4b71Sopenharmony_ci           {"onOffsetChange", nullptr, nullptr, nullptr, nullptr, nullptr, napi_default, userData},
471e41f4b71Sopenharmony_ci       };
472e41f4b71Sopenharmony_ci       if (attribute.width) {
473e41f4b71Sopenharmony_ci           napi_value width;
474e41f4b71Sopenharmony_ci           napi_create_double(g_env, attribute.width.value(), &width);
475e41f4b71Sopenharmony_ci           desc[0].value = width;
476e41f4b71Sopenharmony_ci       }
477e41f4b71Sopenharmony_ci       if (attribute.height) {
478e41f4b71Sopenharmony_ci           napi_value height;
479e41f4b71Sopenharmony_ci           napi_create_double(g_env, attribute.height.value(), &height);
480e41f4b71Sopenharmony_ci           desc[1].value = height;
481e41f4b71Sopenharmony_ci       }
482e41f4b71Sopenharmony_ci       if (attribute.backgroundColor) {
483e41f4b71Sopenharmony_ci           napi_value backgroundColor;
484e41f4b71Sopenharmony_ci           napi_create_uint32(g_env, attribute.backgroundColor.value(), &backgroundColor);
485e41f4b71Sopenharmony_ci           desc[2].value = backgroundColor;
486e41f4b71Sopenharmony_ci       }
487e41f4b71Sopenharmony_ci       if (attribute.pullToRefresh) {
488e41f4b71Sopenharmony_ci           napi_value pullToRefresh;
489e41f4b71Sopenharmony_ci           napi_create_int32(g_env, attribute.pullToRefresh.value(), &pullToRefresh);
490e41f4b71Sopenharmony_ci           desc[3].value = pullToRefresh;
491e41f4b71Sopenharmony_ci       }
492e41f4b71Sopenharmony_ci       if (attribute.isRefreshing) {
493e41f4b71Sopenharmony_ci           napi_value isRefreshing;
494e41f4b71Sopenharmony_ci           napi_create_int32(g_env, attribute.isRefreshing.value(), &isRefreshing);
495e41f4b71Sopenharmony_ci           desc[4].value = isRefreshing;
496e41f4b71Sopenharmony_ci       }
497e41f4b71Sopenharmony_ci       if (attribute.refreshOffset) {
498e41f4b71Sopenharmony_ci           napi_value refreshOffset;
499e41f4b71Sopenharmony_ci           napi_create_double(g_env, attribute.refreshOffset.value(), &refreshOffset);
500e41f4b71Sopenharmony_ci           desc[5].value = refreshOffset;
501e41f4b71Sopenharmony_ci       }
502e41f4b71Sopenharmony_ci       if (attribute.onRefreshing) {
503e41f4b71Sopenharmony_ci           OH_LOG_INFO(LOG_APP, "onRefreshing start");
504e41f4b71Sopenharmony_ci           desc[6].method = [](napi_env env, napi_callback_info info) -> napi_value {
505e41f4b71Sopenharmony_ci               OH_LOG_INFO(LOG_APP, "onRefreshing callback");
506e41f4b71Sopenharmony_ci               size_t argc = 0;
507e41f4b71Sopenharmony_ci               napi_value args[0];
508e41f4b71Sopenharmony_ci               void *data;
509e41f4b71Sopenharmony_ci               napi_get_cb_info(env, info, &argc, args, nullptr, &data);
510e41f4b71Sopenharmony_ci               auto refresh = reinterpret_cast<ArkUIMixedRefresh *>(data);
511e41f4b71Sopenharmony_ci               if (refresh && refresh->attribute_.onRefreshing) {
512e41f4b71Sopenharmony_ci                   refresh->attribute_.onRefreshing();
513e41f4b71Sopenharmony_ci               }
514e41f4b71Sopenharmony_ci               return nullptr;
515e41f4b71Sopenharmony_ci           };
516e41f4b71Sopenharmony_ci       }
517e41f4b71Sopenharmony_ci       if (attribute.onOffsetChange) {
518e41f4b71Sopenharmony_ci           OH_LOG_INFO(LOG_APP, "onOffsetChange start");
519e41f4b71Sopenharmony_ci           desc[7].method = [](napi_env env, napi_callback_info info) -> napi_value {
520e41f4b71Sopenharmony_ci               OH_LOG_INFO(LOG_APP, "onOffsetChange callback");
521e41f4b71Sopenharmony_ci               size_t argc = 1;
522e41f4b71Sopenharmony_ci               napi_value args[1] = {nullptr};
523e41f4b71Sopenharmony_ci               void *data;
524e41f4b71Sopenharmony_ci               napi_get_cb_info(env, info, &argc, args, nullptr, &data);
525e41f4b71Sopenharmony_ci               double offset = 0.0;
526e41f4b71Sopenharmony_ci               napi_get_value_double(env, args[0], &offset);
527e41f4b71Sopenharmony_ci               auto refresh = reinterpret_cast<ArkUIMixedRefresh *>(data);
528e41f4b71Sopenharmony_ci               if (refresh && refresh->attribute_.onOffsetChange) {
529e41f4b71Sopenharmony_ci                   refresh->attribute_.onOffsetChange(offset);
530e41f4b71Sopenharmony_ci               }
531e41f4b71Sopenharmony_ci               return nullptr;
532e41f4b71Sopenharmony_ci           };
533e41f4b71Sopenharmony_ci       }
534e41f4b71Sopenharmony_ci       napi_value refreshAttribute = nullptr;
535e41f4b71Sopenharmony_ci       auto result = napi_create_object_with_properties(g_env, &refreshAttribute, sizeof(desc) / sizeof(desc[0]), desc);
536e41f4b71Sopenharmony_ci       if (result != napi_ok) {
537e41f4b71Sopenharmony_ci           return nullptr;
538e41f4b71Sopenharmony_ci       }
539e41f4b71Sopenharmony_ci       return refreshAttribute;
540e41f4b71Sopenharmony_ci   }
541e41f4b71Sopenharmony_ci   
542e41f4b71Sopenharmony_ci   // Create the component on the ArkTS side and save it in the encapsulation object on the native side.
543e41f4b71Sopenharmony_ci   const std::shared_ptr<ArkUIMixedRefresh> ArkUIMixedRefresh::Create(const NativeRefreshAttribute &attribute) {
544e41f4b71Sopenharmony_ci       napi_handle_scope scope;
545e41f4b71Sopenharmony_ci       napi_open_handle_scope(g_env, &scope);
546e41f4b71Sopenharmony_ci       auto refresh = std::make_shared<ArkUIMixedRefresh>();
547e41f4b71Sopenharmony_ci       auto refreshAttribute = CreateRefreshAttribute(attribute, refresh.get());
548e41f4b71Sopenharmony_ci       if (refreshAttribute == nullptr) {
549e41f4b71Sopenharmony_ci           napi_close_handle_scope(g_env, scope);
550e41f4b71Sopenharmony_ci           return nullptr;
551e41f4b71Sopenharmony_ci       }
552e41f4b71Sopenharmony_ci       napi_value result = nullptr;
553e41f4b71Sopenharmony_ci       napi_value argv[1] = {refreshAttribute};
554e41f4b71Sopenharmony_ci       napi_value createRefresh = nullptr;
555e41f4b71Sopenharmony_ci       napi_get_reference_value(g_env, g_createRefresh, &createRefresh);
556e41f4b71Sopenharmony_ci       // Call the ArkTS Create function to create the ArkTS ComponentContent.
557e41f4b71Sopenharmony_ci       napi_call_function(g_env, nullptr, createRefresh, 1, argv, &result);
558e41f4b71Sopenharmony_ci   
559e41f4b71Sopenharmony_ci       // Obtain the ArkTS Refresh component.
560e41f4b71Sopenharmony_ci       napi_value componentContent = nullptr;
561e41f4b71Sopenharmony_ci       napi_get_named_property(g_env, result, "content", &componentContent);
562e41f4b71Sopenharmony_ci       ArkUI_NodeHandle handle;
563e41f4b71Sopenharmony_ci       OH_ArkUI_GetNodeHandleFromNapiValue(g_env, componentContent, &handle);
564e41f4b71Sopenharmony_ci       assert(handle);
565e41f4b71Sopenharmony_ci       // Obtain the child component slot of the ArkTS Refresh component.
566e41f4b71Sopenharmony_ci       napi_value nodeContent = nullptr;
567e41f4b71Sopenharmony_ci       napi_get_named_property(g_env, result, "childSlot", &nodeContent);
568e41f4b71Sopenharmony_ci       ArkUI_NodeContentHandle contentHandle;
569e41f4b71Sopenharmony_ci       OH_ArkUI_GetNodeContentFromNapiValue(g_env, nodeContent, &contentHandle);
570e41f4b71Sopenharmony_ci       assert(contentHandle);
571e41f4b71Sopenharmony_ci       // Save the ArkTS ComponentContent to prevent the object on the ArkTS side from being released and for subsequent updates.
572e41f4b71Sopenharmony_ci       napi_ref componentContentRef;
573e41f4b71Sopenharmony_ci       napi_create_reference(g_env, componentContent, 1, &componentContentRef);
574e41f4b71Sopenharmony_ci       // Save the ArkTS NodeContent to prevent the object on the ArkTS side from being released and for subsequent updates.
575e41f4b71Sopenharmony_ci       napi_ref nodeContentRef;
576e41f4b71Sopenharmony_ci       napi_create_reference(g_env, nodeContent, 1, &nodeContentRef);
577e41f4b71Sopenharmony_ci       // Update the Refresh component related parameters.
578e41f4b71Sopenharmony_ci       refresh->handle_ = handle;
579e41f4b71Sopenharmony_ci       refresh->env_ = g_env;
580e41f4b71Sopenharmony_ci       refresh->componentContent_ = componentContentRef;
581e41f4b71Sopenharmony_ci       refresh->nodeContent_ = nodeContentRef;
582e41f4b71Sopenharmony_ci       refresh->contentHandle_ = contentHandle;
583e41f4b71Sopenharmony_ci       refresh->attribute_ = attribute;
584e41f4b71Sopenharmony_ci       return refresh;
585e41f4b71Sopenharmony_ci   }
586e41f4b71Sopenharmony_ci   // Implementation of the update function.
587e41f4b71Sopenharmony_ci   void ArkUIMixedRefresh::FlushMixedModeCmd() {
588e41f4b71Sopenharmony_ci       napi_handle_scope scope;
589e41f4b71Sopenharmony_ci       napi_open_handle_scope(g_env, &scope);
590e41f4b71Sopenharmony_ci       // Create the input parameters for the call to the ArkTS API.
591e41f4b71Sopenharmony_ci       auto refreshAttribute = CreateRefreshAttribute(attribute_, this);
592e41f4b71Sopenharmony_ci       if (refreshAttribute == nullptr) {
593e41f4b71Sopenharmony_ci           napi_close_handle_scope(g_env, scope);
594e41f4b71Sopenharmony_ci           return;
595e41f4b71Sopenharmony_ci       }
596e41f4b71Sopenharmony_ci       // Obtain the remaining two API parameters for the update API.
597e41f4b71Sopenharmony_ci       napi_value componentContent = nullptr;
598e41f4b71Sopenharmony_ci       napi_get_reference_value(g_env, componentContent_, &componentContent);
599e41f4b71Sopenharmony_ci       napi_value nodeContent = nullptr;
600e41f4b71Sopenharmony_ci       napi_get_reference_value(g_env, nodeContent_, &nodeContent);
601e41f4b71Sopenharmony_ci   
602e41f4b71Sopenharmony_ci       napi_value argv[3] = {componentContent, nodeContent, refreshAttribute};
603e41f4b71Sopenharmony_ci       napi_value updateRefresh = nullptr;
604e41f4b71Sopenharmony_ci       napi_get_reference_value(g_env, g_updateRefresh, &updateRefresh);
605e41f4b71Sopenharmony_ci       // Call the ArkTS Update function to update.
606e41f4b71Sopenharmony_ci       napi_value result = nullptr;
607e41f4b71Sopenharmony_ci       napi_call_function(g_env, nullptr, updateRefresh, 3, argv, &result);
608e41f4b71Sopenharmony_ci   }
609e41f4b71Sopenharmony_ci   
610e41f4b71Sopenharmony_ci   napi_value ArkUIMixedRefresh::RegisterCreateRefresh(napi_env env, napi_callback_info info) {
611e41f4b71Sopenharmony_ci       size_t argc = 1;
612e41f4b71Sopenharmony_ci       napi_value args[1] = {nullptr};
613e41f4b71Sopenharmony_ci   
614e41f4b71Sopenharmony_ci       napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
615e41f4b71Sopenharmony_ci   
616e41f4b71Sopenharmony_ci       g_env = env;
617e41f4b71Sopenharmony_ci       napi_ref refer;
618e41f4b71Sopenharmony_ci       napi_create_reference(env, args[0], 1, &refer);
619e41f4b71Sopenharmony_ci   
620e41f4b71Sopenharmony_ci       g_createRefresh = refer;
621e41f4b71Sopenharmony_ci       return nullptr;
622e41f4b71Sopenharmony_ci   }
623e41f4b71Sopenharmony_ci   
624e41f4b71Sopenharmony_ci   napi_value ArkUIMixedRefresh::RegisterUpdateRefresh(napi_env env, napi_callback_info info) {
625e41f4b71Sopenharmony_ci       size_t argc = 1;
626e41f4b71Sopenharmony_ci       napi_value args[1] = {nullptr};
627e41f4b71Sopenharmony_ci   
628e41f4b71Sopenharmony_ci       napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
629e41f4b71Sopenharmony_ci   
630e41f4b71Sopenharmony_ci       g_env = env;
631e41f4b71Sopenharmony_ci       napi_ref refer;
632e41f4b71Sopenharmony_ci       napi_create_reference(env, args[0], 1, &refer);
633e41f4b71Sopenharmony_ci   
634e41f4b71Sopenharmony_ci       g_updateRefresh = refer;
635e41f4b71Sopenharmony_ci       return nullptr;
636e41f4b71Sopenharmony_ci   }
637e41f4b71Sopenharmony_ci   
638e41f4b71Sopenharmony_ci   } // namespace NativeModule
639e41f4b71Sopenharmony_ci   
640e41f4b71Sopenharmony_ci   ```
641e41f4b71Sopenharmony_ci
642e41f4b71Sopenharmony_ci6. Use the page structure from the [Integrating with ArkTS Page](ndk-access-the-arkts-page.md) section, and continue with the [timer module simple implementation](ndk-loading-long-list.md), making the **Refresh** component the parent component of the text list. 
643e41f4b71Sopenharmony_ci   ```c
644e41f4b71Sopenharmony_ci   // MixedRefreshExample.h
645e41f4b71Sopenharmony_ci   // Sample code for mixed mode.
646e41f4b71Sopenharmony_ci   
647e41f4b71Sopenharmony_ci   #ifndef MYAPPLICATION_MIXEDREFRESHEXAMPLE_H
648e41f4b71Sopenharmony_ci   #define MYAPPLICATION_MIXEDREFRESHEXAMPLE_H
649e41f4b71Sopenharmony_ci   
650e41f4b71Sopenharmony_ci   #include "ArkUIBaseNode.h"
651e41f4b71Sopenharmony_ci   #include "ArkUIMixedRefresh.h"
652e41f4b71Sopenharmony_ci   #include "TextListExample.h"
653e41f4b71Sopenharmony_ci   #include "UITimer.h"
654e41f4b71Sopenharmony_ci   
655e41f4b71Sopenharmony_ci   #include <js_native_api_types.h>
656e41f4b71Sopenharmony_ci   
657e41f4b71Sopenharmony_ci   namespace NativeModule {
658e41f4b71Sopenharmony_ci   
659e41f4b71Sopenharmony_ci   std::shared_ptr<ArkUIBaseNode> CreateMixedRefreshList(napi_env env) {
660e41f4b71Sopenharmony_ci       auto list = CreateTextListExample();
661e41f4b71Sopenharmony_ci       // Create the Refresh component in mixed mode and mount the List component.
662e41f4b71Sopenharmony_ci       NativeRefreshAttribute nativeRefreshAttribute{
663e41f4b71Sopenharmony_ci           .backgroundColor = 0xFF89CFF0, .refreshOffset = 64, .pullToRefresh = true};
664e41f4b71Sopenharmony_ci       auto refresh = ArkUIMixedRefresh::Create(nativeRefreshAttribute);
665e41f4b71Sopenharmony_ci       refresh->AddChild(list);
666e41f4b71Sopenharmony_ci   
667e41f4b71Sopenharmony_ci       // Set the event for mixed mode.
668e41f4b71Sopenharmony_ci       refresh->SetOnOffsetChange(
669e41f4b71Sopenharmony_ci           [](float offset) { OH_LOG_INFO(LOG_APP, "on refresh offset changed: %{public}f", offset); });
670e41f4b71Sopenharmony_ci       refresh->SetRefreshCallback([refreshPtr = refresh.get(), env]() {
671e41f4b71Sopenharmony_ci           OH_LOG_INFO(LOG_APP, "on refreshing");
672e41f4b71Sopenharmony_ci           // Start the timer to simulate data acquisition.
673e41f4b71Sopenharmony_ci           CreateNativeTimer(env, refreshPtr, 1, [](void *userData, int32_t count) {
674e41f4b71Sopenharmony_ci               // Disable the refresh feature after data is obtained.
675e41f4b71Sopenharmony_ci               auto refresh = reinterpret_cast<ArkUIMixedRefresh *>(userData);
676e41f4b71Sopenharmony_ci               refresh->SetRefreshState(false);
677e41f4b71Sopenharmony_ci               refresh->FlushMixedModeCmd();
678e41f4b71Sopenharmony_ci           });
679e41f4b71Sopenharmony_ci       });
680e41f4b71Sopenharmony_ci   
681e41f4b71Sopenharmony_ci       // Update the event to the ArkTS side.
682e41f4b71Sopenharmony_ci       refresh->FlushMixedModeCmd();
683e41f4b71Sopenharmony_ci       return refresh;
684e41f4b71Sopenharmony_ci   }
685e41f4b71Sopenharmony_ci   
686e41f4b71Sopenharmony_ci   } // namespace NativeModule
687e41f4b71Sopenharmony_ci   
688e41f4b71Sopenharmony_ci   #endif // MYAPPLICATION_MIXEDREFRESHEXAMPLE_H
689e41f4b71Sopenharmony_ci   ```
690e41f4b71Sopenharmony_ci
691e41f4b71Sopenharmony_ci   Replace the entry component creation with the pull-to-refresh text list.
692e41f4b71Sopenharmony_ci
693e41f4b71Sopenharmony_ci   ```c
694e41f4b71Sopenharmony_ci   #include "NativeEntry.h"
695e41f4b71Sopenharmony_ci   
696e41f4b71Sopenharmony_ci   #include "ArkUIMixedRefresh.h"
697e41f4b71Sopenharmony_ci   #include "MixedRefreshExample.h"
698e41f4b71Sopenharmony_ci   #include "TextListExample.h"
699e41f4b71Sopenharmony_ci   
700e41f4b71Sopenharmony_ci   #include <arkui/native_node_napi.h>
701e41f4b71Sopenharmony_ci   #include <arkui/native_type.h>
702e41f4b71Sopenharmony_ci   #include <js_native_api.h>
703e41f4b71Sopenharmony_ci   #include <uv.h>
704e41f4b71Sopenharmony_ci   
705e41f4b71Sopenharmony_ci   namespace NativeModule {
706e41f4b71Sopenharmony_ci   
707e41f4b71Sopenharmony_ci   napi_value CreateNativeRoot(napi_env env, napi_callback_info info) {
708e41f4b71Sopenharmony_ci       size_t argc = 1;
709e41f4b71Sopenharmony_ci       napi_value args[1] = {nullptr};
710e41f4b71Sopenharmony_ci   
711e41f4b71Sopenharmony_ci       napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
712e41f4b71Sopenharmony_ci   
713e41f4b71Sopenharmony_ci       // Obtain NodeContent.
714e41f4b71Sopenharmony_ci       ArkUI_NodeContentHandle contentHandle;
715e41f4b71Sopenharmony_ci       OH_ArkUI_GetNodeContentFromNapiValue(env, args[0], &contentHandle);
716e41f4b71Sopenharmony_ci       NativeEntry::GetInstance()->SetContentHandle(contentHandle);
717e41f4b71Sopenharmony_ci   
718e41f4b71Sopenharmony_ci       // Create a Refresh text list.
719e41f4b71Sopenharmony_ci       auto refresh = CreateMixedRefreshList(env);
720e41f4b71Sopenharmony_ci   
721e41f4b71Sopenharmony_ci       // Keep the native side object in the management class to maintain its lifecycle.
722e41f4b71Sopenharmony_ci       NativeEntry::GetInstance()->SetRootNode(refresh);
723e41f4b71Sopenharmony_ci       return nullptr;
724e41f4b71Sopenharmony_ci   }
725e41f4b71Sopenharmony_ci   
726e41f4b71Sopenharmony_ci   napi_value DestroyNativeRoot(napi_env env, napi_callback_info info) {
727e41f4b71Sopenharmony_ci       // Release the native side object from the management class.
728e41f4b71Sopenharmony_ci       NativeEntry::GetInstance()->DisposeRootNode();
729e41f4b71Sopenharmony_ci       return nullptr;
730e41f4b71Sopenharmony_ci   }
731e41f4b71Sopenharmony_ci   
732e41f4b71Sopenharmony_ci   } // namespace NativeModule
733e41f4b71Sopenharmony_ci   
734e41f4b71Sopenharmony_ci   ```
735