如何生成一个可以交互的移动子窗口

如何生成一个可以交互的移动子窗口

HarmonyOS
2024-05-26 11:48:30
浏览
收藏 0
回答 1
回答 1
按赞同
/
按时间
okmwq

本文主要介绍关于子窗口的生成以及属性设置,在我们日常手机应用过程中,手机APP根据需要会弹出一个子窗口在本APP界面上显示,或者在手机桌面上显示,类似视频聊天界面等。

使用的核心API

  • AppStorage
  • gesture
  • window

核心代码解释

1.showSubWindow(),通过createSubWindow创建子窗口,moveWindowTo和resize来确定窗口的大小和位置,最后通过setUIContent绑定子窗口目标页面。

2.destroySubWindow(),通过destroyWindow来消除子窗口。

3.AppStorage,提供数据存储能力,实现主窗口和子窗口的数据交互。

4.gesture,绑定手势操作。

EntryAbility.ts文件

 onWindowStageCreate(windowStage: window.WindowStage) { 
    // 将自定义数据变量“data”存入AppStorage 
    AppStorage.setOrCreate('data', 1); 
    AppStorage.setOrCreate('window', windowStage); 
  }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

主窗口界面

//Index 
import window from '@ohos.window'; 
  
  
@Entry 
@Component 
struct Index { 
  // 使用@StorageLink将"mainData"与AppStorage中的变量"data"进行双向绑定 
  @StorageLink('data') mainData: number = 1; 
  @StorageLink('window') storWindow:window.WindowStage  | null = null 
  private windowStage = this.storWindow 
  private sub_windowClass :window.Window | null = null 
  
  showSubWindow() { 
    // 创建应用子窗口。 
    if (this.windowStage == null) { 
      console.error('Failed to create the subwindow. Cause: windowStage_ is null'); 
    } else { 
      this.windowStage.createSubWindow("hiSubWindow", (err, data) => { 
        if (err.code) { 
          console.error('Failed to create the subwindow. Cause: ' + JSON.stringify(err)); 
          return; 
        } 
        this.sub_windowClass = data; 
        console.info('Succeeded in creating the subwindow. Data: ' + JSON.stringify(data)); 
        // 子窗口创建成功后,设置子窗口的位置、大小及相关属性等。 
        this.sub_windowClass.moveWindowTo(500, 500, (err) => { 
          if (err.code) { 
            console.error('Failed to move the window. Cause:' + JSON.stringify(err)); 
            return; 
          } 
          console.info('Succeeded in moving the window.'); 
        }); 
        this.sub_windowClass.resize(800, 800, (err) => { 
          if (err.code) { 
            console.error('Failed to change the window size. Cause:' + JSON.stringify(err)); 
            return; 
          } 
          console.info('Succeeded in changing the window size.'); 
        }); 
        // 为子窗口加载对应的目标页面。 
        this.sub_windowClass.setUIContent("pages/SubWindow", (err) => { 
          if (err.code) { 
            console.error('Failed to load the content. Cause:' + JSON.stringify(err)); 
            return; 
          } 
          console.info('Succeeded in loading the content.'); 
          // 显示子窗口。 
          (this.sub_windowClass as window.Window).showWindow((err) => { 
            let errCode: number = err.code; 
            if (errCode) { 
              console.error('Failed to show the window. Cause: ' + JSON.stringify(err)); 
              return; 
            } 
            console.info('Succeeded in showing the window.'); 
          }); 
          if(this.sub_windowClass == null){ 
            console.error('Failed to create the subwindow. Cause: windowStage_ is null'); 
          }else { 
            this.sub_windowClass.setWindowBackgroundColor('#E8A027') 
          } 
        }); 
      }) 
    } 
  } 
  
  destroySubWindow() { 
    if(this.sub_windowClass==null){ 
      console.error('Failed to create the subwindow. Cause: windowStage_ is null'); 
    }else{ 
      this.sub_windowClass.destroyWindow((err) => { 
        if (err.code) { 
          console.error('Failed to destroy the window. Cause: ' + JSON.stringify(err)); 
          return; 
        } 
        console.info('Succeeded in destroying the window.'); 
      }); 
    } 
  
  } 
  
  
  build() { 
    Row() { 
      Column() { 
        Text(`数据传输:${this.mainData}`) 
          .margin({bottom:30}) 
        Button('子窗口数据+1') 
          .backgroundColor('#ff8599cd') 
          .margin({bottom:30}) 
          .onClick(()=>{ 
            // 点击,storData的值加1 
            this.mainData += 1 
          }) 
        Button('创建子窗口') 
          .backgroundColor('#ff8599cd') 
          .onClick(()=>{ 
            // 点击弹出子窗口 
            this.showSubWindow() 
          }) 
          .margin({bottom:30}) 
        Button('消除子窗口') 
          .backgroundColor('#ff8599cd') 
          .onClick(()=>{ 
            // 点击消除子窗口 
            this.destroySubWindow() 
          }) 
      } 
      .width('100%') 
    } 
    .height('100%') 
  } 
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.

子窗口界面

// SubWindow.ets 
import window from '@ohos.window'; 
  
interface Position { 
  x: number, 
  y: number 
} 
  
@Entry 
@Component 
struct SubWindow{ 
  @State offsetX: number = 0 
  @State offsetY: number = 0 
  // 使用@StorageLink将"subData"与AppStorage中的变量"data"进行双向绑定 
  @StorageLink('data') subData: number = 1; 
  // 创建位置变量,并使用@Watch监听,变量发生变化调用moveWindow方法移动窗口 
  @State @Watch("moveWindow") windowPosition: Position = { x: 500, y: 500 }; 
  private panOption: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.All }); 
  private subWindow:window.Window | null = null 
  // 通过悬浮窗名称“hiSubWindow”获取到创建的悬浮窗 
  aboutToAppear() { 
    this.subWindow = window.findWindow("hiSubWindow") 
  } 
  // 将悬浮窗移动到指定位置 
  
  moveWindow() { 
    if(this.subWindow == null){ 
      console.info('Faild in destroying the window.'); 
    }else{ 
      this.subWindow.moveWindowTo(this.windowPosition.x, this.windowPosition.y); 
    } 
  } 
  build(){ 
    Column(){ 
      Text(`传输的数据:${this.subData}`) 
        .fontSize(12) 
        .margin({bottom:10}) 
      Button('主窗口数据+1') 
        .fontSize(12) 
        .backgroundColor('#ff8599cd') 
        .onClick(()=>{ 
          // 点击,subData的值加1 
          this.subData += 1 
        }) 
    } 
    .height('100%') 
    .width('100%') 
    .alignItems(HorizontalAlign.Center) 
    .justifyContent(FlexAlign.Center) 
    .gesture( 
      PanGesture(this.panOption) 
        //手势识别成功回调。 
        .onActionStart((event: GestureEvent) => { 
          console.info('Pan start'); 
        }) 
          // 手势移动过程中回调。发生拖拽时,获取到触摸点的位置,并将位置信息传递给windowPosition 
        .onActionUpdate((event: GestureEvent) => { 
          this.windowPosition.x += event.offsetX; 
          this.windowPosition.y += event.offsetY; 
        }) 
          //手势识别成功,手指抬起后触发回调。 
        .onActionEnd(() => { 
          console.info('Pan end'); 
        }) 
    ) 
  } 
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.

实现效果

生成一个可移动交互的子窗口

适配的版本信息

SDK:4.0.10.15

IDE:DevEco Studio 4.0.1.601

分享
微博
QQ
微信
回复
2024-05-27 15:37:07
相关问题
如何实现一个页面显示窗口
1384浏览 • 1回复 待解决
销毁一个窗口方法
943浏览 • 1回复 待解决
HarmonyOS 窗口是否可手势移动
633浏览 • 1回复 待解决
如何随机生成一个汉字?
1094浏览 • 1回复 待解决
如何生成一个36位UUID?
1139浏览 • 1回复 待解决
如何生成一个32位UUID
1298浏览 • 1回复 待解决
如何实现一个验证码弹窗子窗口
1215浏览 • 1回复 待解决
如何生成一个十六进制颜色色值?
1173浏览 • 1回复 待解决
窗口加载页面是否可以带参数
870浏览 • 1回复 待解决
Scroll中点击某一个层图片移动到顶端
1405浏览 • 1回复 待解决
HarmonyOS 如何拖拽窗口
586浏览 • 1回复 待解决
如何设置窗口背景颜色?
927浏览 • 1回复 待解决