HarmonyOS鸿蒙Next中在点击保存的时候把bindsheet弹窗关闭,但一直没搞成功
HarmonyOS鸿蒙Next中在点击保存的时候把bindsheet弹窗关闭,但一直没搞成功 我现在想在点击保存的时候把bindsheet弹窗关闭,但一直没搞成功,【问题现象】没有报错,现在的情况是openbindsheet(在ConfigPage里)和closebindsheet(在PipCustomDialog里)两个操作不是一个文件里的,closebindsheet时必须要填和打开bindsheet时一样的contentNode,我现在没搞通怎么把openbindsheet时的contentNode给到closebindsheet这个操作

更多关于HarmonyOS鸿蒙Next中在点击保存的时候把bindsheet弹窗关闭,但一直没搞成功的实战教程也可以访问 https://www.itying.com/category-93-b0.html
开发者你好,可以通过AppStorage保存contentNode。
【背景知识】 AppStorage:提供状态变量在应用级全局共享的能力,可以实现应用中不同页面数据共享,在V2版本下可以使用AppStorageV2。 【解决方案】 使用AppStorage可以实现数据在应用中共享,在构建半模态页面的组件内容时保存其数据,再通过唯一的键字符串值访问获取此数据即可。 示例代码如下:
在EntryAbility.ets中获取windowStage:
onWindowStageCreate(windowStage: window.WindowStage): void {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
windowStage.loadContent('pages/MapChartDemo', (err) => {
AppStorage.setOrCreate('uiContext', windowStage.getMainWindowSync().getUIContext());
if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;
}
AppStorage.setOrCreate('windowStage', windowStage)
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.');
});
}
@Entry
@Component
struct Index {
windowStage = AppStorage.get('windowStage') as window.WindowStage;
@State message: string = 'BindSheet';
contentNode: ComponentContent<Params> | null = null;
dialogController: CustomDialogController = new CustomDialogController({
alignment: DialogAlignment.Top,
builder: Dialog(),
cancel: () => {
this.dialogController.close()
},
backgroundColor: Color.Blue,
offset: { dx: 0, dy: 0 }
})
aboutToAppear(): void {
this.contentNode = new ComponentContent(this.getUIContext(), wrapBuilder(buildText),
new Params(this.message, this.dialogController));
AppStorage.setOrCreate('contentNode', this.contentNode)
}
build() {
Column() {
Button('打开Bindsheet')
.onClick(() => {
let uiContext = this.windowStage.getMainWindowSync().getUIContext();
let uniqueId = this.getUniqueId();
let frameNode: FrameNode | null = uiContext.getFrameNodeByUniqueId(uniqueId);
let targetId = frameNode?.getFirstChild()?.getUniqueId();
uiContext.openBindSheet(this.contentNode, {
height: SheetSize.MEDIUM,
title: { title: 'Title', subtitle: 'subtitle' },
}, targetId)
.then(() => {
console.info('openBindSheet success');
})
.catch((err: BusinessError) => {
console.error(`openBindSheet error. Cause:${err.code}, message:${err.message}`);
})
})
}
}
}
弹窗页面:
import { window } from '@kit.ArkUI'
// 弹窗相关
@CustomDialog
@Component
export struct Dialog {
@State showFlag: Visibility = Visibility.Visible
controller: CustomDialogController
build() {
Column() {
Button('关闭Bindsheet')
.onClick(() => {
let node: ComponentContent<Params> = AppStorage.get('contentNode') as ComponentContent<Params>;
let windowStage = AppStorage.get('windowStage') as window.WindowStage
windowStage.getMainWindowSync().getUIContext().closeBindSheet(node)
})
.margin({ top: 53 })
}
.width('100%')
.padding({ bottom: 15 })
.linearGradient(
{
direction: GradientDirection.Bottom,
colors: [['#283790', 0.0], ['#B2B1AB', 1.0]]
}
)
.borderRadius({ bottomLeft: 20, bottomRight: 20 })
}
}
export class Params {
text: string = '';
dialogController: CustomDialogController | null = null
constructor(text: string, dialogController: CustomDialogController | null) {
this.text = text;
this.dialogController = dialogController
}
}
@Builder
export function buildText(params: Params) {
Column() {
Text(params.text)
Button('打开弹窗')
.onClick(() => {
params.dialogController?.open()
})
}
}
更多关于HarmonyOS鸿蒙Next中在点击保存的时候把bindsheet弹窗关闭,但一直没搞成功的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
可以用AppStorage来保存contentNode。 AppStorage能实现应用内不同页面的数据共享,V2版本里可以用AppStorageV2。具体做法是,在构建半模态页面的组件内容时,把数据存到AppStorage里,之后用唯一的键字符串就能访问到这些数据。 以下是示例代码:
主页面
import { common } from '@kit.AbilityKit';
@Entry
@Component
struct Index {
@State message: string = 'BindSheet';
contentNode: ComponentContent<Params> | null = null;
private context = this.getUIContext().getHostContext() as common.UIAbilityContext;
dialogController: CustomDialogController = new CustomDialogController({
alignment: DialogAlignment.Top,
builder: Dialog(),
cancel: () => {
this.dialogController.close()
},
backgroundColor: Color.Blue,
offset: { dx: 0, dy: 0 }
})
aboutToAppear(): void {
this.contentNode = new ComponentContent(this.getUIContext(), wrapBuilder(buildText),
new Params(this.message, this.dialogController));
AppStorage.setOrCreate('contentNode', this.contentNode)
}
build() {
Column() {
Button('打开Bindsheet')
.onClick(() => {
let uniqueId = this.getUniqueId();
let frameNode: FrameNode | null = uiContext.getFrameNodeByUniqueId(uniqueId);
let targetId = frameNode?.getFirstChild()?.getUniqueId();
this.context.openBindSheet(this.contentNode, {
height: SheetSize.MEDIUM,
title: { title: 'Title', subtitle: 'subtitle' },
}, targetId)
})
}
}
}
弹窗组件
import { window } from '@kit.ArkUI'
import { common } from '@kit.AbilityKit';
@CustomDialog
@Component
export struct Dialog {
@State showFlag: Visibility = Visibility.Visible
controller: CustomDialogController
private context = this.getUIContext().getHostContext() as common.UIAbilityContext;
build() {
Column() {
Button('关闭Bindsheet')
.onClick(() => {
let node: ComponentContent<Params> = AppStorage.get('contentNode') as ComponentContent<Params>;
this.context.closeBindSheet(node)
})
.margin({ top: 53 })
}
.width('100%')
.padding({ bottom: 15 })
.linearGradient(
{
direction: GradientDirection.Bottom,
colors: [['#283790', 0.0], ['#B2B1AB', 1.0]]
}
)
.borderRadius({ bottomLeft: 20, bottomRight: 20 })
}
}
export class Params {
text: string = '';
dialogController: CustomDialogController | null = null
constructor(text: string, dialogController: CustomDialogController | null) {
this.text = text;
this.dialogController = dialogController
}
}
@Builder
export function buildText(params: Params) {
Column() {
Text(params.text)
Button('打开弹窗')
.onClick(() => {
params.dialogController?.open()
})
}
}
在HarmonyOS Next中,可通过windowStage的hide方法关闭bindsheet弹窗。确保在保存按钮的点击事件回调中调用弹窗组件的hide()方法。检查事件绑定是否正确,避免异步操作导致hide未执行。若使用自定义弹窗,需通过@State控制弹窗状态,在保存时更新状态变量触发关闭。
在HarmonyOS Next中,跨组件控制弹窗状态可以通过状态管理或事件传递实现。根据你的描述,ConfigPage和PipCustomDialog之间的contentNode需要共享。以下是两种推荐方案:
-
使用AppStorage或LocalStorage
在ConfigPage中打开弹窗时,将contentNode存入AppStorage:AppStorage.setOrCreate('bindsheetContentNode', contentNode);在
PipCustomDialog中关闭时读取:let node = AppStorage.get('bindsheetContentNode'); closeBindSheet(node); -
通过自定义事件传递
在ConfigPage中定义事件并传递参数:import { emitter } from '[@ohos](/user/ohos)/commonEventManager'; // 打开时发布事件 emitter.emit('bindsheetOpen', { contentNode });在
PipCustomDialog中订阅事件:emitter.on('bindsheetOpen', (data) => { this.contentNode = data.contentNode; });
确保关闭操作前已正确获取contentNode,并检查弹窗组件的生命周期是否与节点绑定一致。若仍无法解决,建议检查弹窗组件的visibility属性控制逻辑。

