鸿蒙开发中子窗口创建的作用

本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新

一、子窗口的核心作用

  1. 功能扩展:承载辅助功能(如弹窗、悬浮窗、画中画视频等) 
  2. 多任务处理:允许主窗口和子窗口同时交互(如主窗口浏览,子窗口播放视频) 
  3. 数据通信:通过AppStorage或事件机制实现主窗口与子窗口数据同步 
  4. 灵活布局:可自定义位置、大小和层级(如可拖拽的悬浮窗) 

二、创建子窗口的完整步骤

1. 获取WindowStage对象

在Ability中传递窗口实例到页面:

// EntryAbility.ets
onWindowStageCreate(windowStage: window.WindowStage) {
  windowStage.loadContent('pages/Index');
  AppStorage.setOrCreate('windowStage', windowStage); // 存储到全局
}
2. 创建子窗口

通过createSubWindow方法创建并配置:

// Index.ets
import { window } from '@ohos.window';

let subWindow: window.Window | undefined = undefined;

@Entry
@Component
struct Index {
  @State message: string = '主窗口';

  private createSubWindow() {
    const windowStage = AppStorage.get('windowStage');
    windowStage?.createSubWindow("mySubWindow", (err, data) => {
      if (err.code) {
        console.error('创建失败:', err);
        return;
      }
      subWindow = data;
      
      // 设置子窗口属性
      subWindow.moveWindowTo(300, 300); // 位置
      subWindow.resize(500, 500);       // 大小
      subWindow.setUIContent("pages/SubPage", (err) => { // 加载内容
        subWindow?.showWindow(); // 显示窗口
      });
    });
  }

  build() {
    Column() {
      Button('创建子窗口')
        .onClick(() => this.createSubWindow())
    }
  }
}

3. 子窗口页面开发

// SubPage.ets
@Entry
@Component
struct SubPage {
  @State text: string = '子窗口内容';

  build() {
    Column() {
      Text(this.text)
        .onClick(() => {
          this.text = '点击更新!';
        })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F5F5F5')
  }
}

4. 销毁子窗口

private destroySubWindow() {
  subWindow?.destroyWindow((err) => {
    if (!err.code) console.log('销毁成功');
  });
}

三、高级功能实现

1. 拖拽交互

通过手势事件移动窗口

// SubPage.ets
@State @Watch('onMove') posX: number = 300;
@State @Watch('onMove') posY: number = 300;

onMove() {
  subWindow?.moveWindowTo(this.posX, this.posY);
}

build() {
  Column()
    .gesture(
      GestureGroup(GestureMode.Exclusive, [
        PanGesture({ direction: PanDirection.All })
          .onActionUpdate((event: GestureEvent) => {
            this.posX += event.offsetX;
            this.posY += event.offsetY;
          })
      ])
    )
}
2. 主窗口与子窗口通信

方式一:AppStorage双向绑定

// 主窗口
@StorageLink('sharedData') sharedText: string = '默认';

// 子窗口
@StorageLink('sharedData') subText: string;

 方式二:EventHub事件总线

// 主窗口发布事件
getContext(this).eventHub.emit('update', { data: '新数据' });

// 子窗口监听
getContext(this).eventHub.on('update', (data) => {
  this.text = data.data;
});
3. 悬浮窗样式优化
subWindow?.setWindowBackgroundColor('#00000000'); // 透明背景
subWindow?.setWindowLayoutFullScreen(false);     // 非全屏
subWindow?.setWindowBrightness(0.8);             // 亮度调节

四、完整示例:视频画中画

// 1. 创建视频悬浮窗
createVideoWindow() {
  this.windowStage.createSubWindow("videoWindow", (err, win) => {
    win.resize(300, 200);
    win.moveWindowTo(screenWidth - 320, screenHeight - 220);
    win.setUIContent("pages/VideoPage", () => {
      win.showWindow();
    });
  });
}

// 2. VideoPage.ets中实现播放控制
@Entry
@Component
struct VideoPage {
  @State isPlaying: boolean = true;

  build() {
    Column() {
      VideoPlayer({ src: 'video.mp4' })
        .controls(false)
        .autoPlay(true)
      Button(this.isPlaying ? '暂停' : '播放')
        .onClick(() => this.isPlaying = !this.isPlaying)
    }
  }
}

五、注意事项

  1. 权限声明:系统级悬浮窗需申请权限
    "requestPermissions": [
      { "name": "ohos.permission.SYSTEM_FLOAT_WINDOW" }
    ]
  2. 性能优化:避免频繁创建/销毁窗口,建议复用实例 
  3. 兼容性:子窗口最小尺寸为320x240vp,最大2560x2560vp
  4. 生命周期:子窗口不会出现在任务管理中,需手动管理销毁

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值