1# 构建弹窗
2
3
4通过弹窗控制器显示自定义弹窗,可以设置自定义弹窗的样式和内容。
5
6
7弹窗接口集合定义在结构体里,命名为ArkUI_NativeDialogAPI_x (x表示版本),这些接口围绕弹窗控制器实现各种弹窗控制。
8
9
10## 创建和销毁弹窗控制器
11
12- 创建弹窗控制器
13  [ArkUI_NativeDialogHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nativedialoghandle)表示指向弹窗控制器的指针,可以通过调用[ArkUI_NativeDialogAPI_x](../reference/apis-arkui/_ark_u_i___native_dialog_a_p_i__1.md)的[create](../reference/apis-arkui/_ark_u_i___native_dialog_a_p_i__1.md#create)接口创建一个弹窗控制器。
14
15  该方法返回ArkUI_NativeDialogHandle类型的数据。
16  ```
17  ArkUI_NativeDialogAPI_1 *dialogAPI = reinterpret_cast<ArkUI_NativeDialogAPI_1 *>(
18      OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_DIALOG, "ArkUI_NativeDialogAPI_1"));
19  auto dialogController = dialogAPI->create();
20  ```
21
22- 销毁弹窗控制器
23  当不再需要弹窗操作时,需要主动调用dispose接口销毁弹窗控制器对象。
24  ```
25  ArkUI_NativeDialogAPI_1 *dialogAPI = reinterpret_cast<ArkUI_NativeDialogAPI_1 *>(
26      OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_DIALOG, "ArkUI_NativeDialogAPI_1"));
27  dialogAPI->dispose(dialogController);
28  ```
29
30
31## 设置弹窗样式
32
33可以设置弹窗对齐方式、偏移量,弹窗背板圆角弧度、背景色、蒙层颜色以及区域等。
34
351. 创建弹窗内容节点。
36   ```
37   ArkUI_NodeHandle CreateDialogContent() {
38       ArkUI_NativeNodeAPI_1 *nodeAPI = reinterpret_cast<ArkUI_NativeNodeAPI_1 *>(
39           OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1"));
40       ArkUI_NodeHandle text = nodeAPI->createNode(ARKUI_NODE_TEXT);
41       ArkUI_NumberValue textWidthValue[] = {{.f32 = 300}};
42       ArkUI_AttributeItem textWidthItem = {.value = textWidthValue,
43                                            .size = sizeof(textWidthValue) / sizeof(ArkUI_NumberValue)};
44       nodeAPI->setAttribute(text, NODE_WIDTH, &textWidthItem);
45       ArkUI_NumberValue textHeightValue[] = {{.f32 = 300}};
46       ArkUI_AttributeItem textHeightItem = {.value = textHeightValue,
47                                             .size = sizeof(textWidthValue) / sizeof(ArkUI_NumberValue)};
48       nodeAPI->setAttribute(text, NODE_HEIGHT, &textHeightItem);
49       ArkUI_NodeHandle span = nodeAPI->createNode(ARKUI_NODE_SPAN);
50       ArkUI_AttributeItem spanItem = {.string = "这是一个弹窗"};
51       nodeAPI->setAttribute(span, NODE_SPAN_CONTENT, &spanItem);
52       ArkUI_NodeHandle imageSpan = nodeAPI->createNode(ARKUI_NODE_IMAGE_SPAN);
53       ArkUI_AttributeItem imageSpanItem = {.string = "/pages/common/sky.jpg"};
54       nodeAPI->setAttribute(imageSpan, NODE_IMAGE_SPAN_SRC, &imageSpanItem);
55       ArkUI_NumberValue imageSpanWidthValue[] = {{.f32 = 300}};
56       ArkUI_AttributeItem imageSpanWidthItem = {.value = imageSpanWidthValue,
57                                                 .size = sizeof(textWidthValue) / sizeof(ArkUI_NumberValue)};
58       nodeAPI->setAttribute(imageSpan, NODE_WIDTH, &imageSpanWidthItem);
59       ArkUI_NumberValue imageSpanHeightValue[] = {{.f32 = 200}};
60       ArkUI_AttributeItem imageSpanHeightItem = {.value = imageSpanHeightValue,
61                                                  .size = sizeof(textWidthValue) / sizeof(ArkUI_NumberValue)};
62       nodeAPI->setAttribute(imageSpan, NODE_HEIGHT, &imageSpanHeightItem);
63       nodeAPI->addChild(text, span);
64       nodeAPI->addChild(text, imageSpan);
65       return text;
66   }
67   ```
68
692. 通过controller控制弹窗样式。弹窗接口清单和描述可查看[native_dialog.h](../reference/apis-arkui/native__dialog_8h.md)。
70   ```
71   void ShowDialog() {
72       ArkUI_NativeDialogAPI_1 *dialogAPI = reinterpret_cast<ArkUI_NativeDialogAPI_1 *>(
73           OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_DIALOG, "ArkUI_NativeDialogAPI_1"));
74       if (!dialogController) {
75           dialogController = dialogAPI->create();
76       }
77       auto contentNode = CreateDialogContent();
78       dialogAPI->setContent(dialogController, contentNode);
79       dialogAPI->setContentAlignment(dialogController, static_cast<int32_t>(ARKUI_ALIGNMENT_BOTTOM), 0, 0);
80       dialogAPI->setBackgroundColor(dialogController, 0xffffffff);
81       dialogAPI->setCornerRadius(dialogController, 6, 6, 6, 6);
82       dialogAPI->setModalMode(dialogController, false);
83       dialogAPI->setAutoCancel(dialogController, true);
84       dialogAPI->show(dialogController, false);
85   }
86   ```
87
883. 不需要弹窗时关闭弹窗。
89   ```
90   void CloseDialog() {
91       ArkUI_NativeDialogAPI_1 *dialogAPI = reinterpret_cast<ArkUI_NativeDialogAPI_1 *>(
92           OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_DIALOG, "ArkUI_NativeDialogAPI_1"));
93       dialogAPI->close(dialogController);
94   }
95   ```
96
97
98## 弹窗的交互
99
100可创建交互页面,打开或关闭弹窗。
101
1021. 创建一个可交互的界面,点击Button之后可以弹窗。其中 ArkUI_NodeContentHandle 类型节点的获取与使用可参考[接入ArkTS页面](ndk-access-the-arkts-page.md)。
103   ```
104   constexpr int32_t BUTTON_CLICK_ID = 1;
105   bool isShown = false;
106   ArkUI_NativeDialogHandle dialogController;
107   ArkUI_NodeHandle buttonNode;
108
109   void MainViewMethod(ArkUI_NodeContentHandle handle) {
110       ArkUI_NativeNodeAPI_1 *nodeAPI = reinterpret_cast<ArkUI_NativeNodeAPI_1 *>(
111           OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1"));
112       ArkUI_NodeHandle column = nodeAPI->createNode(ARKUI_NODE_COLUMN);
113       ArkUI_NumberValue widthValue[] = {{.f32 = 300}};
114       ArkUI_AttributeItem widthItem = {.value = widthValue, .size = sizeof(widthValue) / sizeof(ArkUI_NumberValue)};
115       nodeAPI->setAttribute(column, NODE_WIDTH, &widthItem);
116       ArkUI_NumberValue heightValue[] = {{.f32 = 300}};
117       ArkUI_AttributeItem heightItem = {.value = heightValue, .size = sizeof(heightValue) / sizeof(ArkUI_NumberValue)};
118       nodeAPI->setAttribute(column, NODE_HEIGHT, &heightItem);
119
120       buttonNode = nodeAPI->createNode(ARKUI_NODE_BUTTON);
121       ArkUI_NumberValue buttonWidthValue[] = {{.f32 = 200}};
122       ArkUI_AttributeItem buttonWidthItem = {.value = buttonWidthValue,
123                                              .size = sizeof(buttonWidthValue) / sizeof(ArkUI_NumberValue)};
124       nodeAPI->setAttribute(buttonNode, NODE_WIDTH, &buttonWidthItem);
125       ArkUI_NumberValue buttonHeightValue[] = {{.f32 = 50}};
126       ArkUI_AttributeItem buttonHeightItem = {.value = buttonHeightValue,
127                                               .size = sizeof(buttonHeightValue) / sizeof(ArkUI_NumberValue)};
128       nodeAPI->setAttribute(buttonNode, NODE_HEIGHT, &buttonHeightItem);
129       ArkUI_AttributeItem labelItem = {.string = "点击弹窗"};
130       nodeAPI->setAttribute(buttonNode, NODE_BUTTON_LABEL, &labelItem);
131       ArkUI_NumberValue buttonTypeValue[] = {{.i32 = static_cast<int32_t>(ARKUI_BUTTON_TYPE_NORMAL)}};
132       ArkUI_AttributeItem buttonTypeItem = {.value = buttonTypeValue,
133                                             .size = sizeof(buttonTypeValue) / sizeof(ArkUI_NumberValue)};
134       nodeAPI->setAttribute(buttonNode, NODE_BUTTON_TYPE, &buttonTypeItem);
135       nodeAPI->registerNodeEvent(buttonNode, NODE_ON_CLICK, BUTTON_CLICK_ID, nullptr);
136       nodeAPI->addNodeEventReceiver(buttonNode, OnButtonClicked);
137       nodeAPI->addChild(column, buttonNode);
138       OH_ArkUI_NodeContent_AddNode(handle, column);
139   }
140   ```
141
1422. 创建Button事件的回调函数,当Button点击时触发弹窗显示或关闭。
143   ```
144   void OnButtonClicked(ArkUI_NodeEvent *event) {
145       if (!event || !buttonNode) {
146           return;
147       }
148       auto eventId = OH_ArkUI_NodeEvent_GetTargetId(event);
149       if (eventId == BUTTON_CLICK_ID) {
150           ArkUI_NativeNodeAPI_1 *nodeAPI = reinterpret_cast<ArkUI_NativeNodeAPI_1 *>(
151               OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1"));
152           if (isShown) {
153               isShown = false;
154               ArkUI_AttributeItem labelItem = {.string = "显示弹窗"};
155               nodeAPI->setAttribute(buttonNode, NODE_BUTTON_LABEL, &labelItem);
156               CloseDialog();
157           } else {
158               isShown = true;
159               ArkUI_AttributeItem labelItem = {.string = "关闭弹窗"};
160               nodeAPI->setAttribute(buttonNode, NODE_BUTTON_LABEL, &labelItem);
161               ShowDialog();
162           }
163       }
164   }
165   ```
166
167   ![zh-cn_image_0000001902966196](figures/zh-cn_image_0000001902966196.gif)
168