Compare commits
26 Commits
b58e726004
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 4cb3badb4d | |||
| 9010489037 | |||
| 3a4338c99a | |||
| ed6cbec7c9 | |||
| 7bd741a8a0 | |||
| 15223b7de4 | |||
| 7f9c4bc663 | |||
| bdfab3ab29 | |||
| ff8c5714d9 | |||
| 58ee459459 | |||
| f30b7036d6 | |||
| 1654669845 | |||
| 0cfbbb8065 | |||
| c0c8d90c4f | |||
| 6e569b3ef5 | |||
| 472fc2e574 | |||
| d303942188 | |||
| b3eb012942 | |||
|
|
b688e11f93 | ||
| 793324640e | |||
| 1d6e5653c3 | |||
| 1b925cf8fe | |||
| bab53c5e9f | |||
| 94812592c2 | |||
| 172581dff7 | |||
| e55bf2535c |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -11,3 +11,4 @@
|
||||
**/.test
|
||||
oh-package-lock.json5
|
||||
/oh-package-lock.json5
|
||||
**/**/.preview
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"string": [
|
||||
{
|
||||
"name": "app_name",
|
||||
"value": "HM4Demo"
|
||||
"value": "HMDemo"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
22
app/src/main/ets/AppAbilityStage.ets
Normal file
22
app/src/main/ets/AppAbilityStage.ets
Normal file
@@ -0,0 +1,22 @@
|
||||
import { AbilityConstant, AbilityStage, Configuration, Want } from '@kit.AbilityKit';
|
||||
|
||||
const TAG = '[AbilityStage]';
|
||||
|
||||
export default class AppAbilityStage extends AbilityStage {
|
||||
|
||||
onCreate(): void {
|
||||
console.log(TAG, "onCreate")
|
||||
}
|
||||
|
||||
// onAcceptWant(want: Want): string {
|
||||
// }
|
||||
|
||||
// onNewProcessRequest(want: Want): string {
|
||||
// }
|
||||
|
||||
onConfigurationUpdate(newConfig: Configuration): void {
|
||||
}
|
||||
|
||||
onMemoryLevel(level: AbilityConstant.MemoryLevel): void {
|
||||
}
|
||||
}
|
||||
43
app/src/main/ets/MyApp.ets
Normal file
43
app/src/main/ets/MyApp.ets
Normal file
@@ -0,0 +1,43 @@
|
||||
import { Context } from '@ohos.arkui.UIContext';
|
||||
import { window } from '@kit.ArkUI';
|
||||
import { abilityAccessCtrl } from '@kit.AbilityKit';
|
||||
import { Log } from '@devwiki/base';
|
||||
import { BusinessError } from '@kit.BasicServicesKit';
|
||||
|
||||
const TAG = '[MyApp]'
|
||||
|
||||
export class MyApp {
|
||||
|
||||
static appContext: Context;
|
||||
static uiContext: UIContext;
|
||||
static mainWindow: window.Window;
|
||||
static uiAbilityContext: Context;
|
||||
|
||||
private constructor() {
|
||||
}
|
||||
|
||||
static initAbility(uiAbilityContext: Context) {
|
||||
MyApp.uiAbilityContext = uiAbilityContext;
|
||||
MyApp.appContext = uiAbilityContext.getApplicationContext();
|
||||
}
|
||||
|
||||
static initWindow(window: window.Window) {
|
||||
MyApp.mainWindow = window;
|
||||
MyApp.uiContext = window.getUIContext();
|
||||
}
|
||||
|
||||
static requestBasicPermission() {
|
||||
let atManager = abilityAccessCtrl.createAtManager();
|
||||
try {
|
||||
atManager.requestPermissionsFromUser(MyApp.uiAbilityContext,
|
||||
['ohos.permission.INTERNET'])
|
||||
.then((data) => {
|
||||
Log.info(TAG, 'requestBasicPermission, data:' + data.permissions[0])
|
||||
})
|
||||
.catch((err: BusinessError) => {
|
||||
Log.info(TAG, 'requestBasicPermission, error:' + err.message)
|
||||
})
|
||||
} catch (err) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
|
||||
import { hilog } from '@kit.PerformanceAnalysisKit';
|
||||
import { window } from '@kit.ArkUI';
|
||||
import { MyApp } from '../MyApp';
|
||||
|
||||
const TAG = '[AppAbility]'
|
||||
|
||||
export default class AppAbility extends UIAbility {
|
||||
constructor() {
|
||||
@@ -10,6 +13,8 @@ export default class AppAbility extends UIAbility {
|
||||
|
||||
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
|
||||
MyApp.initAbility(this.context);
|
||||
MyApp.requestBasicPermission();
|
||||
}
|
||||
|
||||
onDestroy(): void {
|
||||
@@ -19,12 +24,12 @@ export default class AppAbility extends UIAbility {
|
||||
onWindowStageCreate(windowStage: window.WindowStage): void {
|
||||
// Main window is created, set main page for this ability
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
|
||||
|
||||
windowStage.loadContent('pages/Index', (err, data) => {
|
||||
if (err.code) {
|
||||
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
|
||||
return;
|
||||
}
|
||||
MyApp.initWindow(windowStage.getMainWindowSync());
|
||||
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { CommonRes, TitleBar } from '@devwiki/common_ui';
|
||||
import web_webview from '@ohos.web.webview';
|
||||
import { TitleBarMenuType } from '@devwiki/common_ui';
|
||||
import { router, window } from '@kit.ArkUI';
|
||||
import promptAction from '@ohos.promptAction';
|
||||
@@ -7,8 +6,11 @@ import { BusinessError } from '@ohos.base';
|
||||
import { Log } from '@devwiki/base';
|
||||
import { BaseLocalStorage, ScreenUtil } from '@devwiki/base';
|
||||
import { HomeItem, HomeItemGroup } from '../model/Home';
|
||||
import { CalculateAdapter } from '@devwiki/hmcalculate';
|
||||
import { MyApp } from '../MyApp';
|
||||
|
||||
import './animation/LoadingPage'
|
||||
import './animation/ScaleRotatePage'
|
||||
import { PageName } from './PageName';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
@@ -28,7 +30,9 @@ struct Index {
|
||||
{
|
||||
name: 'Component',
|
||||
items: [
|
||||
{name: 'InputPage', page: 'pages/component/InputPage'}
|
||||
{name: 'InputPage', page: 'pages/component/InputPage'},
|
||||
{name: 'ToastPage', page: 'pages/component/ToastPage'},
|
||||
{name: 'TextPage', page: 'pages/component/TextPage'}
|
||||
]
|
||||
},
|
||||
// 布局
|
||||
@@ -44,6 +48,8 @@ struct Index {
|
||||
name: "Animation",
|
||||
items: [
|
||||
{ name: 'CompTransition', page: 'pages/animation/CompTransitionPage'},
|
||||
{ name: 'Loading', page: 'pages/animation/LoadingPage'},
|
||||
{ name: 'ScaleRotatePage', page: PageName.ScaleRotatePage },
|
||||
]
|
||||
},
|
||||
// 多媒体
|
||||
@@ -58,18 +64,22 @@ struct Index {
|
||||
name: 'System',
|
||||
items: [
|
||||
{name: "Scheme", page: 'pages/system/SchemePage'},
|
||||
{name: "MVVM", page: 'pages/mvvm/HomePage'}
|
||||
{name: "MVVM", page: 'pages/mvvm/HomePage'},
|
||||
{name: "ArrayBind", page: 'pages/mvvm/ArrayBindPage'},
|
||||
{name: "SetLanguage", page: 'pages/system/SetLanguagePage'}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Map',
|
||||
items: [
|
||||
{name: 'Map', page: 'pages/map/MapPage'}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
adapter?: CalculateAdapter;
|
||||
|
||||
aboutToAppear(): void {
|
||||
ScreenUtil.getInstance().initScreenSize();
|
||||
BaseLocalStorage.getInstance().init(getContext(this));
|
||||
this.adapter = new CalculateAdapter();
|
||||
let a = this.adapter.add(1,2);
|
||||
ScreenUtil.getInstance().initScreenSize(MyApp.appContext);
|
||||
BaseLocalStorage.getInstance().init(MyApp.appContext);
|
||||
}
|
||||
|
||||
onPageShow(): void {
|
||||
@@ -107,17 +117,17 @@ struct Index {
|
||||
}).then((result: promptAction.ShowDialogSuccessResponse) => {
|
||||
if (result.index === 0) {
|
||||
// 用户点击了“取消”按钮
|
||||
Log.i('User canceled the operation.');
|
||||
Log.info('User canceled the operation.');
|
||||
} else if (result.index === 1) {
|
||||
// 用户点击了“确认”按钮
|
||||
Log.i('User confirmed the operation.');
|
||||
Log.info('User confirmed the operation.');
|
||||
// 调用router.back()方法,返回上一个页面
|
||||
router.back();
|
||||
}
|
||||
}).catch((err: Error) => {
|
||||
let message = (err as BusinessError).message
|
||||
let code = (err as BusinessError).code
|
||||
Log.i(`Invoke showDialog failed, code is ${code}, message is ${message}`);
|
||||
Log.info(`Invoke showDialog failed, code is ${code}, message is ${message}`);
|
||||
})
|
||||
return true;
|
||||
}
|
||||
@@ -144,7 +154,11 @@ struct Index {
|
||||
Divider().margin({ top: 2 });
|
||||
}.onClick(() => {
|
||||
if (item.page) {
|
||||
if (item.page.startsWith('pages/')) {
|
||||
this.getUIContext().getRouter().pushUrl({url: item.page })
|
||||
} else {
|
||||
this.getUIContext().getRouter().pushNamedRoute({name: item.page })
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -167,7 +181,7 @@ struct Index {
|
||||
})
|
||||
}
|
||||
})
|
||||
}.width('100%').margin({top: 16, bottom: 48})
|
||||
}.width('100%').margin({top: 16}).layoutWeight(1)
|
||||
}.width('100%').height('100%')
|
||||
}
|
||||
}
|
||||
5
app/src/main/ets/pages/PageName.ets
Normal file
5
app/src/main/ets/pages/PageName.ets
Normal file
@@ -0,0 +1,5 @@
|
||||
|
||||
export enum PageName {
|
||||
|
||||
ScaleRotatePage = 'animation/ScaleRotatePage'
|
||||
}
|
||||
40
app/src/main/ets/pages/animation/LoadingPage.ets
Normal file
40
app/src/main/ets/pages/animation/LoadingPage.ets
Normal file
@@ -0,0 +1,40 @@
|
||||
import { CommonRes } from '@devwiki/common_ui/Index';
|
||||
import { PageName } from '../../utils/PageRouter';
|
||||
import { curves } from '@kit.ArkUI';
|
||||
|
||||
@Entry({ routeName: PageName.loadingPage })
|
||||
@Component
|
||||
struct LoadingPage {
|
||||
@State animate: boolean = false;
|
||||
@State rotateValue: number = 0;
|
||||
|
||||
@Prop @Watch('onVisibleChanged')visible: boolean = false;
|
||||
onVisibleChanged() {
|
||||
if (this.visible) {
|
||||
this.animate = true;
|
||||
// 组件一的rotate属性发生变化,所以会给组件一添加rotate旋转动画
|
||||
this.rotateValue = this.animate ? 360 : 0;
|
||||
}else {
|
||||
this.animate = false;
|
||||
}
|
||||
}
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
|
||||
Image(CommonRes.getImage('ic_loading'))
|
||||
.rotate({ angle: this.rotateValue })
|
||||
.width(32).height(32).fillColor('#2196F3')
|
||||
.animation({
|
||||
curve: curves.initCurve(Curve.Linear),
|
||||
playMode: PlayMode.Normal,
|
||||
iterations: -1,
|
||||
duration: 1000
|
||||
}).visibility(this.visible ? Visibility.Visible : Visibility.None)
|
||||
|
||||
Button('change').width('60%').height(36).onClick(() =>{
|
||||
this.visible = !this.visible;
|
||||
}).margin({top: 24})
|
||||
}.width('100%').height('100%').justifyContent(FlexAlign.Center)
|
||||
}
|
||||
}
|
||||
67
app/src/main/ets/pages/animation/ScaleRotatePage.ets
Normal file
67
app/src/main/ets/pages/animation/ScaleRotatePage.ets
Normal file
@@ -0,0 +1,67 @@
|
||||
import { PageName } from '../PageName';
|
||||
|
||||
@Component
|
||||
@Entry({routeName: PageName.ScaleRotatePage})
|
||||
struct ScaleRotatePage {
|
||||
|
||||
@State orderId:string = ''
|
||||
@State rootJustifyContent: FlexAlign = FlexAlign.Start
|
||||
|
||||
@State showQRAnimation: boolean= false
|
||||
@State qrColumnHeight: Length = ''
|
||||
@State qrJustifyContent: FlexAlign = FlexAlign.Start
|
||||
|
||||
@State showBarcodeAnimation : boolean = false;
|
||||
@State barcodeHeight: Length = ''
|
||||
@State barcodeAngle: number = 0
|
||||
|
||||
@Builder
|
||||
ScanBarCodeDialog(){
|
||||
|
||||
}
|
||||
|
||||
private ScanBarCodeDialogController: CustomDialogController = new CustomDialogController({
|
||||
builder: this.ScanBarCodeDialog,
|
||||
autoCancel: true,
|
||||
alignment: DialogAlignment.Center,
|
||||
customStyle: true,
|
||||
openAnimation: {
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
build() {
|
||||
|
||||
Column(){
|
||||
Text('Title')
|
||||
|
||||
Column(){
|
||||
Image($r('app.media.ic_eye_off')).width(200).height(200).onClick(() =>{
|
||||
|
||||
})
|
||||
Text('Order Id:' + this.orderId).visibility(this.showQRAnimation ? Visibility.Visible : Visibility.None)
|
||||
}.width('100%').visibility(this.showBarcodeAnimation ? Visibility.None : Visibility.Visible)
|
||||
.animation({
|
||||
duration: 1000
|
||||
})
|
||||
|
||||
Text('Order Id:' + this.orderId).visibility(this.showQRAnimation || this.showBarcodeAnimation ? Visibility.None : Visibility.Visible)
|
||||
|
||||
Column(){
|
||||
|
||||
Text('Order Id:' + this.orderId).visibility(this.showBarcodeAnimation ? Visibility.Visible : Visibility.None)
|
||||
|
||||
Image($r('app.media.ic_eye_off')).width(400).height(100).onClick(() =>{
|
||||
})
|
||||
}.visibility(this.showQRAnimation ? Visibility.None : Visibility.Visible)
|
||||
.rotate({ centerX: '50%', centerY: '50%', angle: this.barcodeAngle})
|
||||
.animation({
|
||||
duration: 1000
|
||||
})
|
||||
|
||||
|
||||
}.width('100%').height('100%').alignItems(HorizontalAlign.Center).justifyContent(this.rootJustifyContent)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -2,7 +2,7 @@ import { CommonRes } from '@devwiki/common_ui/Index'
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
export struct SVGPage {
|
||||
struct SVGPage {
|
||||
build() {
|
||||
Column() {
|
||||
Text().width(96).height(96).backgroundColor($r('app.media.ic_eye_off'))
|
||||
|
||||
@@ -3,6 +3,27 @@
|
||||
@Component
|
||||
struct TextPage {
|
||||
|
||||
@State states: string[] = ['1', '2', '3', '4'];
|
||||
|
||||
build() {
|
||||
Column(){
|
||||
Button('Change').onClick(() => {
|
||||
this.states[3] = '999'
|
||||
})
|
||||
List(){
|
||||
ForEach(this.states, (state: string, index: number) => {
|
||||
ListItem(){
|
||||
Column(){
|
||||
Text(state).width(this.getWidth(state, index))
|
||||
Divider().width('90%')
|
||||
}
|
||||
}
|
||||
})
|
||||
}.height('100%').width('100')
|
||||
}.width('100%')
|
||||
}
|
||||
|
||||
getWidth(title: string, index: number): Length {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
41
app/src/main/ets/pages/component/ToastPage.ets
Normal file
41
app/src/main/ets/pages/component/ToastPage.ets
Normal file
@@ -0,0 +1,41 @@
|
||||
import { Toast } from '@devwiki/common_ui/'
|
||||
|
||||
@Observed
|
||||
class ToastViewMode {
|
||||
|
||||
showToast?: (msg: ResourceStr) => void;
|
||||
|
||||
showHint(msg: ResourceStr) {
|
||||
this.showToast?.(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct ToastPage {
|
||||
|
||||
@Provide toastVM: ToastViewMode = new ToastViewMode();
|
||||
|
||||
aboutToAppear(): void {
|
||||
this.toastVM.showToast = (msg: ResourceStr) => {
|
||||
Toast.showToast(msg, true);
|
||||
}
|
||||
}
|
||||
|
||||
build() {
|
||||
|
||||
Column(){
|
||||
Button("ShowDefault").width('80%').height(36).onClick(() =>{
|
||||
Toast.showToast("Test Default")
|
||||
})
|
||||
|
||||
Button("ShowTopmost").width('80%').height(36).onClick(() =>{
|
||||
Toast.showToast("Test Topmost", true)
|
||||
}).margin({ top: 16 })
|
||||
|
||||
Button("VM Show").width('80%').height(36).onClick(() =>{
|
||||
this.toastVM.showHint("test vm Show")
|
||||
}).margin({ top: 16 })
|
||||
}.height('100%').width('100%').justifyContent(FlexAlign.Center)
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ import { ComponentConst } from '@devwiki/common_ui/Index'
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
export struct RelativeContainerPage {
|
||||
struct RelativeContainerPage {
|
||||
|
||||
build() {
|
||||
RelativeContainer() {
|
||||
@@ -12,7 +12,7 @@ export struct RelativeContainerPage {
|
||||
top: { anchor: ComponentConst.ContainerId, align: VerticalAlign.Top },
|
||||
left: { anchor: ComponentConst.ContainerId, align: HorizontalAlign.Start },
|
||||
bottom: { anchor: ComponentConst.ContainerId, align: VerticalAlign.Bottom }
|
||||
}).id('left_menu')
|
||||
}).id('left_menu0')
|
||||
|
||||
Button(){
|
||||
Text("2222").height(64)
|
||||
@@ -21,7 +21,7 @@ export struct RelativeContainerPage {
|
||||
top: { anchor: ComponentConst.ContainerId, align: VerticalAlign.Top },
|
||||
right: { anchor: ComponentConst.ContainerId, align: HorizontalAlign.End },
|
||||
bottom: { anchor: ComponentConst.ContainerId, align: VerticalAlign.Bottom }
|
||||
}).id('right_menu')
|
||||
}).id('right_menu0')
|
||||
}.height(64).width('100%').backgroundColor(Color.Red)
|
||||
}
|
||||
}
|
||||
58
app/src/main/ets/pages/map/MapPage.ets
Normal file
58
app/src/main/ets/pages/map/MapPage.ets
Normal file
@@ -0,0 +1,58 @@
|
||||
import { abilityAccessCtrl, bundleManager, common, PermissionRequestResult, Permissions } from '@kit.AbilityKit';
|
||||
import { geoLocationManager } from '@kit.LocationKit';
|
||||
import { BusinessError } from '@kit.BasicServicesKit';
|
||||
import { LocationHelper } from '../../utils/LocationHelper';
|
||||
|
||||
@Component
|
||||
@Entry({routeName: 'MapPage'})
|
||||
struct MapPage {
|
||||
@State isShowLocationPopup: boolean = false
|
||||
appName: string = ''
|
||||
@State isLocationPermission: boolean = false;
|
||||
@State locText: string = ''
|
||||
|
||||
locationHelper: LocationHelper = new LocationHelper(getContext(this) as common.UIAbilityContext);
|
||||
|
||||
@Builder
|
||||
locationViewBuilder() {
|
||||
Row() {
|
||||
Text('开启定位权限').fontSize(15);
|
||||
Button('去开启')
|
||||
.type(ButtonType.Normal)
|
||||
.height(24)
|
||||
.borderRadius(12)
|
||||
.width(60)
|
||||
.backgroundColor(Color.Red)
|
||||
.onClick(() => {
|
||||
this.locationHelper.getLocationAddress( 31.12, 121.11, 1, (error: BusinessError, data: geoLocationManager.GeoAddress[]) => {
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
SymbolGlyph($r('sys.symbol.xmark')).width(24).height(24).borderRadius(12).onClick(() => {
|
||||
this.isShowLocationPopup = false;
|
||||
})
|
||||
}
|
||||
.height(40)
|
||||
.alignItems(VerticalAlign.Center)
|
||||
.padding(5)
|
||||
.position({ x: 7, y: 50 })
|
||||
.zIndex(999)
|
||||
.backgroundColor('#123333')
|
||||
.borderRadius(10)
|
||||
.opacity(0.7)
|
||||
}
|
||||
|
||||
build() {
|
||||
|
||||
Column(){
|
||||
this.locationViewBuilder();
|
||||
Text(this.locText);
|
||||
}.width('100%').height('100%')
|
||||
}
|
||||
|
||||
aboutToAppear(): void {
|
||||
this.locationHelper.requestPermissionsFromUser((allowScope: boolean, allowPrecision: boolean) => {
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -137,7 +137,7 @@ async function release() {
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
export struct AudioPlayerPage {
|
||||
struct AudioPlayerPage {
|
||||
|
||||
build() {
|
||||
}
|
||||
|
||||
25
app/src/main/ets/pages/mvvm/ArrayBindPage.ets
Normal file
25
app/src/main/ets/pages/mvvm/ArrayBindPage.ets
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
export struct ArrayBindPage {
|
||||
|
||||
@State firstDatas: string[] = ["1"];
|
||||
@State secondDatas: string[] = ["2"]
|
||||
|
||||
build() {
|
||||
Column(){
|
||||
|
||||
Text(this.firstDatas[0]);
|
||||
Text(this.secondDatas[0]).margin({top: 16})
|
||||
Button("Change").margin({top: 16}).onClick(() => {
|
||||
let first = this.firstDatas;
|
||||
this.changeFirstIndex(first);
|
||||
this.changeFirstIndex(this.secondDatas);
|
||||
})
|
||||
}.width('100%').height('100%')
|
||||
}
|
||||
|
||||
changeFirstIndex(datas: string[]) {
|
||||
datas[0] = '111'
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Emitter, EmitterItem } from '@devwiki/base';
|
||||
import { Toast } from '../../utils/Toast';
|
||||
import { Toast } from '@devwiki/common_ui';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
export struct HomePage {
|
||||
struct HomePage {
|
||||
|
||||
@Provide tv1ViewModel: TabView1ViewModel = new TabView1ViewModel();
|
||||
@Provide tv2ViewModel: TabView2ViewModel = new TabView2ViewModel();
|
||||
|
||||
45
app/src/main/ets/pages/net/APIModel.ts
Normal file
45
app/src/main/ets/pages/net/APIModel.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { BusinessError } from '@ohos.base';
|
||||
|
||||
export class APIQuery extends Map<string, string|number|boolean> { }
|
||||
|
||||
export interface APIHeader {
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
export enum APIRequestMethod {
|
||||
GET, POST, PUT, DELETE
|
||||
}
|
||||
|
||||
export class APIRequest {
|
||||
url: string = "";
|
||||
method: APIRequestMethod = APIRequestMethod.POST;
|
||||
extraData?: string | Object | ArrayBuffer;
|
||||
header?: APIHeader[];
|
||||
}
|
||||
|
||||
export class APIResult<T> {
|
||||
httpCode: number;
|
||||
businessError?: BusinessError;
|
||||
error?: APIError;
|
||||
data?: T;
|
||||
}
|
||||
|
||||
export interface APIError{
|
||||
errors: string[];
|
||||
message: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface Organization {
|
||||
id: number;
|
||||
name: string;
|
||||
full_name: string;
|
||||
email: string;
|
||||
avatar_url: string;
|
||||
description: string;
|
||||
website: string;
|
||||
location: string;
|
||||
visibility: string;
|
||||
repo_admin_change_team_access: boolean;
|
||||
username: string;
|
||||
}
|
||||
123
app/src/main/ets/pages/net/RestAPI.ets
Normal file
123
app/src/main/ets/pages/net/RestAPI.ets
Normal file
@@ -0,0 +1,123 @@
|
||||
import http from '@ohos.net.http';
|
||||
import { Log } from '@devwiki/base/Index';
|
||||
import { APIError, APIHeader, APIQuery, APIRequestMethod, Organization } from './APIModel';
|
||||
import { APIRequest } from './APIModel';
|
||||
import { APIResult } from './APIModel';
|
||||
import axios from '@ohos/axios';
|
||||
import { Axios } from '@ohos/axios';
|
||||
|
||||
const TAG = '[RestAPI]'
|
||||
|
||||
export class RestAPI {
|
||||
|
||||
private baseUrl: string ='https://gitea.com/api/v1';
|
||||
private readonly timeout = 10000;
|
||||
private baseQuery: string = '?=0';
|
||||
private defaultHeaders: APIHeader[] = [
|
||||
{ "connection" : "keep-alive" },
|
||||
{ 'accept-encoding' : 'gzip, deflate, br, zstd' },
|
||||
{ 'accept-language' : 'zh-CN,zh;q=0.9,en;q=0.8' }
|
||||
];
|
||||
|
||||
public getAllOrganizations(callback: (result: APIResult<Organization[]>) => void) {
|
||||
let path = '/orgs'
|
||||
let url = this.getUrl(path);
|
||||
Log.info(TAG, 'getOrgByName url:' + url);
|
||||
this.request({
|
||||
url: url,
|
||||
method: APIRequestMethod.GET
|
||||
}, callback);
|
||||
}
|
||||
|
||||
public getAllOrganizationsByPage(page: number, limit: number, callback: (result: APIResult<Organization[]>) => void) {
|
||||
let path = '/orgs'
|
||||
let extraQuery = new APIQuery()
|
||||
extraQuery.set('page', page);
|
||||
extraQuery.set('limit', limit);
|
||||
let url = this.getUrl(path, extraQuery);
|
||||
Log.info(TAG, 'getOrgByName url:' + url);
|
||||
this.request({
|
||||
url: url,
|
||||
method: APIRequestMethod.GET
|
||||
}, callback);
|
||||
}
|
||||
|
||||
public getOrgByName(name: string, callback: (result: APIResult<Organization>) => void) {
|
||||
let path = `/orgs/${name}`;
|
||||
let url = this.getUrl(path);
|
||||
Log.info(TAG, 'getOrgByName url:' + url);
|
||||
this.request({
|
||||
url: url,
|
||||
method: APIRequestMethod.GET
|
||||
}, callback);
|
||||
}
|
||||
|
||||
request<T>(apiReq: APIRequest, callback: (result: APIResult<T>) => void) {
|
||||
Log.info(TAG, 'request, url:' + apiReq.url)
|
||||
let httpRequest = http.createHttp();
|
||||
let option:http.HttpRequestOptions = this.createHttpRequestOption(apiReq);
|
||||
httpRequest.request(apiReq.url, option, (error, resp) =>{
|
||||
let result: APIResult<T> = new APIResult();
|
||||
if (!error) {
|
||||
Log.info(TAG, 'result, httpCode:' + result.httpCode + ', data:' + resp.result?.toString())
|
||||
result.httpCode = resp.responseCode;
|
||||
try {
|
||||
if (resp.responseCode == http.ResponseCode.OK) {
|
||||
result.data = JSON.parse(resp.result?.toString()) as T
|
||||
} else {
|
||||
result.error = JSON.parse(resp.result?.toString()) as APIError;
|
||||
}
|
||||
} catch (e) {
|
||||
Log.error(TAG, 'result json parse error:' + e)
|
||||
}
|
||||
callback?.(result);
|
||||
} else {
|
||||
result.businessError = error;
|
||||
callback?.(result);
|
||||
Log.error(TAG, `request ${apiReq.url} failed, code:${error.code}, message:${error.message}`)
|
||||
}
|
||||
httpRequest.destroy();
|
||||
});
|
||||
}
|
||||
|
||||
private createHttpRequestOption(apiReq: APIRequest): http.HttpRequestOptions{
|
||||
let headers: APIHeader[] = this.defaultHeaders;
|
||||
if (apiReq.header) {
|
||||
apiReq.header.forEach((header) =>{
|
||||
headers.push(header);
|
||||
})
|
||||
}
|
||||
let method: http.RequestMethod = http.RequestMethod.GET;
|
||||
if (apiReq.method == APIRequestMethod.POST) {
|
||||
method = http.RequestMethod.POST;
|
||||
} else if (apiReq.method == APIRequestMethod.PUT) {
|
||||
method = http.RequestMethod.PUT;
|
||||
} else if (apiReq.method == APIRequestMethod.DELETE) {
|
||||
method = http.RequestMethod.DELETE;
|
||||
} else {
|
||||
method = http.RequestMethod.GET;
|
||||
}
|
||||
return {
|
||||
method: method,
|
||||
extraData : apiReq.extraData,
|
||||
readTimeout : this.timeout,
|
||||
connectTimeout: this.timeout,
|
||||
expectDataType: http.HttpDataType.STRING,
|
||||
header: headers,
|
||||
usingProtocol: http.HttpProtocol.HTTP1_1
|
||||
};
|
||||
}
|
||||
|
||||
private getUrl(path: string, extraQuery?: APIQuery): string {
|
||||
let url = `${this.baseUrl}${path}${this.baseQuery}`;
|
||||
if (extraQuery) {
|
||||
for (let key of extraQuery.keys()) {
|
||||
url += `&${key}=${extraQuery.get(key)}`
|
||||
}
|
||||
}
|
||||
Log.debug(TAG, `get url, path: ${path}, url:${url}`)
|
||||
return url;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,44 +1,95 @@
|
||||
import { Log } from '@devwiki/base/Index';
|
||||
import axios, { AxiosError, AxiosResponse } from '@ohos/axios'
|
||||
import http from '@ohos.net.http';
|
||||
import { RestAPI } from './RestAPI';
|
||||
import { Organization } from './APIModel';
|
||||
import { convertxml, util } from '@kit.ArkTS';
|
||||
|
||||
const TAG = '[RestAPIPage]'
|
||||
|
||||
@Entry({routeName: "RestAPIPage"})
|
||||
@Component
|
||||
export struct RestAPIPage {
|
||||
struct RestAPIPage {
|
||||
|
||||
@State viewModel: RestAPIViewModel = new RestAPIViewModel();
|
||||
|
||||
build() {
|
||||
Row() {
|
||||
Column() {
|
||||
Flex({
|
||||
justifyContent: FlexAlign.SpaceBetween
|
||||
justifyContent: FlexAlign.Start,
|
||||
direction: FlexDirection.Column,
|
||||
alignItems: ItemAlign.Center
|
||||
}) {
|
||||
Button("Get").onClick(() =>{
|
||||
this.viewModel.getServerVersion();
|
||||
|
||||
Refresh({
|
||||
refreshing: $$this.viewModel.refreshing,
|
||||
}){
|
||||
List(){
|
||||
ForEach(this.viewModel.orsg, (org: Organization, index: number) =>{
|
||||
ListItem(){
|
||||
Row() {
|
||||
Image(org.avatar_url).width(36).height(36).objectFit(ImageFit.Contain)
|
||||
Text(org.name)
|
||||
}.justifyContent(FlexAlign.Start).alignItems(VerticalAlign.Center).height(48)
|
||||
}
|
||||
})
|
||||
}.width('100%').height('100%').layoutWeight(1)
|
||||
}.pullToRefresh(true)
|
||||
.onRefreshing(() =>{
|
||||
this.viewModel.getAllOrgs();
|
||||
})
|
||||
|
||||
Text(this.viewModel.serverVersion).backgroundColor(Color.Blue).flexGrow(1);
|
||||
}
|
||||
}.justifyContent(FlexAlign.Start).alignItems(VerticalAlign.Center).width('80%').backgroundColor(Color.Green)
|
||||
Button("GetByHttp").onClick(() =>{
|
||||
this.viewModel.getServerVersionByHttp();
|
||||
}).margin({top: 20})
|
||||
}.width('80%')
|
||||
}.width('100%')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class RestAPIViewModel {
|
||||
|
||||
serverVersion: string = '123'
|
||||
orsg: Organization[] = []
|
||||
refreshing: boolean = false;
|
||||
|
||||
async getServerVersion() {
|
||||
await axios({
|
||||
method: "post",
|
||||
url: 'https://music.devwiki.net/rest/ping.view?v=1.16.1&c=myapp&f=json'
|
||||
}).then((response: AxiosResponse) => {
|
||||
if (response.status == 200) {
|
||||
let version:string = response.data['subsonic-response']['serverVersion'];
|
||||
this.serverVersion = version;
|
||||
Log.i(`serverVersion: ${this.serverVersion}`)
|
||||
private restAPI: RestAPI = new RestAPI();
|
||||
|
||||
getAllOrgs() {
|
||||
this.restAPI.getAllOrganizations((result) => {
|
||||
if (result.data) {
|
||||
this.orsg = result.data;
|
||||
}
|
||||
}).catch((error: AxiosError) => {
|
||||
Log.e(error.message);
|
||||
this.refreshing = false;
|
||||
})
|
||||
}
|
||||
|
||||
getServerVersionByHttp() {
|
||||
let request = http.createHttp();
|
||||
let header: Map<string, string> = new Map();
|
||||
request.request('https://qt.gtimg.cn/q=s_sh000001', {
|
||||
header: {
|
||||
'Content-Type': 'text/html; charset=GBK'
|
||||
},
|
||||
expectDataType: http.HttpDataType.ARRAY_BUFFER
|
||||
}).then(res => {
|
||||
let data = this.gbkToUTF8(res.result as ArrayBuffer);
|
||||
Log.info(res.responseCode.toString());
|
||||
})
|
||||
}
|
||||
|
||||
gbkToUTF8(content: ArrayBuffer): string {
|
||||
let textDecoderOptions: util.TextDecoderOptions = {
|
||||
fatal: false,
|
||||
ignoreBOM : true
|
||||
}
|
||||
let decodeWithStreamOptions: util.DecodeWithStreamOptions = {
|
||||
stream: true
|
||||
}
|
||||
let textDecoder = util.TextDecoder.create('gbk', textDecoderOptions);
|
||||
let retStr = textDecoder.decodeWithStream( new Uint8Array(content) , decodeWithStreamOptions);
|
||||
return retStr;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -26,10 +26,10 @@ class TcpSocket {
|
||||
let message = String.fromCharCode(messages);
|
||||
messageView += message;
|
||||
}
|
||||
Log.i(`receive message: ${messageView}`)
|
||||
Log.info(`receive message: ${messageView}`)
|
||||
})
|
||||
this.tcp.on('error', (error) => {
|
||||
Log.i(`tcp error: ${error.message}`)
|
||||
Log.info(`tcp error: ${error.message}`)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -40,19 +40,19 @@ class TcpSocket {
|
||||
this.tcp.bind(address)
|
||||
this.tcp.connect(this.connectOptions, (error) => {
|
||||
if (error) {
|
||||
Log.e(`connect fail: ${error.message}`);
|
||||
Log.error(`connect fail: ${error.message}`);
|
||||
return;
|
||||
}
|
||||
Log.i('connect success')
|
||||
Log.info('connect success')
|
||||
})
|
||||
}
|
||||
|
||||
send(text: string) {
|
||||
let option: socket.TCPSendOptions = { data: text}
|
||||
this.tcp.send(option).then(() => {
|
||||
Log.i(`send data: ${text} success`)
|
||||
Log.info(`send data: ${text} success`)
|
||||
}).catch((error: BusinessError) => {
|
||||
Log.e(`send data: ${text} error: ${error.message}`)
|
||||
Log.error(`send data: ${text} error: ${error.message}`)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -60,7 +60,7 @@ class TcpSocket {
|
||||
|
||||
@Component
|
||||
@Entry
|
||||
export struct TcpSocketPage {
|
||||
struct TcpSocketPage {
|
||||
|
||||
tcpSocket: TcpSocket = new TcpSocket();
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { common, Want } from '@kit.AbilityKit';
|
||||
|
||||
@Component
|
||||
@Entry
|
||||
export struct SchemePage {
|
||||
struct SchemePage {
|
||||
build() {
|
||||
Column() {
|
||||
TitleBar({
|
||||
@@ -13,16 +13,22 @@ export struct SchemePage {
|
||||
}
|
||||
})
|
||||
|
||||
Button("Open").width(120).height(36).onClick(() => {
|
||||
this.openScheme()
|
||||
Button("OpenApp").width(120).height(36).onClick(() => {
|
||||
this.openScheme('alipays://platformapi/startapp?appId=20000001')
|
||||
}).margin({ top: 48 })
|
||||
|
||||
Button("OpenStore").width(120).height(36).onClick(() => {
|
||||
this.openScheme('store://appgallery.huawei.com/app/detail?id=com.alipay.mobile.client')
|
||||
}).margin({ top: 48 })
|
||||
}
|
||||
}
|
||||
|
||||
openScheme() {
|
||||
openScheme(uri: string) {
|
||||
let context = getContext(this) as common.UIAbilityContext;
|
||||
let wantInfo: Want = {
|
||||
uri: 'https://devwiki.net'
|
||||
// action: 'ohos.want.action.viewData',
|
||||
// entities: ['entity.system.browsable'],
|
||||
uri: uri
|
||||
}
|
||||
context.startAbility(wantInfo);
|
||||
}
|
||||
|
||||
48
app/src/main/ets/pages/system/SetLanguagePage.ets
Normal file
48
app/src/main/ets/pages/system/SetLanguagePage.ets
Normal file
@@ -0,0 +1,48 @@
|
||||
import { TitleBar } from '@devwiki/common_ui';
|
||||
import { i18n } from '@kit.LocalizationKit';
|
||||
import { Log } from '@devwiki/base';
|
||||
|
||||
const TAG = '[SetLanguagePage]'
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct SetLanguagePage {
|
||||
private readonly languageGroup = "languageGroup"
|
||||
@State selectedLanguage: string = 'zh-Hans';
|
||||
|
||||
aboutToAppear(): void {
|
||||
let languages:string[] = i18n.System.getSystemLanguages();
|
||||
languages.forEach((value, index) => {
|
||||
Log.info(TAG, `${index.toString()}:${value}`)
|
||||
})
|
||||
}
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
TitleBar({
|
||||
title: $r('app.string.set_language_title')
|
||||
});
|
||||
Row() {
|
||||
Text('简体中文');
|
||||
Radio({ group: this.languageGroup, value: 'zh-Hans' }).checked(this.selectedLanguage == 'zh-Hans')
|
||||
.onChange(isChecked => {
|
||||
if (isChecked) {
|
||||
i18n.System.setAppPreferredLanguage('zh-Hans')
|
||||
this.selectedLanguage = 'zh-Hans'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Row() {
|
||||
Text('英文');
|
||||
Radio({ group: this.languageGroup, value: 'en-US' }).checked(this.selectedLanguage == 'en-US')
|
||||
.onChange(isChecked => {
|
||||
if (isChecked) {
|
||||
i18n.System.setAppPreferredLanguage('en-US')
|
||||
this.selectedLanguage = 'en-US'
|
||||
}
|
||||
});
|
||||
}
|
||||
}.width('100%').height('100%')
|
||||
}
|
||||
}
|
||||
42
app/src/main/ets/pages/system/SystemEventPage.ets
Normal file
42
app/src/main/ets/pages/system/SystemEventPage.ets
Normal file
@@ -0,0 +1,42 @@
|
||||
import commonEventManager from '@ohos.commonEventManager';
|
||||
import Base from '@ohos.base';
|
||||
|
||||
|
||||
@Component
|
||||
@Entry
|
||||
export struct SystemEventPage {
|
||||
// 用于保存创建成功的订阅者对象,后续使用其完成订阅及退订的动作
|
||||
subscriber: commonEventManager.CommonEventSubscriber | null = null;
|
||||
// 订阅者信息
|
||||
subscribeInfo: commonEventManager.CommonEventSubscribeInfo = {
|
||||
events: ["usual.event.SCREEN_OFF"], // 订阅灭屏公共事件
|
||||
}
|
||||
|
||||
aboutToAppear(): void {
|
||||
// 创建订阅者回调
|
||||
commonEventManager.createSubscriber(this.subscribeInfo, (err: Base.BusinessError, data: commonEventManager.CommonEventSubscriber) => {
|
||||
if (err) {
|
||||
console.error(`Failed to create subscriber. Code is ${err.code}, message is ${err.message}`);
|
||||
return;
|
||||
}
|
||||
console.info('Succeeded in creating subscriber.');
|
||||
this.subscriber = data;
|
||||
// 订阅公共事件回调
|
||||
})
|
||||
|
||||
// 订阅公共事件回调
|
||||
if (this.subscriber !== null) {
|
||||
commonEventManager.subscribe(this.subscriber, (err: Base.BusinessError, data: commonEventManager.CommonEventData) => {
|
||||
if (err) {
|
||||
console.error(`Failed to subscribe common event. Code is ${err.code}, message is ${err.message}`);
|
||||
return;
|
||||
}
|
||||
})
|
||||
} else {
|
||||
console.error(`Need create subscriber`);
|
||||
}
|
||||
}
|
||||
|
||||
build() {
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
@Entry({routeName: "TimerPage"})
|
||||
@Component
|
||||
export struct TimerPage {
|
||||
struct TimerPage {
|
||||
build() {
|
||||
}
|
||||
}
|
||||
@@ -5,12 +5,12 @@ import { TitleBar } from '@devwiki/common_ui/src/main/ets/component/TitleBar';
|
||||
@CustomDialog
|
||||
export struct WebPageDialog {
|
||||
@StorageLink(ScreenUtil.isPortraitKey) isPortrait: boolean = true;
|
||||
dialogController: CustomDialogController;
|
||||
dialogController?: CustomDialogController;
|
||||
|
||||
build() {
|
||||
WebPage({
|
||||
onTitleBarLeftClick: () => {
|
||||
this.dialogController.close();
|
||||
this.dialogController?.close();
|
||||
}
|
||||
}).height(this.isPortrait ? '95%' : '90%').width(this.isPortrait ? '100%' : '50%')
|
||||
}
|
||||
@@ -18,7 +18,7 @@ export struct WebPageDialog {
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
export struct WebDialogPage {
|
||||
struct WebDialogPage {
|
||||
|
||||
dialogController: CustomDialogController = new CustomDialogController({
|
||||
builder: WebPageDialog(),
|
||||
|
||||
@@ -30,7 +30,6 @@ export struct WebPage {
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
RelativeContainer() {
|
||||
TitleBar({
|
||||
title: this.viewModel.pageTitle,
|
||||
onLeftClicked: () => {
|
||||
@@ -44,12 +43,7 @@ export struct WebPage {
|
||||
// 必须这么写 onTitleBarRightClick内部的代码才执行,
|
||||
// 直接 onRightClicked: this.onTitleBarRightClick 这么写, 代码不执行
|
||||
onRightClicked: (event: ClickEvent) => { this.onTitleBarRightClick(event)},
|
||||
})
|
||||
.width('100%')
|
||||
.alignRules({
|
||||
top: { anchor: ComponentConst.ContainerId, align: VerticalAlign.Top },
|
||||
left: { anchor: ComponentConst.ContainerId, align: HorizontalAlign.Start }
|
||||
}).id("title_bar");
|
||||
}).width('100%')
|
||||
|
||||
Divider().alignRules({
|
||||
top: { anchor: "title_bar", align: VerticalAlign.Bottom },
|
||||
@@ -57,12 +51,7 @@ export struct WebPage {
|
||||
}).width('100%').id("divider")
|
||||
|
||||
WebView({ param: this.viewModel.webParam, controller: this.webViewController }).width('100%')
|
||||
.alignRules({
|
||||
top: { anchor: "divider", align: VerticalAlign.Bottom },
|
||||
left: { anchor: ComponentConst.ContainerId, align: HorizontalAlign.Start },
|
||||
bottom: { anchor: ComponentConst.ContainerId, align: VerticalAlign.Bottom }
|
||||
}).id("host_web")
|
||||
}.width('100%').height('100%')
|
||||
.layoutWeight(1).borderWidth(1).borderColor(Color.Red)
|
||||
}.width('100%').height('100%')
|
||||
}
|
||||
}
|
||||
@@ -88,7 +77,7 @@ class WebPageController extends WebViewController {
|
||||
class WebPageViewModel {
|
||||
|
||||
webParam: WebViewParam = {
|
||||
webUrl: "https://devwiki.net"
|
||||
webUrl: "https://baidu.com"
|
||||
};
|
||||
|
||||
pageTitle: ResourceStr = "WebPage";
|
||||
|
||||
105
app/src/main/ets/utils/LocationHelper.ets
Normal file
105
app/src/main/ets/utils/LocationHelper.ets
Normal file
@@ -0,0 +1,105 @@
|
||||
import { abilityAccessCtrl, bundleManager, common, PermissionRequestResult, Permissions } from '@kit.AbilityKit';
|
||||
import { BusinessError } from '@kit.BasicServicesKit';
|
||||
import { geoLocationManager } from '@kit.LocationKit';
|
||||
|
||||
const locationPermission: Permissions[] = ['ohos.permission.LOCATION', 'ohos.permission.APPROXIMATELY_LOCATION'];
|
||||
|
||||
export class LocationHelper {
|
||||
|
||||
appInfo: bundleManager.BundleInfo;
|
||||
context: common.UIAbilityContext;
|
||||
atManager: abilityAccessCtrl.AtManager;
|
||||
|
||||
constructor(context: common.UIAbilityContext) {
|
||||
this.context = context;
|
||||
this.atManager = abilityAccessCtrl.createAtManager();
|
||||
this.appInfo = bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION) // 获取应用信息
|
||||
}
|
||||
|
||||
checkLocationPermission(callback: (isAllow: boolean) => void) {
|
||||
let status = this.atManager.checkAccessTokenSync(this.appInfo.appInfo.accessTokenId, locationPermission[0])
|
||||
callback(status === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED)
|
||||
}
|
||||
|
||||
gotoSystemSetting() {
|
||||
|
||||
}
|
||||
|
||||
// openLocation(callback:(address: string) => void) {
|
||||
// let options: AMapLocationOption = {
|
||||
// priority: geoLocationManager.LocationRequestPriority.FIRST_FIX, //定位优先配置选项
|
||||
// scenario: geoLocationManager.LocationRequestScenario.UNSET, //定位场景设置
|
||||
// timeInterval: 2, //定位时间间隔
|
||||
// distanceInterval: 0, //位置报告距离间隔
|
||||
// maxAccuracy: 0, //定位精度 单位:米
|
||||
// allowsBackgroundLocationUpdates: false, //是否允许后台定位
|
||||
// locatingWithReGeocode: true, //定位是否返回逆地理信息
|
||||
// reGeocodeLanguage: AMapLocationReGeocodeLanguage.Chinese, //逆地址语言类型
|
||||
// isOffset: true //是否加偏
|
||||
// }
|
||||
// let listener: IAMapLocationListener = {
|
||||
// onLocationChanged: (location) => {
|
||||
// this.getLocationAddress(location.latitude, location.longitude, 1, (err, data) => {
|
||||
// if (err) {
|
||||
// console.error('getAddressesFromLocation: err=' + JSON.stringify(err));
|
||||
// }
|
||||
// if (data) {
|
||||
// console.log('getAddressesFromLocation: data=' + JSON.stringify(data));
|
||||
// let loc = data[0].placeName ?? '';
|
||||
// if (data[0].administrativeArea) {
|
||||
// loc = loc.replace(data[0].administrativeArea, '')
|
||||
// }
|
||||
// if (data[0].subAdministrativeArea) {
|
||||
// loc = loc.replace(data[0].subAdministrativeArea, '')
|
||||
// }
|
||||
// if (data[0].subLocality) {
|
||||
// loc = loc.replace(data[0].subLocality, '')
|
||||
// }
|
||||
// if (data[0].roadName) {
|
||||
// loc = loc.replace(data[0].roadName, '')
|
||||
// }
|
||||
// if (data[0].subRoadName) {
|
||||
// loc = loc.replace(data[0].subRoadName, '')
|
||||
// }
|
||||
// if (data[0].subRoadName && loc === '') {
|
||||
// loc = data[0].subRoadName?.toString()
|
||||
// }
|
||||
// callback(loc);
|
||||
// }
|
||||
// });
|
||||
// }, onLocationError: (error) => {
|
||||
// console.error(`IAMapLocationListener ${error.errorMsg}:${error.errorCode}`)
|
||||
// }
|
||||
// };
|
||||
// this.locationManger?.setLocationListener(AMapLocationType.Updating, listener) //设置定位信息监听
|
||||
// this.locationManger?.setLocationOption(AMapLocationType.Updating, options) //设置定位配置项
|
||||
// this.locationManger?.startUpdatingLocation() //开启连续定位
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* 请求定位 allowScope是否允许定位, allowPrecision: 是否允许获取精确位置
|
||||
* @param callback
|
||||
*/
|
||||
requestPermissionsFromUser(callback: (allowScope: boolean, allowPrecision: boolean) => void): void {
|
||||
this.atManager.requestPermissionsFromUser(this.context, locationPermission)
|
||||
.then((data: PermissionRequestResult) => {
|
||||
callback(data.authResults[1] === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED,
|
||||
data.authResults[0] === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED);
|
||||
})
|
||||
.catch((err: BusinessError) => {
|
||||
console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
|
||||
})
|
||||
}
|
||||
|
||||
getLocationAddress(latitude: number, longitude: number, maxItems: number, callback:(error: BusinessError, data: geoLocationManager.GeoAddress[]) => void) {
|
||||
let reverseGeocodeRequest:geoLocationManager.ReverseGeoCodeRequest = {"latitude": latitude, "longitude": longitude, "maxItems": maxItems};
|
||||
try {
|
||||
geoLocationManager.getAddressesFromLocation(reverseGeocodeRequest, (err, data) => {
|
||||
callback(err, data);
|
||||
});
|
||||
} catch (err) {
|
||||
console.error("errCode:" + JSON.stringify(err));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,3 +2,7 @@
|
||||
export class PageRouter{
|
||||
static readonly WebPage: string = "@bundle:net.devwiki.hm4demo/app/ets/pages/web/WebPage"
|
||||
}
|
||||
|
||||
export enum PageName {
|
||||
loadingPage = 'LoadingPage',
|
||||
}
|
||||
|
||||
33
app/src/main/ets/utils/PasteboardUtil.ets
Normal file
33
app/src/main/ets/utils/PasteboardUtil.ets
Normal file
@@ -0,0 +1,33 @@
|
||||
import { pasteboard } from '@kit.BasicServicesKit';
|
||||
|
||||
class PasteboardUtil {
|
||||
|
||||
static async copyData(data: string, type: CopyDataType) {
|
||||
try {
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
|
||||
let mineType = pasteboard.MIMETYPE_TEXT_PLAIN;
|
||||
|
||||
if (type === CopyDataType.URI) {
|
||||
mineType = pasteboard.MIMETYPE_TEXT_URI;
|
||||
} else if (type === CopyDataType.HTML) {
|
||||
mineType = pasteboard.MIMETYPE_TEXT_HTML;
|
||||
}
|
||||
|
||||
const pasteData: pasteboard.PasteData = pasteboard.createData(mineType, data);
|
||||
const systemPasteboard: pasteboard.SystemPasteboard = pasteboard.getSystemPasteboard();
|
||||
|
||||
await systemPasteboard.setData(pasteData);
|
||||
} catch (err) {
|
||||
console.error('Failed to set PasteData.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export enum CopyDataType {
|
||||
TEXT,
|
||||
URI,
|
||||
HTML
|
||||
}
|
||||
@@ -4,11 +4,18 @@
|
||||
"type": "entry",
|
||||
"description": "$string:module_desc",
|
||||
"mainElement": "AppAbility",
|
||||
"srcEntry": "./ets/AppAbilityStage.ets",
|
||||
"deviceTypes": [
|
||||
"phone",
|
||||
"tablet",
|
||||
"2in1"
|
||||
],
|
||||
"metadata": [
|
||||
{
|
||||
"name": "client_id",
|
||||
"value": "123456789"
|
||||
}
|
||||
],
|
||||
"deliveryWithInstall": true,
|
||||
"installationFree": false,
|
||||
"pages": "$profile:main_pages",
|
||||
@@ -36,7 +43,18 @@
|
||||
],
|
||||
"requestPermissions": [
|
||||
{
|
||||
"name" : "ohos.permission.INTERNET"
|
||||
"name": "ohos.permission.LOCATION",
|
||||
"reason": "$string:location_permission",
|
||||
"usedScene": {
|
||||
"when": "inuse"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ohos.permission.APPROXIMATELY_LOCATION",
|
||||
"reason": "$string:approximately_location",
|
||||
"usedScene": {
|
||||
"when": "inuse"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2,15 +2,27 @@
|
||||
"string": [
|
||||
{
|
||||
"name": "module_desc",
|
||||
"value": "module description"
|
||||
"value": "HM4Demo App"
|
||||
},
|
||||
{
|
||||
"name": "AppAbility_desc",
|
||||
"value": "description"
|
||||
"value": "HM4Demo"
|
||||
},
|
||||
{
|
||||
"name": "AppAbility_label",
|
||||
"value": "label"
|
||||
"value": "HM4Demo"
|
||||
},
|
||||
{
|
||||
"name": "set_language_title",
|
||||
"value": "Set Language"
|
||||
},
|
||||
{
|
||||
"name": "location_permission",
|
||||
"value": "location_permission"
|
||||
},
|
||||
{
|
||||
"name": "approximately_location",
|
||||
"value": "approximately_location"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -3,10 +3,12 @@
|
||||
"pages/Index",
|
||||
|
||||
"pages/animation/CompTransitionPage",
|
||||
"pages/animation/LoadingPage",
|
||||
|
||||
"pages/component/InputPage",
|
||||
"pages/component/SVGPage",
|
||||
"pages/component/TextPage",
|
||||
"pages/component/ToastPage",
|
||||
|
||||
"pages/layout/LinearLayoutPage",
|
||||
"pages/layout/RelativeContainerPage",
|
||||
@@ -16,14 +18,20 @@
|
||||
"pages/media/PhotoPage",
|
||||
|
||||
"pages/mvvm/HomePage",
|
||||
"pages/mvvm/ArrayBindPage",
|
||||
|
||||
"pages/net/TcpSocketPage",
|
||||
"pages/net/RestAPIPage",
|
||||
|
||||
"pages/system/SchemePage",
|
||||
"pages/system/TimerPage",
|
||||
"pages/system/SetLanguagePage",
|
||||
|
||||
"pages/web/WebPage",
|
||||
"pages/web/WebDialogPage"
|
||||
"pages/web/WebDialogPage",
|
||||
|
||||
"pages/map/MapPage"
|
||||
|
||||
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2,15 +2,27 @@
|
||||
"string": [
|
||||
{
|
||||
"name": "module_desc",
|
||||
"value": "module description"
|
||||
"value": "HMDemo"
|
||||
},
|
||||
{
|
||||
"name": "AppAbility_desc",
|
||||
"value": "description"
|
||||
"value": "HMDemo_Ability"
|
||||
},
|
||||
{
|
||||
"name": "AppAbility_label",
|
||||
"value": "label"
|
||||
"value": "HMDemo"
|
||||
},
|
||||
{
|
||||
"name": "set_language_title",
|
||||
"value": "Set Language"
|
||||
},
|
||||
{
|
||||
"name": "location_permission",
|
||||
"value": "location_permission"
|
||||
},
|
||||
{
|
||||
"name": "approximately_location",
|
||||
"value": "approximately_location"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -2,15 +2,27 @@
|
||||
"string": [
|
||||
{
|
||||
"name": "module_desc",
|
||||
"value": "模块描述"
|
||||
"value": "HMDemo"
|
||||
},
|
||||
{
|
||||
"name": "AppAbility_desc",
|
||||
"value": "description"
|
||||
"value": "HMDemo_Ability"
|
||||
},
|
||||
{
|
||||
"name": "AppAbility_label",
|
||||
"value": "label"
|
||||
"value": "HMDemo"
|
||||
},
|
||||
{
|
||||
"name": "set_language_title",
|
||||
"value": "设置语言"
|
||||
},
|
||||
{
|
||||
"name": "location_permission",
|
||||
"value": "location_permission"
|
||||
},
|
||||
{
|
||||
"name": "approximately_location",
|
||||
"value": "approximately_location"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -34,12 +34,12 @@ export class BaseLocalStorage {
|
||||
let options: dataPreferences.Options = { name: BaseLocalStorage.XY_DP_Name };
|
||||
this.preferences = dataPreferences.getPreferencesSync(this.context, options);
|
||||
} else {
|
||||
Log.i("LocalStorage is already init.")
|
||||
Log.info("LocalStorage is already init.")
|
||||
}
|
||||
}
|
||||
|
||||
public putData(key: string, value: dataPreferences.ValueType) {
|
||||
Log.i(`put sp data, key:${key}, value:${value}`)
|
||||
Log.info(`put sp data, key:${key}, value:${value}`)
|
||||
this.preferences?.putSync(key, value);
|
||||
this.preferences?.flush();
|
||||
}
|
||||
@@ -51,7 +51,7 @@ export class BaseLocalStorage {
|
||||
|
||||
public getData(key: string, defaultValue: dataPreferences.ValueType): dataPreferences.ValueType | undefined {
|
||||
let value = this.preferences?.getSync(key, defaultValue);
|
||||
Log.i(`get sp data, key:${key}, value:${value}`)
|
||||
Log.info(`get sp data, key:${key}, value:${value}`)
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,28 +2,28 @@
|
||||
import hilog from '@ohos.hilog';
|
||||
|
||||
let domain: number = 0xFF00;
|
||||
let prefix: string = 'HM4Demo';
|
||||
let format: string = `%{public}s`;
|
||||
let prefix: string = 'HMDemo';
|
||||
let format: string = `%{public}s, %{public}s`;
|
||||
|
||||
export class Log {
|
||||
|
||||
static d(...args: string[]) {
|
||||
static debug(...args: string[]) {
|
||||
hilog.debug(domain, prefix, format, args);
|
||||
}
|
||||
|
||||
static i(...args: string[]) {
|
||||
static info(...args: string[]) {
|
||||
hilog.info(domain, prefix, format, args);
|
||||
}
|
||||
|
||||
static w(...args: string[]) {
|
||||
static warn(...args: string[]) {
|
||||
hilog.warn(domain, prefix, format, args);
|
||||
}
|
||||
|
||||
static e(...args: string[]) {
|
||||
static error(...args: string[]) {
|
||||
hilog.error(domain, prefix, format, args);
|
||||
}
|
||||
|
||||
static f(...args: string[]) {
|
||||
static fatal(...args: string[]) {
|
||||
hilog.fatal(domain,prefix, format, args);
|
||||
}
|
||||
|
||||
@@ -25,11 +25,11 @@ export class ScreenUtil {
|
||||
return ScreenUtil.instance;
|
||||
}
|
||||
|
||||
initScreenSize(): void {
|
||||
initScreenSize(context: Context): void {
|
||||
this.portraitListener.on('change', (result)=> {
|
||||
AppStorage.setOrCreate(ScreenUtil.isPortraitKey, result.matches)
|
||||
})
|
||||
window.getLastWindow(getContext(this))
|
||||
window.getLastWindow(context)
|
||||
.then((windowClass: window.Window) => {
|
||||
let type = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR; // 以导航条避让为例
|
||||
let avoidArea = windowClass.getWindowAvoidArea(type);
|
||||
@@ -106,7 +106,7 @@ export class ScreenUtil {
|
||||
}
|
||||
|
||||
setWindowKeepScreenOn(isKeep: boolean) {
|
||||
Log.i(`setWindowKeepScreenOn:${isKeep}`)
|
||||
Log.info(`setWindowKeepScreenOn:${isKeep}`)
|
||||
window.getLastWindow(getContext(this))
|
||||
.then((windowClass: window.Window) => {
|
||||
windowClass.setWindowKeepScreenOn(isKeep);
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
"name": "default",
|
||||
"type": "HarmonyOS",
|
||||
"material": {
|
||||
"certpath": "build_script/sign/HM4Demo.cer",
|
||||
"storePassword": "0000001B9C6223E8C618FEFD3D871B066F744A4E9C03C09D8ED7E7C7ECE6C1F53A54A6748EC341B960E492",
|
||||
"certpath": "C:\\Users\\zyz\\.ohos\\config\\default_HMDemo_i5yHT0lu8Bugf7Se0a-mWm67_DsSdIYAWNVACnIC98c=.cer",
|
||||
"storePassword": "0000001B17961DDECEBACEACD9CAA1E45CB0BEF5D5A935C253F2AB99644951676ED1B6F102D2B5AD8BCBA2",
|
||||
"keyAlias": "debugKey",
|
||||
"keyPassword": "0000001B63515E7120BC166D17A66B98A717DE9B06276194E4317B5317F70EA2835B8AD262B9DD4FD6AB55",
|
||||
"profile": "build_script/sign/HM4Demo.p7b",
|
||||
"keyPassword": "0000001B72605A837A1D1827D656F3D157F771A9B6DEC8B264626F1EFBBDA8FF65464F416F4B5C7F9FA84F",
|
||||
"profile": "C:\\Users\\zyz\\.ohos\\config\\default_HMDemo_i5yHT0lu8Bugf7Se0a-mWm67_DsSdIYAWNVACnIC98c=.p7b",
|
||||
"signAlg": "SHA256withECDSA",
|
||||
"storeFile": "build_script/sign/HM4Demo.p12"
|
||||
"storeFile": "C:\\Users\\zyz\\.ohos\\config\\default_HMDemo_i5yHT0lu8Bugf7Se0a-mWm67_DsSdIYAWNVACnIC98c=.p12"
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -22,8 +22,7 @@
|
||||
{
|
||||
"name": "default",
|
||||
"signingConfig": "default",
|
||||
"compileSdkVersion": "4.1.0(11)",
|
||||
"compatibleSdkVersion": "4.0.0(10)",
|
||||
"compatibleSdkVersion": "5.0.0(12)",
|
||||
"runtimeOS": "HarmonyOS",
|
||||
}
|
||||
],
|
||||
|
||||
@@ -4,3 +4,4 @@ export { WebView, WebViewController, WebViewParam } from './src/main/ets/compone
|
||||
export { CommonRes, CommonMediaName } from './src/main/ets/utils/CommonRes'
|
||||
|
||||
export { PhoneInput } from './src/main/ets/component/InputComponent'
|
||||
export { Toast } from './src/main/ets/utils/Toast'
|
||||
|
||||
@@ -8,7 +8,6 @@ function textInputStyle() {
|
||||
.padding(5)
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Component
|
||||
export struct PhoneInput {
|
||||
@Prop countryCode: string = "+86"
|
||||
@@ -26,7 +25,7 @@ export struct PhoneInput {
|
||||
Row() {
|
||||
Text(this.countryCode)
|
||||
.height(44)
|
||||
Image($r('app.media.ic_chevron_down'))
|
||||
Image($r(`app.media.ic_chevron_down`))
|
||||
.objectFit(ImageFit.Contain)
|
||||
.width(12)
|
||||
.height(12)
|
||||
@@ -55,7 +54,7 @@ export struct PhoneInput {
|
||||
})
|
||||
.width('100%')
|
||||
|
||||
Image($r('app.media.ic_clear_circle'))
|
||||
Image($r(`app.media.ic_clear_circle`))
|
||||
.width(18)
|
||||
.height(18)
|
||||
.backgroundColor(Color.Green)
|
||||
|
||||
@@ -15,21 +15,20 @@ export enum TitleBarMenuType{
|
||||
Text = 2
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Component
|
||||
export struct TitleBar {
|
||||
|
||||
@Prop title: ResourceStr;
|
||||
@Prop title: ResourceStr = '';
|
||||
|
||||
@Prop barHeight: number = 48;
|
||||
@Prop menuPadding: number = 8;
|
||||
|
||||
@Prop leftText: ResourceStr = "";
|
||||
@Prop leftIcon: Resource = $r("app.media.ic_chevron_left");
|
||||
@Prop leftIcon: Resource = $r(`app.media.ic_chevron_left`);
|
||||
@Prop leftMenuType: TitleBarMenuType = TitleBarMenuType.Icon;
|
||||
|
||||
@Prop rightText: ResourceStr = "";
|
||||
@Prop rightIcon: Resource = $r("app.media.ic_close");
|
||||
@Prop rightIcon: Resource = $r(`app.media.ic_close`);
|
||||
@Prop rightMenuType: TitleBarMenuType = TitleBarMenuType.None;
|
||||
|
||||
@Prop titleTextAlign: TextAlign = TextAlign.Start;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import web_webview from '@ohos.web.webview';
|
||||
import { WebScriptCallback, WebScriptFunction } from './WebScript';
|
||||
import { picker } from '@kit.CoreFileKit';
|
||||
import { BusinessError } from '@kit.BasicServicesKit';
|
||||
|
||||
export class WebViewParam {
|
||||
webUrl: string = "";
|
||||
@@ -9,6 +11,8 @@ export class WebViewParam {
|
||||
export struct WebView {
|
||||
|
||||
private webviewController: web_webview.WebviewController = new web_webview.WebviewController();
|
||||
selectOptions?: picker.PhotoSelectOptions | picker.DocumentSelectOptions;
|
||||
viewPicker?: picker.PhotoViewPicker | picker.DocumentViewPicker;
|
||||
controller: WebViewController = new WebViewController();
|
||||
@Prop @Watch("onParamChanged")param: WebViewParam = new WebViewParam();
|
||||
|
||||
@@ -33,6 +37,21 @@ export struct WebView {
|
||||
controller: this.webviewController
|
||||
})
|
||||
.onPageEnd(() => { this.controller.onPageEnd(this.webviewController.getTitle()) })
|
||||
.onShowFileSelector( (event) =>{
|
||||
let uri: string[] | null = null;
|
||||
this.selectOptions = new picker.DocumentSelectOptions();
|
||||
this.viewPicker = new picker.DocumentViewPicker();
|
||||
this.viewPicker.select(this.selectOptions).then((result) => {
|
||||
uri = result;
|
||||
console.info('DocumentViewPicker.select to file succeed and uri is:' + uri);
|
||||
if (event) {
|
||||
event.result.handleFileList(uri);
|
||||
}
|
||||
}).catch((err: BusinessError) => {
|
||||
console.error(`Invoke documentViewPicker.select failed, code is ${err.code}, message is ${err.message}`);
|
||||
})
|
||||
return true;
|
||||
})
|
||||
.width('100%')
|
||||
.height('100%');
|
||||
}
|
||||
|
||||
@@ -7,27 +7,27 @@ export class CommonRes {
|
||||
}
|
||||
|
||||
public static getIconRefresh(): Resource {
|
||||
return $r("app.media.ic_refresh");
|
||||
return $r(`app.media.ic_refresh`);
|
||||
}
|
||||
|
||||
public static getIconChevronLeft(): Resource {
|
||||
return $r("app.media.ic_chevron_left");
|
||||
return $r(`app.media.ic_chevron_left`);
|
||||
}
|
||||
|
||||
public static getIconChevronRight(): Resource {
|
||||
return $r("app.media.ic_chevron_right");
|
||||
return $r(`app.media.ic_chevron_right`);
|
||||
}
|
||||
|
||||
public static getIconClose(): Resource {
|
||||
return $r("app.media.ic_close");
|
||||
return $r(`app.media.ic_close`);
|
||||
}
|
||||
|
||||
public static getIconEyeOn(): Resource {
|
||||
return $r("app.media.ic_eye_on");
|
||||
return $r(`app.media.ic_eye_on`);
|
||||
}
|
||||
|
||||
public static getIconEyeOff(): Resource {
|
||||
return $r("app.media.ic_eye_off");
|
||||
return $r(`app.media.ic_eye_off`);
|
||||
}
|
||||
|
||||
public static getImage(resName: string): Resource {
|
||||
|
||||
26
common_ui/src/main/ets/utils/Res.ets
Normal file
26
common_ui/src/main/ets/utils/Res.ets
Normal file
@@ -0,0 +1,26 @@
|
||||
import { util } from '@kit.ArkTS';
|
||||
|
||||
export class Res {
|
||||
|
||||
static getRawFileContent(name: string): string {
|
||||
let content = getContext().resourceManager.getRawFileContentSync(name);
|
||||
let textDecoderOptions: util.TextDecoderOptions = {
|
||||
fatal: false,
|
||||
ignoreBOM : true
|
||||
}
|
||||
let decodeWithStreamOptions: util.DecodeWithStreamOptions = {
|
||||
stream: true
|
||||
}
|
||||
let textDecoder = util.TextDecoder.create('utf-8', textDecoderOptions);
|
||||
let retStr = textDecoder.decodeWithStream( content , decodeWithStreamOptions);
|
||||
return retStr;
|
||||
}
|
||||
|
||||
static getResStr(descName: string, ...rest: string[]): ResourceStr {
|
||||
try {
|
||||
return $r(`app.string.${descName}`, ...rest);
|
||||
} catch (e) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
import promptAction from '@ohos.promptAction';
|
||||
|
||||
export class Toast {
|
||||
static showToast(message: ResourceStr) {
|
||||
static showToast(message: ResourceStr, topmost: boolean = false) {
|
||||
promptAction.showToast({
|
||||
message: message,
|
||||
duration: 2000,
|
||||
bottom: "50%"
|
||||
bottom: "50%",
|
||||
showMode: promptAction.ToastShowMode.TOP_MOST
|
||||
});
|
||||
}
|
||||
}
|
||||
1
common_ui/src/main/resources/base/media/ic_loading.svg
Normal file
1
common_ui/src/main/resources/base/media/ic_loading.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>loading</title><path d="M12,4V2A10,10 0 0,0 2,12H4A8,8 0 0,1 12,4Z" /></svg>
|
||||
|
After Width: | Height: | Size: 143 B |
@@ -1,5 +0,0 @@
|
||||
import localUnitTest from './LocalUnit.test';
|
||||
|
||||
export default function testsuite() {
|
||||
localUnitTest();
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
|
||||
|
||||
export default function localUnitTest() {
|
||||
describe('localUnitTest',() => {
|
||||
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
|
||||
beforeAll(() => {
|
||||
// Presets an action, which is performed only once before all test cases of the test suite start.
|
||||
// This API supports only one parameter: preset action function.
|
||||
});
|
||||
beforeEach(() => {
|
||||
// Presets an action, which is performed before each unit test case starts.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: preset action function.
|
||||
});
|
||||
afterEach(() => {
|
||||
// Presets a clear action, which is performed after each unit test case ends.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: clear action function.
|
||||
});
|
||||
afterAll(() => {
|
||||
// Presets a clear action, which is performed after all test cases of the test suite end.
|
||||
// This API supports only one parameter: clear action function.
|
||||
});
|
||||
it('assertContain', 0, () => {
|
||||
// Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
|
||||
let a = 'abc';
|
||||
let b = 'b';
|
||||
// Defines a variety of assertion methods, which are used to declare expected boolean conditions.
|
||||
expect(a).assertContain(b);
|
||||
expect(a).assertEqual(a);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,16 +1,28 @@
|
||||
@echo off
|
||||
chcp 65001 > nul
|
||||
set native_path=D:\AppData\Huawei\Sdk\HarmonyOS-NEXT-DP2\base\native\
|
||||
set toolchain=%native_path%build\cmake\ohos.toolchain.cmake
|
||||
set cmake_root=%native_path%build-tools\cmake\
|
||||
set cmake_path=%cmake_root%bin\cmake.exe
|
||||
set ninja_path=%cmake_root%bin\ninja.exe
|
||||
set make_path=C:\MinGW\msys\1.0\bin\make.exe
|
||||
set arch=arm64-v8a
|
||||
|
||||
set "native_path=C:\Program Files\Huawei\DevEco Studio5\sdk\HarmonyOS-NEXT-DB1\openharmony\native\"
|
||||
:: IF NOT "%~2" == "" (
|
||||
:: set "native_path=%~2"
|
||||
:: )
|
||||
echo native_path: "%native_path%"
|
||||
|
||||
set "toolchain=%native_path%build\cmake\ohos.toolchain.cmake"
|
||||
echo toolchain: "%toolchain%"
|
||||
set "cmake_root=%native_path%build-tools\cmake\"
|
||||
echo cmake_root: "%cmake_root%"
|
||||
set "cmake_path=%cmake_root%bin\cmake.exe"
|
||||
echo cmake_path: "%cmake_path%"
|
||||
set "ninja_path=%cmake_root%bin\ninja.exe"
|
||||
echo ninja_path: "%ninja_path%"
|
||||
set "make_path=C:\MinGW\msys\1.0\bin\make.exe"
|
||||
echo make_path: %make_path%
|
||||
set "arch=arm64-v8a"
|
||||
|
||||
IF NOT "%~1" == "" (
|
||||
set arch=%1
|
||||
set "arch=%~1"
|
||||
)
|
||||
echo arch: "%arch%"
|
||||
|
||||
if exist build (
|
||||
del /q /s build
|
||||
@@ -28,11 +40,10 @@ if exist dist (
|
||||
|
||||
cd build
|
||||
:: 使用 make 构建
|
||||
:: %cmake_path% -G"Unix Makefiles" -DCMAKE_MAKE_PROGRAM="%make_path%" -DOHOS_STL=c++_static -DOHOS_ARCH="%arch%" -DOHOS_PLATFORM=OHOS -DCMAKE_TOOLCHAIN_FILE=%toolchain% ..
|
||||
:: "%cmake_path%" -G "Unix Makefiles" -DCMAKE_MAKE_PROGRAM="%make_path%" -DOHOS_STL=c++_static -DOHOS_ARCH="%arch%" -DOHOS_PLATFORM=OHOS -DCMAKE_TOOLCHAIN_FILE="%toolchain%" ..
|
||||
:: %make_path%
|
||||
|
||||
:: 使用 ninja 构建
|
||||
%cmake_path% -GNinja -DCMAKE_MAKE_PROGRAM="%ninja_path%" -DOHOS_STL=c++_static -DOHOS_ARCH="%arch%" -DOHOS_PLATFORM=OHOS -DCMAKE_TOOLCHAIN_FILE=%toolchain% ..
|
||||
%ninja_path%
|
||||
"%cmake_path%" -G "Ninja" -D CMAKE_MAKE_PROGRAM="%ninja_path%" -D OHOS_STL=c++_static -D OHOS_ARCH="%arch%" -D OHOS_PLATFORM=OHOS -D CMAKE_TOOLCHAIN_FILE="%toolchain%" ..
|
||||
"%ninja_path%"
|
||||
cd ../
|
||||
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
@echo off
|
||||
chcp 65001 > nul
|
||||
build.bat
|
||||
|
||||
build.bat x86_64
|
||||
|
||||
build.bat
|
||||
1
cppLib/build_x86.bat
Normal file
1
cppLib/build_x86.bat
Normal file
@@ -0,0 +1 @@
|
||||
build.bat "x86_64"
|
||||
BIN
cppLib/dist/lib/arm64-v8a/libcalculate.so
vendored
BIN
cppLib/dist/lib/arm64-v8a/libcalculate.so
vendored
Binary file not shown.
BIN
cppLib/dist/lib/x86_64/libcalculate.so
vendored
BIN
cppLib/dist/lib/x86_64/libcalculate.so
vendored
Binary file not shown.
BIN
dependencies/hvigor-4.1.1.tgz
vendored
BIN
dependencies/hvigor-4.1.1.tgz
vendored
Binary file not shown.
BIN
dependencies/hvigor-ohos-arkui-x-plugin-3.1.0.tgz
vendored
BIN
dependencies/hvigor-ohos-arkui-x-plugin-3.1.0.tgz
vendored
Binary file not shown.
BIN
dependencies/hvigor-ohos-plugin-4.1.1.tgz
vendored
BIN
dependencies/hvigor-ohos-plugin-4.1.1.tgz
vendored
Binary file not shown.
@@ -1 +1,2 @@
|
||||
export { CalculateAdapter } from './src/main/cpp/types/libhmcalculate/index'
|
||||
export { Calculator } from './src/main/ets/Calculator'
|
||||
export { CalculateInfo } from './src/main/ets/CalculateInfo'
|
||||
@@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 3.4.1)
|
||||
project(hmcalculate)
|
||||
|
||||
set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
add_definitions(-DOHOS_PLATFORM)
|
||||
|
||||
if(DEFINED PACKAGE_FIND_FILE)
|
||||
include(${PACKAGE_FIND_FILE})
|
||||
@@ -13,16 +14,61 @@ include_directories(${NATIVERENDER_ROOT_PATH}
|
||||
|
||||
add_library(hmcalculate SHARED
|
||||
napi_init.cpp
|
||||
CalculateInfo.h
|
||||
CalculateAdaptor.cpp)
|
||||
|
||||
# 根据不同的架构选择不同的库文件路径
|
||||
IF(OHOS_ARCH STREQUAL "arm64-v8a")
|
||||
set(LIB_DIR ${NATIVERENDER_ROOT_PATH}/../../../../cppLib/dist/lib/arm64-v8a)
|
||||
ELSEIF(OHOS_ARCH STREQUAL "x86_64")
|
||||
set(LIB_DIR ${NATIVERENDER_ROOT_PATH}/../../../../cppLib/dist/lib/x86_64)
|
||||
ELSE()
|
||||
MESSAGE(FATAL_ERROR "Unsupported architecture: ${OHOS_ARCH}")
|
||||
ENDIF()
|
||||
find_library(
|
||||
# Sets the name of the path variable.
|
||||
EGL-lib
|
||||
# Specifies the name of the NDK library that
|
||||
# you want CMake to locate.
|
||||
EGL
|
||||
)
|
||||
|
||||
target_link_libraries(hmcalculate PUBLIC ${LIB_DIR}/libcalculate.so)
|
||||
find_library(
|
||||
# Sets the name of the path variable.
|
||||
GLES-lib
|
||||
# Specifies the name of the NDK library that
|
||||
# you want CMake to locate.
|
||||
GLESv3
|
||||
)
|
||||
|
||||
find_library(
|
||||
# Sets the name of the path variable.
|
||||
hilog-lib
|
||||
# Specifies the name of the NDK library that
|
||||
# you want CMake to locate.
|
||||
hilog_ndk.z
|
||||
)
|
||||
|
||||
find_library(
|
||||
# Sets the name of the path variable.
|
||||
libnapi-lib
|
||||
# Specifies the name of the NDK library that
|
||||
# you want CMake to locate.
|
||||
ace_napi.z
|
||||
)
|
||||
|
||||
find_library(
|
||||
# Sets the name of the path variable.
|
||||
libace-lib
|
||||
# Specifies the name of the NDK library that
|
||||
# you want CMake to locate.
|
||||
ace_ndk.z
|
||||
)
|
||||
|
||||
find_library(
|
||||
# Sets the name of the path variable.
|
||||
libuv-lib
|
||||
# Specifies the name of the NDK library that
|
||||
# you want CMake to locate.
|
||||
uv
|
||||
)
|
||||
|
||||
target_link_libraries(hmcalculate PUBLIC
|
||||
${EGL-lib}
|
||||
${GLES-lib}
|
||||
${hilog-lib}
|
||||
${libnapi-lib}
|
||||
${libace-lib}
|
||||
${libuv-lib}
|
||||
${NATIVERENDER_ROOT_PATH}/../../../../cppLib/dist/lib/${OHOS_ARCH}/libcalculate.so)
|
||||
@@ -1,7 +1,6 @@
|
||||
#ifndef CPPLIB_LIBRARY_H
|
||||
#define CPPLIB_LIBRARY_H
|
||||
|
||||
#include <string>
|
||||
#include "CalculateInfo.h"
|
||||
|
||||
class Calculate {
|
||||
|
||||
@@ -5,8 +5,10 @@
|
||||
// please include "napi/native_api.h".
|
||||
|
||||
#include "CalculateAdaptor.h"
|
||||
#include "js_native_api.h"
|
||||
#include "Calculate.h"
|
||||
#include "CalculateInfo.h"
|
||||
#include <string>
|
||||
#include <stdint.h>
|
||||
|
||||
CalculateAdaptor::CalculateAdaptor() {
|
||||
_calculate = &Calculate::getInstance();
|
||||
@@ -30,7 +32,6 @@ CalculateAdaptor *util_get_napi_info(napi_env env, napi_callback_info cbinfo, si
|
||||
return calculator;
|
||||
}
|
||||
|
||||
|
||||
napi_value calculate_add(napi_env env, napi_callback_info info) {
|
||||
size_t argc = 2;
|
||||
napi_value argv[2] = {0};
|
||||
@@ -58,7 +59,57 @@ napi_value calculate_getInfo(napi_env env, napi_callback_info info) {
|
||||
info2.versionCode = calculator->_calculate->getInfo().versionCode;
|
||||
info2.versionName = calculator->_calculate->getInfo().versionName;
|
||||
|
||||
napi_value value;
|
||||
napi_value js_frame;
|
||||
napi_create_object(env, &js_frame);
|
||||
util_set_object_string_property_value(env, js_frame, "name", info2.name.c_str());
|
||||
util_set_object_string_property_value(env, js_frame, "versionName", info2.versionName.c_str());
|
||||
util_set_object_int32_property_value(env, js_frame, "versionCode", info2.versionCode);
|
||||
|
||||
return js_frame;
|
||||
}
|
||||
|
||||
napi_value util_create_int32_value(napi_env env, int32_t arg)
|
||||
{
|
||||
napi_value value;
|
||||
napi_status status = napi_create_int32(env, arg, &value);
|
||||
return value;
|
||||
}
|
||||
|
||||
napi_status util_set_object_int32_property_value(napi_env env, napi_value object, const char *name, int32_t value)
|
||||
{
|
||||
napi_value js_value = util_create_int32_value(env, value);
|
||||
return napi_set_named_property(env, object, name, js_value);
|
||||
}
|
||||
|
||||
napi_value util_create_string_value(napi_env env, const char *arg)
|
||||
{
|
||||
napi_value value;
|
||||
napi_status status = napi_create_string_utf8(env, arg, NAPI_AUTO_LENGTH, &value);
|
||||
return value;
|
||||
}
|
||||
|
||||
napi_status util_set_object_string_property_value(napi_env env, napi_value object, const char *name, const char *value)
|
||||
{
|
||||
napi_value js_value = util_create_string_value(env, value);
|
||||
return napi_set_named_property(env, object, name, js_value);
|
||||
}
|
||||
|
||||
char *util_get_object_string_property_value(napi_env env, napi_value arg, const char *name)
|
||||
{
|
||||
napi_status status = napi_ok;
|
||||
napi_value js_result;
|
||||
status = napi_get_named_property(env, arg, name, &js_result);
|
||||
if (napi_ok == status) {
|
||||
return util_get_string_value(env, js_result);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
char *util_get_string_value(napi_env env, napi_value arg)
|
||||
{
|
||||
size_t len = 0;
|
||||
napi_get_value_string_utf8(env, arg, nullptr, 0, &len); // 获取字符串长度到len
|
||||
char *buf = new char[len + 1]; // 分配合适大小的char数组
|
||||
napi_get_value_string_utf8(env, arg, buf, len + 1, &len); // 获取字符串
|
||||
return buf;
|
||||
}
|
||||
|
||||
@@ -7,16 +7,16 @@
|
||||
#ifndef HM4DEMO_CALCULATOR_H
|
||||
#define HM4DEMO_CALCULATOR_H
|
||||
|
||||
#include "CalculateInfo.h"
|
||||
#include "Calculate.h"
|
||||
#include "js_native_api.h"
|
||||
#include <stdint.h>
|
||||
|
||||
class CalculateAdaptor {
|
||||
public:
|
||||
CalculateAdaptor();
|
||||
CalculateAdaptor(napi_env env, napi_value thisVar);
|
||||
~CalculateAdaptor();
|
||||
Calculate *_calculate;
|
||||
virtual ~CalculateAdaptor();
|
||||
Calculate *_calculate = nullptr;
|
||||
};
|
||||
|
||||
CalculateAdaptor *util_get_napi_info(napi_env env, napi_callback_info cbinfo, size_t argc, napi_value *argv);
|
||||
@@ -24,5 +24,12 @@ CalculateAdaptor *util_get_napi_info(napi_env env, napi_callback_info cbinfo, si
|
||||
napi_value calculate_add(napi_env env, napi_callback_info info);
|
||||
napi_value calculate_getInfo(napi_env env, napi_callback_info info);
|
||||
|
||||
napi_value util_create_int32_value(napi_env env, int32_t arg);
|
||||
napi_status util_set_object_int32_property_value(napi_env env, napi_value object, const char *name, int32_t value);
|
||||
|
||||
napi_value util_create_string_value(napi_env env, const char *arg);
|
||||
napi_status util_set_object_string_property_value(napi_env env, napi_value object, const char *name, const char *value);
|
||||
char *util_get_object_string_property_value(napi_env env, napi_value arg, const char *name);
|
||||
char *util_get_string_value(napi_env env, napi_value arg);
|
||||
|
||||
#endif //HM4DEMO_CALCULATOR_H
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "napi/native_api.h"
|
||||
#include "CalculateAdaptor.h"
|
||||
#include "js_native_api.h"
|
||||
#include "CalculateAdaptor.h"
|
||||
|
||||
napi_value JS_Constructor(napi_env env, napi_callback_info info) {
|
||||
napi_value thisVar = nullptr;
|
||||
@@ -38,12 +38,12 @@ static napi_module demoModule = {
|
||||
.nm_flags = 0,
|
||||
.nm_filename = nullptr,
|
||||
.nm_register_func = Init,
|
||||
.nm_modname = "native_lib",
|
||||
.nm_modname = "hmcalculate",
|
||||
.nm_priv = ((void*)0),
|
||||
.reserved = { 0 },
|
||||
};
|
||||
|
||||
extern "C" __attribute__((constructor)) void RegisterNatvie_libModule(void)
|
||||
extern "C" __attribute__((constructor)) void RegisterHmcalculateModule(void)
|
||||
{
|
||||
napi_module_register(&demoModule);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export class CalculateAdapter {
|
||||
export class CalculateAdaptor {
|
||||
add(a: number, b: number): number;
|
||||
getInfo(): Object;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "libhmcalculate.so",
|
||||
"types": "./index.d.ts",
|
||||
"version": "",
|
||||
"version": "1.0.0",
|
||||
"description": "Please describe the basic information."
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
import { CalculateAdapter } from 'native_lib.so'
|
||||
import { CalculateAdaptor } from 'libhmcalculate.so'
|
||||
import { CalculateInfo } from './CalculateInfo'
|
||||
|
||||
export class Calculator {
|
||||
|
||||
private adaptor!:CalculateAdapter;
|
||||
private adaptor!:CalculateAdaptor;
|
||||
|
||||
constructor() {
|
||||
this.adaptor = new CalculateAdapter();
|
||||
this.adaptor = new CalculateAdaptor();
|
||||
}
|
||||
|
||||
add(a:number, b: number): number {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"hvigorVersion": "file:../dependencies/hvigor-4.1.1.tgz",
|
||||
"modelVersion": "5.0.0",
|
||||
"dependencies": {
|
||||
"@ohos/hvigor-ohos-plugin": "file:../dependencies/hvigor-ohos-plugin-4.1.1.tgz",
|
||||
},
|
||||
"execution": {
|
||||
// "analyze": "default", /* Define the build analyze mode. Value: [ "default" | "verbose" | false ]. Default: "default" */
|
||||
|
||||
File diff suppressed because one or more lines are too long
54
hvigorw
54
hvigorw
@@ -1,54 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Hvigor startup script, version 1.0.0
|
||||
#
|
||||
# Required ENV vars:
|
||||
# ------------------
|
||||
# NODE_HOME - location of a Node home dir
|
||||
# or
|
||||
# Add /usr/local/nodejs/bin to the PATH environment variable
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
HVIGOR_APP_HOME="`pwd -P`"
|
||||
HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js
|
||||
#NODE_OPTS="--max-old-space-size=4096"
|
||||
|
||||
fail() {
|
||||
echo "$*"
|
||||
exit 1
|
||||
}
|
||||
|
||||
set_executable_node() {
|
||||
EXECUTABLE_NODE="${NODE_HOME}/bin/node"
|
||||
if [ -x "$EXECUTABLE_NODE" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
EXECUTABLE_NODE="${NODE_HOME}/node"
|
||||
if [ -x "$EXECUTABLE_NODE" ]; then
|
||||
return
|
||||
fi
|
||||
fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed"
|
||||
}
|
||||
|
||||
# Determine node to start hvigor wrapper script
|
||||
if [ -n "${NODE_HOME}" ]; then
|
||||
set_executable_node
|
||||
else
|
||||
EXECUTABLE_NODE="node"
|
||||
command -v ${EXECUTABLE_NODE} &> /dev/null || fail "ERROR: NODE_HOME not set and 'node' command not found"
|
||||
fi
|
||||
|
||||
# Check hvigor wrapper script
|
||||
if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ]; then
|
||||
fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}"
|
||||
fi
|
||||
|
||||
if [ -z "${NODE_OPTS}" ]; then
|
||||
NODE_OPTS="--"
|
||||
fi
|
||||
|
||||
# start hvigor-wrapper script
|
||||
exec "${EXECUTABLE_NODE}" "${NODE_OPTS}" \
|
||||
"${HVIGOR_WRAPPER_SCRIPT}" "$@"
|
||||
54
hvigorw.bat
54
hvigorw.bat
@@ -1,54 +0,0 @@
|
||||
@rem
|
||||
@rem ----------------------------------------------------------------------------
|
||||
@rem Hvigor startup script for Windows, version 1.0.0
|
||||
@rem
|
||||
@rem Required ENV vars:
|
||||
@rem ------------------
|
||||
@rem NODE_HOME - location of a Node home dir
|
||||
@rem or
|
||||
@rem Add %NODE_HOME%/bin to the PATH environment variable
|
||||
@rem ----------------------------------------------------------------------------
|
||||
@rem
|
||||
@echo off
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js
|
||||
set NODE_EXE=node.exe
|
||||
@rem set NODE_OPTS="--max-old-space-size=4096"
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
if not defined NODE_OPTS set NODE_OPTS="--"
|
||||
|
||||
@rem Find node.exe
|
||||
if defined NODE_HOME (
|
||||
set NODE_HOME=%NODE_HOME:"=%
|
||||
set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE%
|
||||
)
|
||||
|
||||
%NODE_EXE% --version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" (
|
||||
"%NODE_EXE%" "%NODE_OPTS%" "%WRAPPER_MODULE_PATH%" %*
|
||||
) else if exist "%NODE_EXE_PATH%" (
|
||||
"%NODE_EXE%" "%NODE_OPTS%" "%WRAPPER_MODULE_PATH%" %*
|
||||
) else (
|
||||
echo.
|
||||
echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the NODE_HOME variable in your environment to match the
|
||||
echo location of your NodeJs installation.
|
||||
)
|
||||
|
||||
if "%ERRORLEVEL%" == "0" (
|
||||
if "%OS%" == "Windows_NT" endlocal
|
||||
) else (
|
||||
exit /b %ERRORLEVEL%
|
||||
)
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"modelVersion": "5.0.0",
|
||||
//项目名称
|
||||
"name": "hm4demo",
|
||||
//项目版本号
|
||||
|
||||
36
readme.md
36
readme.md
@@ -1,19 +1,29 @@
|
||||
本项目代码地址为: [Harmony/HM4Demo - HM4Demo - DevWiki Gitea](https://git.devwiki.net/Harmony/HM4Demo)
|
||||
本项目代码地址为: [Harmony/HMDemo - HMDemo - DevWiki Gitea](https://git.devwiki.net/Harmony/HMDemo)
|
||||
|
||||
提交时会同步更新至:
|
||||
- github: [Dev-Wiki/HM4Demo](https://github.com/Dev-Wiki/HM4Demo)
|
||||
- gitee : [DevWiki/HM4Demo](https://gitee.com/devwiki/HM4Demo)
|
||||
- github: [Dev-Wiki/HMDemo](https://github.com/Dev-Wiki/HMDemo)
|
||||
- gitee : [DevWiki/HMDemo](https://gitee.com/devwiki/HMDemo)
|
||||
|
||||
[TOC]
|
||||
|
||||
# 项目概要
|
||||
|
||||
## 重要说明
|
||||
## 1. 重要说明
|
||||
|
||||
本项目为 HM4项目,其中:
|
||||
目前分支如下:
|
||||
### 1.1 master分支
|
||||
|
||||
基于API11,即 DevEco使用 4.x或者 5.0.3.200版本
|
||||
- compileSdkVersion : 4.1.0(11)
|
||||
- compatibleSdkVersion: 4.0.0(10)
|
||||
|
||||
### 1.2 api12分支
|
||||
基于API12, DevEco使用 5.0.3.300之后版本
|
||||
|
||||
请使用API对应的DevEco进行编译.
|
||||
|
||||
### 1.3项目模块
|
||||
|
||||
本项目模块分为:
|
||||
- app: 主入口模块
|
||||
- common_ui : 通用UI动态共享库模块
|
||||
@@ -22,19 +32,21 @@
|
||||
- native_lib: 包含C++ 的 shared 模块
|
||||
|
||||
|
||||
## app模块
|
||||
## 2. app模块
|
||||
|
||||
- [MVVM架构](app/src/main/ets/pages/mvvm/HomePage.ets)
|
||||
|
||||
- [web功能](app/src/main/ets/pages/web)
|
||||
- [动画](app/src/main/ets/pages/animation)
|
||||
- [组件](app/src/main/ets/pages/component)
|
||||
- [布局学习](app/src/main/ets/pages/layout)
|
||||
- [线性布局](app/src/main/ets/pages/layout/LinearLayoutPage.ets)
|
||||
- [动画](app/src/main/ets/pages/animation)
|
||||
- [多媒体](app/src/main/ets/pages/media)
|
||||
- [AVPlayer](app/src/main/ets/pages/media/AVPlayerPage.ets)
|
||||
- [照片选择](app/src/main/ets/pages/media/PhotoPage.ets)
|
||||
- [MVVM架构](app/src/main/ets/pages/mvvm/HomePage.ets)
|
||||
- [网络](app/src/main/ets/pages/net)
|
||||
- [系统功能](app/src/main/ets/pages/system)
|
||||
- [web功能](app/src/main/ets/pages/web)
|
||||
|
||||
## common ui模块
|
||||
## 3. common ui模块
|
||||
|
||||
包含的组件有:
|
||||
|
||||
@@ -44,7 +56,7 @@
|
||||
|
||||
|
||||
|
||||
## base 模块
|
||||
## 4. base 模块
|
||||
|
||||
事件相关:
|
||||
- 事件发射器: [Emitter](base/src/main/ets/event/Emitter.ets)
|
||||
|
||||
Reference in New Issue
Block a user