HarmonyOS 鸿蒙Next怎么实现当前界面的横竖屏?

HarmonyOS 鸿蒙Next怎么实现当前界面的横竖屏?

下面是我的代码,从其他的页面跳到当前界面,希望web能切换横竖屏 调转用的NavPathStack

import { webview } from "@kit.ArkWeb";
import { window } from "@kit.ArkUI";

@Builder
export function HomeDetailBuilder(id: string) {
  HomeDetail({ urlWebId: id });
}

@Component
export struct HomeDetail{

  private controller: webview.WebviewController = new webview.WebviewController();
  private pathStack ?: NavPathStack;
  @State urlWebId: string = ''

  build() {
    NavDestination(){
      Column() {
        Button(){
          Image($r('app.media.svg_back')).width(22).height(22).fillColor(Color.Black)
        }.width(40).height(40).backgroundColor($r('app.color.color_f2f2f2')).margin({ left : 12 ,top : 8 })
        .onClick(() => {this.pathStack?.pop()})
        Row(){
          Button('竖屏').onClick(()=>{
            window.getLastWindow(getContext(this), (err, win) => {
              win.setPreferredOrientation(window.Orientation.PORTRAIT)
            })
          })
          Button('横屏').onClick(()=>{
            window.getLastWindow(getContext(this), (err, win) => {
              win.setPreferredOrientation(window.Orientation.LANDSCAPE_INVERTED)
            })
          })
        }
        Web({ src: this.urlWebId, controller: this.controller })
          .cacheMode(CacheMode.Default)
          .domStorageAccess(true)
          .javaScriptAccess(true)
          .onPageEnd(() => {
            this.controller.prefetchPage(this.urlWebId);
          })
      }.alignItems(HorizontalAlign.Start)
    }
    .hideTitleBar(true)
    .width('100%')
    .height('100%')
    .onReady((context: NavDestinationContext) => {
      this.pathStack = context.pathStack;
      this.urlWebId = context.pathInfo.param as string;
    })
  }
}

只切换NavDestination 需要怎么弄?


更多关于HarmonyOS 鸿蒙Next怎么实现当前界面的横竖屏?的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

目前好像没有办法只切换NavDestination。可以在退出当前页面时恢复原来横竖屏状态

import { webview } from '@kit.ArkWeb';
import { window } from '@kit.ArkUI';
import { common } from '@kit.AbilityKit';

@Builder
export function HomeDetailBuilder(id: string) {
  HomeDetail({ urlWebId: id });
}

@Component
export struct HomeDetail {
  private controller: webview.WebviewController = new webview.WebviewController();
  private pathStack ?: NavPathStack;
  @State urlWebId: string = ''
  @State globalLandscape: boolean = false
  @State landscape: boolean = false

  aboutToAppear() {
    // 记录横竖屏状态
    this.globalLandscape = this.getUIContext().getMediaQuery().matchMediaSync('(orientation: landscape)').matches
  }

  aboutToDisappear() {
    // 恢复原来横竖屏状态
    if (this.landscape != this.globalLandscape) {
      this.changeOrientation(this.globalLandscape)
    }
  }

  // 改变设备横竖屏状态函数
  private changeOrientation(isLandscape: boolean) {
    this.landscape = isLandscape
    let context: common.UIAbilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext;
    window.getLastWindow(context).then((lastWindow) => {
      lastWindow.setPreferredOrientation(isLandscape ? window.Orientation.USER_ROTATION_LANDSCAPE : window.Orientation.USER_ROTATION_PORTRAIT)
    });
  }

  build() {
    NavDestination() {
      Column() {
        Button() {
          Image($r('app.media.svg_back')).width(22).height(22).fillColor(Color.Black)
        }
        .width(40)
        .height(40)
        .backgroundColor($r('app.color.color_f2f2f2'))
        .margin({ left: 12, top: 8 })
        .onClick(() => {
          this.pathStack?.pop()
        })

        Row() {
          Button('竖屏').onClick(() => {
            this.changeOrientation(false);
          })
          Button('横屏').onClick(() => {
            this.changeOrientation(true);
          })
        }

        Web({ src: this.urlWebId, controller: this.controller })
          .cacheMode(CacheMode.Default)
          .domStorageAccess(true)
          .javaScriptAccess(true)
          .onPageEnd(() => {
            this.controller.prefetchPage(this.urlWebId);
          })
      }.alignItems(HorizontalAlign.Start)
    }
    .hideTitleBar(true)
    .width('100%')
    .height('100%')
    .onReady((context: NavDestinationContext) => {
      this.pathStack = context.pathStack;
      this.urlWebId = context.pathInfo.param as string;
    })
  }
}

更多关于HarmonyOS 鸿蒙Next怎么实现当前界面的横竖屏?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中实现横竖屏切换,需在config.json中配置屏幕方向。在"abilities"节点下的对应ability中添加"orientation"字段,可选值:“unspecified”(默认)、“landscape”(横屏)、“portrait”(竖屏)或"sensor"(随传感器旋转)。例如强制竖屏配置为:“orientation”: “portrait”。此配置适用于Stage模型。UI自适应布局建议使用百分比或资源限定符(如small/medium/large)。

在HarmonyOS Next中,要实现NavDestination内的横竖屏切换,可以使用window模块的setPreferredOrientation方法。从你的代码来看,已经基本实现了这个功能,但需要注意以下几点:

  1. 确保在config.json中声明了屏幕方向权限:
"abilities": [
  {
    "orientation": "unspecified"
  }
]
  1. 对于NavDestination内部的横竖屏切换,你的实现方式是正确的。通过window.getLastWindow获取当前窗口实例,然后调用setPreferredOrientation设置方向。

  2. 如果只想切换NavDestination内部的内容方向而不影响整个窗口,可以考虑以下方案:

@State isLandscape: boolean = false

build() {
  NavDestination() {
    Column() {
      // 横竖屏切换按钮
      Button(this.isLandscape ? '竖屏' : '横屏')
        .onClick(() => {
          this.isLandscape = !this.isLandscape
        })
      
      // 根据方向调整布局
      if (this.isLandscape) {
        // 横屏布局
        Row() {
          // 横屏内容
        }
      } else {
        // 竖屏布局
        Column() {
          // 竖屏内容
        }
      }
    }
  }
}

这种方式通过状态变量控制界面布局的切换,而不是改变整个窗口方向。

回到顶部