HarmonyOS 鸿蒙Next XComponet 组件是否支持 expandSafeArea?

发布于 1周前 作者 sinazl 来自 鸿蒙OS

HarmonyOS 鸿蒙Next XComponet 组件是否支持 expandSafeArea? XComponet 组件是否支持 expandSafeArea, 用高德地图不支持设置该属性,如果要适配沉浸式就不能用安全区域的方案了,有其他替代方案吗?

2 回复

可以使用 setXComponentSurfaceRect + expandSafeArea 来实现

参考 demo

import { BusinessError } from '@kit.BasicServicesKit';
import { camera } from '@kit.CameraKit';
import { abilityAccessCtrl, common } from '@kit.AbilityKit';
import { image } from '@kit.ImageKit';
import { display, window } from '@kit.ArkUI';
const context = this as common.UIAbilityContext;

@Entry
@Component
struct GetFrontCameraImage {
  private xComponentController: XComponentController = new XComponentController();
  private previewOutput?: camera.PreviewOutput
  private photoOutput?: camera.PhotoOutput
  @State pixmap?: image.PixelMap = undefined
  private surfaceId : string | undefined = undefined
  private buffer: ArrayBuffer | undefined = undefined

  async getCameraImage() {
    // 1、使用系统相机框架camera模块获取物理摄像头信息。
    let cameraManager = camera.getCameraManager(context);
    let camerasInfo: Array<camera.CameraDevice> = cameraManager.getSupportedCameras();
    let cameraDevice: camera.CameraDevice = camerasInfo[0];
    // 检测相机状态
    cameraManager.on('cameraStatus', (err: BusinessError, cameraStatusInfo: camera.CameraStatusInfo) => {
      console.log(`camera : ${cameraStatusInfo.camera.cameraId}`);
      console.log(`status : : ${cameraStatusInfo.status}`);
    });
    // 2、创建并启动物理摄像头输入流通道
    // 设置为前置摄像头 camera.CameraPosition.CAMERA_POSITION_FRONT
    let cameraInput = cameraManager.createCameraInput(camera.CameraPosition.CAMERA_POSITION_BACK, camera.CameraType.CAMERA_TYPE_DEFAULT);
    await cameraInput.open();
    // 3、拿到物理摄像头信息查询摄像头支持预览流支持的输出格式,结合XComponent提供的surfaceId创建预览输出通道
    let outputCapability = cameraManager.getSupportedOutputCapability(cameraDevice, camera.SceneMode.NORMAL_PHOTO);
    let previewProfile = outputCapability.previewProfiles[0];
    let surfaceId = this.xComponentController.getXComponentSurfaceId();
    this.previewOutput = cameraManager.createPreviewOutput(previewProfile, surfaceId);
    this.photoOutput = cameraManager!.createPhotoOutput(outputCapability.photoProfiles[0]);
    this.photoOutput!.on('photoAvailable', (errCode: BusinessError, photo: camera.Photo): void => {
      if (errCode) {
        console.error(`${errCode}`)
      }
      let imageObj = photo.main;
      imageObj.getComponent(image.ComponentType.JPEG, async (errCode: BusinessError, component: image.Component) => {
        if (errCode || component === undefined) {
          return;
        }
        if (component.byteBuffer) {
          this.buffer = component.byteBuffer;
          console.log("buffer::" + this.buffer.byteLength)
          if (component.byteBuffer as ArrayBuffer) {
            let sourceOptions: image.SourceOptions = {
              sourceDensity: 120,
              sourcePixelFormat: 0, // NV21
              sourceSize: {
                height: outputCapability.previewProfiles[0].size.height,
                width: outputCapability.previewProfiles[0].size.width
              },
            }
            try {
              let imageResource = image.createImageSource(component.byteBuffer, sourceOptions);
              imageResource.createPixelMap().then(res=>{
                this.pixmap = res;
              });
            } catch (error) {
              let err = error as BusinessError;
              console.error('Failed to addOutput(photoOutput). errorCode = ' + err.code);
            }
          }
        } else {
          console.error('byteBuffer is null');
          return;
        }
      })
      imageObj.release();
    })
    // 4、创建相机会话,在会话中添加摄像头输入流和预览输出流,然后启动会话,预览画面就会在XComponent组件上送显。
    let captureSession = cameraManager.createSession(camera.SceneMode.NORMAL_PHOTO);
    captureSession.beginConfig();
    captureSession.addInput(cameraInput);
    captureSession.addOutput(this.previewOutput);
    captureSession.addOutput(this.photoOutput);
    captureSession.commitConfig()
    captureSession.start();
  }

  build() {
    Column(){
      XComponent({ id: 'xComponentId1', type: 'surface', controller: this.xComponentController })
        .onLoad(() => {
          // 在调用前确保已经获得相机权限
          this.surfaceId = this.xComponentController.getXComponentSurfaceId();
          display.getAllDisplays((err, data) => {
            let screenWidth : number = data[0].width
            let screenHeight : number = data[0].height
            let surfaceRect: SurfaceRect = { offsetX: 0, offsetY: 0, surfaceWidth: screenWidth, surfaceHeight: screenHeight }
            this.xComponentController.setXComponentSurfaceRect(surfaceRect)
          })
          abilityAccessCtrl.createAtManager().requestPermissionsFromUser(getContext(this), ['ohos.permission.CAMERA']).then(() => {
            this.getCameraImage();
          })
        })
        .width('100%')
        .expandSafeArea([SafeAreaType.SYSTEM],[SafeAreaEdge.TOP,SafeAreaEdge.BOTTOM])
    }
  }
}

参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-basic-components-xcomponent-V5#setxcomponentsurfacerect12

更多关于HarmonyOS 鸿蒙Next XComponet 组件是否支持 expandSafeArea?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


HarmonyOS 鸿蒙Next XComponent 组件支持expandSafeArea属性。在鸿蒙系统中,expandSafeArea属性通常用于控制组件是否扩展到安全区域之外。安全区域是指屏幕中不受遮挡(如刘海屏、水滴屏、圆角等)的部分,确保重要内容不被遮挡,提升用户体验。

当设置为支持expandSafeArea时,意味着该组件可以超出常规布局边界,扩展到屏幕的安全区域之外。这在设计需要全屏显示或需要利用屏幕特殊形态(如曲面屏)的应用场景中非常有用。

需要注意的是,虽然鸿蒙系统支持expandSafeArea属性,但具体实现可能因组件类型、布局方式以及系统版本等因素而有所不同。开发者在使用时,应参考最新的鸿蒙开发文档和API指南,确保组件在不同设备和系统版本上的兼容性和表现一致性。

如果在使用XComponent组件时遇到与expandSafeArea相关的问题,可能是由组件配置、布局代码或系统版本等因素引起的。建议仔细检查相关代码和配置,并参考鸿蒙官方文档进行调试。如果问题依旧没法解决请联系官网客服,官网地址是:

https://www.itying.com/category-93-b0.html

回到顶部