赞
踩
Demo基于Open Harmony系统使用ETS语言进行编写,本Demo主要通过设备认证、分布式拉起、分布式数据管理等功能来实现。
在DevEco Studio中点击File -> New Project ->[Standard]Empty Ability->Next,Language 选择ETS语言,最后点击Finish即创建成功。
build() { Flex({ direction: FlexDirection.Column}) { //发现设备 Button('发现设备', { type: ButtonType.Normal, stateEffect: true }) .borderRadius(8) .backgroundColor(0x317aff).width(90) .onClick(() =>{ this.fun() }) //设备认证 Button('authDevice', { type: ButtonType.Normal, stateEffect: true }) .borderRadius(8) .backgroundColor(0x317aff).width(90) .onClick(() =>{ this.authDevice() }) // 拉起应用 Button('拉起应用', { type: ButtonType.Normal, stateEffect: true }) .borderRadius(8) .backgroundColor(0x317aff).width(90) .onClick(() =>{ this.startAb() }) Stack({ alignContent:Alignment.TopEnd }){ Text('家庭账本') .fontSize(20) .fontWeight(FontWeight.Bold) .width('100%') .margin({left:12}) .onClick(() =>{ // routePage() this.fun() }) Image("/picture/add.png") .width(40) .height(40) .align(Alignment.Start) .margin({ right:12 }).onClick(() =>{ routePage() }) } .width(350) .height(60) .margin({ top:10, bottom:10 }) Flex({ direction: FlexDirection.Column, alignItems:ItemAlign.Start, }){ Text("2022年12月") .fontSize(20) .fontColor(Color.White) Text("结余") .fontSize(20) .fontColor(Color.White) .margin({ top:30 }).align(Alignment.Start) Text("总支出0|总收入0") .fontSize(16) .fontColor(Color.White) .margin({ top:10 }).align(Alignment.Start) } .backgroundColor("#665A5A") .height(230) .layoutWeight(1) .padding(10) .onClick(() =>{ routePage() }) Tabs() { TabContent() { ProjectList() } .tabBar("项目") TabContent() { Statistics() } .tabBar("统计") } } .width('100%') .height('100%') .padding({ left:12,right:12 }) }
底部TabContent 项目模块
@Component struct ProjectList { remoteDataManager = new RemoteDataManager() @State ProjectData: Array<any> = [] TestData:any[] = [] TestKvData: Array<any> = [] kvManager = null kvStore = null STORE_ID = 'store_accountbook' aboutToAppear(){ try { const config = { userInfo: { userId: '0', userType: 0 }, bundleName: 'com.example.accountbookets' } factory.createKVManager(config).then((manager) => { this.kvManager = manager let options = { createIfMissing: true, encrypt: false, backup: false, autoSync: true, kvStoreType: 1, securityLevel: 3 } this.kvManager.getKVStore(this.STORE_ID, options).then((store) => { this.kvStore = store this.kvStore.get("key2").then((data) => { this.ProjectData = JSON.parse(data) }) }).catch((err) => { }) }).catch((err) => { }) } catch (e) { } } @Builder ProjectItem(image, name, des,time,money) { Flex({ direction: FlexDirection.Row,alignItems: ItemAlign.Center }){ Image($r("app.media.icon1")) .width(30) .height(30) Column() { Text(name) .fontSize(16) .fontColor(Color.Black) Text('11:20') .fontSize(16) .fontColor(Color.Gray) } .alignItems(HorizontalAlign.Start) .margin({left:15}) Text('HUAWEI') .fontSize(12) .fontColor(Color.Black) .margin({left:20}) Text(des) .fontSize(14) .fontColor(Color.Gray) .margin({left:15}) Column() { Text('-100') .fontSize(16) .fontColor(Color.Black) Text(time) .fontSize(16) .fontColor(Color.Gray) } .alignItems(HorizontalAlign.Start) .margin({left:20}) } .width(400) .height(50) .margin({top:10}) } build() { List() { ForEach(this.ProjectData, (item) => { ListItem() { this.ProjectItem(item.image, item.name, item.des,item.time,item.money) } .onClick(() => { }) }, (item) => JSON.stringify(item)) { } } } }
底部TabContent 统计模块
@Component struct Statistics{ build(){ Flex({ direction: FlexDirection.Row}){ Tabs() { TabContent() { PayList() } .tabBar("支出分类") TabContent() { } .tabBar("成员分类") } } } }
统计模块里面的TabContent
@Component struct PayList { private PayData: PayBean[] = initializeOnStartup() @Builder PayItem(previewUrl, title, describe) { Flex({ direction: FlexDirection.Row,alignItems: ItemAlign.Center }){ Image(previewUrl) .width(30) .height(30) Text(title) .fontSize(16) .fontColor(Color.Black) .margin({left:8}) Text('100%') .fontSize(12) .fontColor(Color.Black) .margin({left:8}) Progress({ value: 20, total: 150, style: ProgressStyle.Linear }).color(Color.Red).value(150).width(200) Text('-100') .fontSize(14) .fontColor(Color.Gray) .margin({left:8}) } .width(400) .height(50) .margin({top:10}) } build() { List() { ForEach(this.PayData, (item) => { ListItem() { this.PayItem(item.image, item.name, item.des) } .onClick(() => { console.info("点击我") router.push({ uri: "pages/VideoPlayer", }) }) }, (item) => JSON.stringify(item)) { } } } }
build() { Flex({ direction: FlexDirection.Column,alignItems: ItemAlign.Center}) { Flex({ direction: FlexDirection.Row,alignItems: ItemAlign.Center}) { Image("/picture/icon_back.png") .width(35) .height(35) .onClick(() =>{ router.push({ uri: "pages/index", }) }) Text("加一笔") .fontSize(20) .fontWeight(FontWeight.Bold) .margin({left:20}) }.margin({top:10}) .padding({left:20}) .height(100) .width(500) Stack({ alignContent: Alignment.TopStart }){ Tabs() { TabContent() { pay({payTime:$strTime,payRemark:$strRemark,payType:$strType}) } .tabBar("支出") TabContent() { Income() } .tabBar("收入") } .height(450) }.width(500) .height(500) Flex({ direction: FlexDirection.Row,alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }){ Text("输入金额") .fontColor(Color.Black) .fontSize(20) .margin({ right:15 }) .width(100) TextInput({ placeholder: '100', text:this.strMoney }) .type(InputType.Normal) .placeholderColor(Color.Gray) .placeholderFont({ size: 20, weight: 2}) .enterKeyType(EnterKeyType.Search) .caretColor(Color.Green) .width(250) .height(40) .borderRadius('20px') } .width(400) .height(50) Text('保存') .fontColor(Color.White) .fontSize(20) .margin({ top:20 }) .textAlign(TextAlign.Center) .width(380) .height(80) .backgroundColor("#FE4F16") .onClick(() =>{ TestData.push({image:"/picture/icon1.png",title:'canyin',des:'ceshi',time:'2021',money:'50'}) if (AppStorage.Get("key1") == null) { AppStorage.SetAndLink("key1", TestData) this.remoteDataManager.dataChange("key2", JSON.stringify(TestData)) }else{ this.TestStorageData = AppStorage.Get("key1") // // this.TestStorageData.push({image:"/picture/icon1.png",title:'canyin',des:'beizhu',time:'2021',money:'50'}) //具体代码 this.TestStorageData.push({image:"/picture/icon1.png",title:this.strType,des:this.strRemark,time:this.strTime,money:this.strMoney}) AppStorage.SetAndLink("key1", this.TestStorageData) let str = JSON.stringify(this.TestStorageData) this.TestKvData = JSON.parse(str) this.remoteDataManager.dataChange("key2", JSON.stringify(this.TestKvData)) } router.push({ uri: "pages/index", }) }) } .width('100%') .height('100%') }
add页面支出模块
@Component struct pay{ @Link payTime:string @Link payRemark:string @Link payType:string @State private index:number = 0 @State strType:string = "canyin" @State AccountData: Array<any> = [ { previewUrl: "/picture/icon1.png", title: "canyin" ,number:0}, { previewUrl: "/picture/icon2_2.png", title: "gouwu" ,number:1}, { previewUrl: "/picture/icon3_3.png", title: "jiaotong" ,number:2}, { previewUrl: "/picture/icon4_4.png", title: "fuwu" ,number:3}, { previewUrl: "/picture/icon5_5.png", title: "jiaoyu" ,number:4}, { previewUrl: "/picture/icon6_6.png", title: "yundong" ,number:5}, { previewUrl: "/picture/icon7_7.png", title: "luxing" ,number:6}, { previewUrl: "/picture/icon8_8.png", title: "yiliao" ,number:7}, // { previewUrl: "/picture/icon9_9.png", title: "生活" ,number:9}, // { previewUrl: "/picture/icon10_10.png", title: "宠物" ,number:10}, ] @Builder ProItem(previewUrl, title,number) { Stack() { Flex({ direction: FlexDirection.Column }) { if (this.index == number) { if (number == 0) { Image("/picture/icon1.png") .width(60) .height(60) }else if (number == 1) { Image("/picture/icon2.png") .width(60) .height(60) }else if (number == 2) { Image("/picture/icon3.png") .width(60) .height(60) }else if (number == 3) { Image("/picture/icon4.png") .width(60) .height(60) }else if (number == 4) { Image("/picture/icon5.png") .width(60) .height(60) }else if (number == 5) { Image("/picture/icon6.png") .width(60) .height(60) }else if (number == 6) { Image("/picture/icon7.png") .width(60) .height(60) }else if (number == 7) { Image("/picture/icon8.png") .width(60) .height(60) }else if (number == 8) { Image("/picture/icon9.png") .width(60) .height(60) }else if (number == 9) { Image("/picture/icon10.png") .width(60) .height(60) } }else{ if (number == 0) { Image("/picture/icon1_1.png") .width(60) .height(60) }else{ Image(previewUrl) .width(60) .height(60) } } Column() { Text(title) .fontSize(16) .fontColor(Color.Black) } .alignItems(HorizontalAlign.Center) } } .height(100) .width(100) .margin({ bottom: 16 }) } build(){ Flex({direction: FlexDirection.Column}){ Grid(){ ForEach(this.AccountData, (item) => { GridItem() { this.ProItem(item.previewUrl, item.title,item.number) } .onClick(() => { console.info("点击我") this.index = item.number this.payType = this.AccountData[this.index].title }) }, (item) => JSON.stringify(item)) { } } .rowsTemplate('1fr 1fr') .columnsTemplate('1fr 1fr 1fr 1fr') .columnsGap(8) .rowsGap(8) .height(200) // Time() // Remark() // ******************时间********************** Flex({ direction: FlexDirection.Row,alignItems: ItemAlign.Center }){ Text("时间") .fontColor(Color.Black) .fontSize(20) .margin({ right:15 }) .width(70) TextInput({ placeholder: '输入收支时间', text: this.payTime }) .type(InputType.Normal) .placeholderColor(Color.Gray) .placeholderFont({ size: 20, weight: 2}) .enterKeyType(EnterKeyType.Search) .caretColor(Color.Green) .width(300) .height(40) .borderRadius('20px') .backgroundColor(Color.White) .onChange((value: string) => { this.payTime = value }) } .margin({ top:20,left:15 }) .width(200) //*******************备注******************** Flex({ direction: FlexDirection.Row,alignItems: ItemAlign.Center }){ Text("备注") .fontColor(Color.Black) .fontSize(20) .margin({ right:15 }) .width(70) TextInput({ placeholder: '输入说明', text: this.payRemark }) .type(InputType.Normal) .placeholderColor(Color.Gray) .placeholderFont({ size: 20, weight: 2}) .enterKeyType(EnterKeyType.Search) .caretColor(Color.Green) // .layoutWeight(8) .height(40) .width(300) .borderRadius('20px') .backgroundColor(Color.White) .onChange((value: string) => { this.payRemark = value }) } .margin({ top:20,left:15 }) .width(50) .height(50) } .height('100%') .layoutWeight(1) } }
收入模块代码
@Component
struct Income{
build(){
Flex({direction: FlexDirection.Column}){
Time()
Remark()
}
}
}
时间模块
@Component struct Time{ @State inputTime:string = '' build(){ Flex({ direction: FlexDirection.Row,alignItems: ItemAlign.Center }){ Text("时间") .fontColor(Color.Black) .fontSize(20) .margin({ right:15 }) .width(70) TextInput({ placeholder: '2021', text: this.inputTime }) .type(InputType.Normal) .placeholderColor(Color.Gray) .placeholderFont({ size: 20, weight: 2}) .enterKeyType(EnterKeyType.Search) .caretColor(Color.Green) .width(300) .height(40) .borderRadius('20px') .backgroundColor(Color.White) } .margin({ top:20,left:15 }) .width(200) } }
备注模块
@Component struct Remark{ @State inputRemark:string = '' build(){ Flex({ direction: FlexDirection.Row,alignItems: ItemAlign.Center }){ Text("备注") .fontColor(Color.Black) .fontSize(20) .margin({ right:15 }) .width(70) TextInput({ placeholder: 'ceshe', text: this.inputRemark }) .type(InputType.Normal) .placeholderColor(Color.Gray) .placeholderFont({ size: 20, weight: 2}) .enterKeyType(EnterKeyType.Search) .caretColor(Color.Green) // .layoutWeight(8) .height(40) .width(300) .borderRadius('20px') .backgroundColor(Color.White) } .margin({ top:20,left:15 }) .width(50) .height(50) } }
设备认证是依赖 DeviceManager 组件来实现的,详细代码参考源码RemoteDeviceModel.ets
1.创建DeviceManager实例
registerDeviceListCallback(callback) {
if (typeof (this.#deviceManager) === 'undefined') {
deviceManager.createDeviceManager('com.example.tictactoegame', (error, value) => {
if (error) return
this.#deviceManager = value;
this.registerDeviceListCallback_(callback);
});
} else {
this.registerDeviceListCallback_(callback);
}
}
2.查询可信设备列表
var list = this.#deviceManager.getTrustedDeviceListSync();
if (typeof (list) != 'undefined' && typeof (list.length) != 'undefined') {
this.deviceList = list;
}
3.注册设备上下线监听
this.#deviceManager.on('deviceStateChange', (data) => { switch (data.action) { case 0: this.deviceList[this.deviceList.length] = data.device; this.callback(); if (this.authCallback != null) { this.authCallback(); this.authCallback = null; } break; case 2: if (this.deviceList.length > 0) { for (var i = 0; i < this.deviceList.length; i++) { if (this.deviceList[i].deviceId === data.device.deviceId) { this.deviceList[i] = data.device; break; } } } this.callback(); break; case 1: if (this.deviceList.length > 0) { var list = []; for (var i = 0; i < this.deviceList.length; i++) { if (this.deviceList[i].deviceId != data.device.deviceId) { list[i] = data.device; } } this.deviceList = list; } this.callback(); break; default: break; } });
4.设备发现
this.#deviceManager.on('deviceFound', (data) => {
for (let i = 0; i < this.discoverList.length; i++) {
if (that.discoverList[i].deviceId === data.device.deviceId) {
return;
}
}
this.discoverList[this.discoverList.length] = data.device;
this.callback();
});
5.设备认证
authDevice(deviceInfo, callback){ let extraInfo = { "targetPkgName": 'com.example.tictactoegame', "appName": 'com.example.tictactoegame', "appDescription": 'com.example.tictactoegame', "business": '0' }; let authParam = { "authType": 1, "appIcon": '', "appThumbnail": '', "extraInfo": extraInfo }; this.#deviceManager.authenticateDevice(deviceInfo, authParam, (err, data) => { if (err) { this.authCallback = null; } else { this.authCallback = callback; } }); }
分布式数据管理
依赖@ohos.data.distributedData模块实现,详细参考源码RemoteDataManager.ets
1.导入该模块
import factory from '@ohos.data.distributedData';
2.创建KVManager实例,用于管理数据库对象
registerDataListCallback(callback) { let that = this if (this.kvManager == null) { try { const config = { userInfo: { userId: '0', userType: 0 }, bundleName: 'com.example.tictactoegame' } factory.createKVManager(config).then((manager) => { that.kvManager = manager that.registerDataListCallback_(callback) }).catch((err) => { }) } catch (e) { } } else { this.registerDataListCallback_(callback) } }
3.创建并获取KVStore数据库
registerDataListCallback_(callback) { let that = this if (that.kvManager == null) { callback() return } if (that.kvStore == null) { try { let options = { createIfMissing: true, encrypt: false, backup: false, autoSync: true, kvStoreType: 1, securityLevel: 3 } this.kvManager.getKVStore(this.STORE_ID, options).then((store) => { that.kvStore = store that._registerDataListCallback_(callback) }).catch((err) => { }) } catch (e) { } } else { this._registerDataListCallback_(callback) } }
4.订阅指定类型的数据变更通知
_registerDataListCallback_(callback) {
let that = this
if (that.kvManager == null) {
callback()
return
}
this.kvStore.on('dataChange', 1, function(data) {
if (data) {
that.arr = data.updateEntries
callback()
}
})
}
5.添加指定类型键值对到数据库
startAbilityContinuation(deviceId) {
let wantValue = {
bundleName: 'com.example.tictactoegame',
abilityName: 'com.example.tictactoegame.MainAbility',
deviceId: deviceId,
parameters: {
uri: 'pages/Fight'
}
};
featureAbility.startAbility({ want: wantValue }).then(() => {
router.replace({ uri: 'pages/Fight' })
});
}
使用 FeatureAbility 模块的startAbility接口拉起远程设备app
startAbilityContinuation(deviceId) {
let wantValue = {
bundleName: 'com.example.tictactoegame',
abilityName: 'com.example.tictactoegame.MainAbility',
deviceId: deviceId,
parameters: {
uri: 'pages/Fight'
}
};
featureAbility.startAbility({ want: wantValue }).then(() => {
router.replace({ uri: 'pages/Fight' })
});
}
新建一个账单数据 添加到分布式数据
this.remoteDataManager.dataChange("key2", JSON.stringify(this.TestKvData))
在另一台设备监听并获取显示该条数据
private onPageShow() {
this.remoteDataManager.registerDataListCallback(() => {
let arr = this.remoteDataManager.arr[0]
this.strTest = arr.value.value
this.ProjectData = JSON.parse(this.strTest)
}
为了能让大家更好的学习鸿蒙(HarmonyOS NEXT)开发技术,这边特意整理了《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05
https://qr21.cn/FV7h05
入门必看:https://qr21.cn/FV7h05
1. 应用开发导读(ArkTS)
2. ……
HarmonyOS 概念:https://qr21.cn/FV7h05
如何快速入门:https://qr21.cn/FV7h05
1. 基本概念
2. 构建第一个ArkTS应用
3. ……
开发基础知识:https://qr21.cn/FV7h05
1. 应用基础知识
2. 配置文件
3. 应用数据管理
4. 应用安全管理
5. 应用隐私保护
6. 三方应用调用管控机制
7. 资源分类与访问
8. 学习ArkTS语言
9. ……
基于ArkTS 开发:https://qr21.cn/FV7h05
1. Ability开发
2. UI开发
3. 公共事件与通知
4. 窗口管理
5. 媒体
6. 安全
7. 网络与链接
8. 电话服务
9. 数据管理
10. 后台任务(Background Task)管理
11. 设备管理
12. 设备使用信息统计
13. DFX
14. 国际化开发
15. 折叠屏系列
16. ……
https://qr21.cn/FV7h05
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。