HarmonyOS 自定义组件的使用

使用@Component自定义了组件StationInfoComponent,使用的时候直接StationInfoComponent(),报错class constructor cannot called without 'new'。

HarmonyOS
2天前
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
Heiang

当前自定义组件引用方式有问题,建议使用navigation的自定义弹窗实现,可以参考以下demo:

// DemoPage.ets
import { map, mapCommon, MapComponent } from '@kit.MapKit';
import { AsyncCallback, BusinessError } from '@ohos.base';
import { abilityAccessCtrl, common, Permissions } from '@kit.AbilityKit';
import { geoLocationManager } from '@kit.LocationKit';

@Builder
export function DemoPageBuilder() {
  DemoPage()
}
@Entry
@Component
struct DemoPage {
  @State message: string = 'Hello World';
  private callback?: AsyncCallback<map.MapComponentController>;
  private mapController?: map.MapComponentController;
  private context?: common.UIAbilityContext
  private mapOption?: mapCommon.MapOptions;
  pageInfos: NavPathStack = new NavPathStack()

  aboutToAppear() {
    AppStorage.setOrCreate('pageInfos', this.pageInfos)
    //申请位置权限
    this.context = getContext(this) as common.UIAbilityContext;
    this.mapOption = {
      position: {
        target: {
          latitude: xxx,
          longitude: xxx
        },
        zoom: 12
      },
      zoomControlsEnabled: false
    }
    // 地图初始化的回调
    this.callback = async (err, mapController) => {
      if (!err) {
        // 获取地图的控制器类,用来操作地图
        this.mapController = mapController;
        this.mapController.setCompassControlsEnabled(false) //关闭指南针
        this.mapController.setRotateGesturesEnabled(false)
        this.mapController.on("markerClick", (marker) => {
          (AppStorage.get('pageInfos') as NavPathStack).pushPathByName('StationInfoComponent', null, true)
          // StationInfoComponent()
        });
        // 执行自定义的方法
        this.customizedMethod();
      }
    };
  }

  build() {
    Navigation(this.pageInfos) {
      Stack() {
        //地图
        MapComponent({ mapOptions: this.mapOption, mapCallback: this.callback })
          .width('100%')
          .height('100%');
      }.width('100%').height('100%')
    }
  }

  // 自定义的方法
  private customizedMethod() {
    this.addCurrentLocationMarker(37.735033, 112.612375, this.mapController)
  }

  /**
   * 申请权限
   * @param permissions
   * @param context
   */
  reqPermissionsFromUser(permissions: Array<Permissions>, context: common.UIAbilityContext): void {
    let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
    // requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
    atManager.requestPermissionsFromUser(context, permissions).then((data) => {
      let grantStatus: Array<number> = data.authResults;
      let length: number = grantStatus.length;
      for (let i = 0; i < length; i++) {
        if (grantStatus[i] === 0) {
          // 用户授权,可以继续访问目标操作
          this.getCurrentLocation()
        } else {
          // 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
          return;
        }
      }
      // 授权成功
    }).catch((err: BusinessError) => {
      console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
    })
  }

  /**
   * 获取用户位置
   */
  getCurrentLocation() {
    let requestInfo: geoLocationManager.LocationRequest = {
      'priority': geoLocationManager.LocationRequestPriority.FIRST_FIX,
      'scenario': geoLocationManager.LocationRequestScenario.UNSET,
      'timeInterval': 60,
      'distanceInterval': 100,
      'maxAccuracy': 0
    };
    try {
      geoLocationManager.getCurrentLocation(requestInfo).then((location) => {
        this.addCurrentLocationMarker(location.latitude, location.longitude, this.mapController)
      })
    } catch (err) {
      console.error("err:" + JSON.stringify(err));
    }
  }

  /**
   * 添加当前位置的marker点
   * @param lat
   * @param lng
   */
  addCurrentLocationMarker(lat: number, lng: number, mapController?: map.MapComponentController) {
    let markerOptions: mapCommon.MarkerOptions = {
      position: {
        latitude: xxx,
        longitude: xxx
      },
      rotation: 0,
      visible: true,
      zIndex: 0,
      alpha: 1,
      anchorU: 0.5,
      anchorV: 1,
      clickable: true,
      draggable: true,
      flat: false,
      icon: 'position_icon.png'//需要把icon图标放在resources/rawfile目录下,使用该目录下的相对路径
    };
    const available = canIUse('SystemCapability.Map.Core')
    if (available) {
      mapController?.addMarker(markerOptions)
    }
  }
}
// StationInfoComponent.ets
import { HashMap } from '@kit.ArkTS'

@Builder
export function StationInfoComponentBuilder() {
  StationInfoComponent()
}

@Component
struct StationInfoComponent {
  @State themeName: string = ''
  @State GradientBg: Array<[ResourceColor, number]> = new Array();
  @State GradientBgMap: HashMap<string, Array<[ResourceColor, number]>> =
    new HashMap<string, Array<[ResourceColor, number]>>()

  aboutToAppear(): void {
    this.GradientBgMap.set("name1", [['#ffe3d236', 0.0], ['#ff5bb8b8', 0.5], ['#ffbf4cba', 1.0]])
    this.GradientBgMap.set("name2", [['#ff3684e3', 0.0], ['#ff545f5f', 0.5], ['#ff5cd013', 1.0]])
    this.themeName = 'name1'
    this.GradientBg = this.GradientBgMap.get("name1")
  }

  build() {
    NavDestination() {
      Column() {
        Button("点击关闭弹窗")
          .onClick(() => {
            (AppStorage.get('pageInfos') as NavPathStack).pop()
          })
        Button("点击改变渐变色背景")
          .onClick(() => {
            if (this.themeName == 'name1') {
              this.GradientBg = this.GradientBgMap.get("name2")
              this.themeName = 'name2'
            } else {
              this.GradientBg = this.GradientBgMap.get("name1")
              this.themeName = 'name1'
            }
          })
        Row()
          .width('90%')
          .height(130)
          .backgroundColor(Color.White)
          .borderRadius(14)
          .linearGradient({
            angle: 180,
            colors: this.GradientBg
          })
      }
    }
    .hideTitleBar(true)
    .mode(NavDestinationMode.DIALOG)
  }
}
// main_pages.json
{
  "src": [
  "pages/DemoPage",
  "pages/StationInfoComponent"
  ]
}
// route_map.json
{
  "routerMap": [
  {
    "name": "DemoPage",
    "pageSourceFile": "src/main/ets/pages/DemoPage.ets",
    "buildFunction": "DemoPageBuilder"
  },
  {
    "name": "StationInfoComponent",
    "pageSourceFile": "src/main/ets/pages/StationInfoComponent.ets",
    "buildFunction": "StationInfoComponentBuilder"
  }
  ]
}

注意:

(1)上面两个文件放在src/main/resources/base/profile/里面。

(2)需要在module.json5文件中添加配置route_map.json文件。

"routerMap": "$profile:route_map"
分享
微博
QQ
微信
回复
1天前
相关问题
自定义组件onMeasureSize使用
560浏览 • 1回复 待解决
HarmonyOS 定义自定义组件
207浏览 • 1回复 待解决
自定义组件使用@ObjectLink报错
1514浏览 • 1回复 待解决
HarmonyOS 使用自定义字体
414浏览 • 1回复 待解决
自定义组件使用watch监听
581浏览 • 1回复 待解决
HarmonyOS 自定义组件问题
636浏览 • 1回复 待解决
HarmonyOS 自定义滑动组件
30浏览 • 1回复 待解决
HarmonyOS如何自定义组件Controller?
526浏览 • 1回复 待解决
HarmonyOS 自定义组件事件处理
509浏览 • 1回复 待解决