#星计划#梅科尔工作室HOS-我和鸿蒙的故事 原创
开发经历
2022年12月-2023年9月:系统性完成鸿蒙学习,能够完整使用DevEco Studio进行鸿蒙App的开发和测试;
2023年8月-2024年1月在自闭症项目开发鸿蒙app模块;能够完成基础页面开发、前后端交互例如:图片上传和命令下发,图片的动态变化,折线图,AI大模型等功能; 通过华为考试认证:
<HarmonyOS第一课>系列证书:
<Harmony0S主题课>ArkUI之属性动画、<Harmony0S主题课>三方库、<Harmony0S主题课>使用DevEco Studio高效开发
获得harmonyOS应用开发者基础认证
项目开发
具体展示:
用到的主要功能
1、AI大模型页面
首先是主函数build()来排版对话框:
chat设置三个属性:
id:number; //根据这个数字循环
content: string; // 聊天内容
role: Boolean; // 聊天角色
这三个属性参与遍历
export class Chat {
id:number; //根据这个数字循环
content: string; // 聊天内容
role: Boolean; // 聊天角色
constructor(id:number, content: string, role: Boolean) {
this.id=id;
this.content = content;
this.role = role;
}
}
用List列表(消息弹窗布局更加方便)和 ForEach循环(循环遍历消息弹窗列表,然后每条消息往下排版);
通过判断角色是我还是对方(if语句:初始化时第一个是机器人角色,id先设为1,角色布尔类型设为true)分别写左右两个弹窗;
List() {
ForEach(this.arr, (item: Chat) => {
ListItem() {
if(item.role){
Row({ space: 8 }){
Image($r("app.media.jiqiren3"))
.width(48)
.height(48)
.borderRadius(8)
Row(){
Text(item.content)
.fontSize(16)
.copyOption(CopyOptions.LocalDevice)
.fontColor("#FFFFFF")
}.width("60%")
.borderRadius(12)
.padding({ top: 14, right: 10, bottom: 14, left: 10 })
.shadow({
radius: 12,
color: 0xE1E3E5,
offsetX: 4,
offsetY: 4
})
.backgroundColor('#ff4c4bf3')
}.width("95%")
.justifyContent(FlexAlign.Start)
}else{
Row({ space: 8 }){
Row(){
Text(item.content)
.fontSize(16)
.copyOption(CopyOptions.LocalDevice)
}.justifyContent(FlexAlign.End)
.borderRadius(12)
.padding({ top: 14, right: 10, bottom: 14, left: 10 })
.shadow({
radius: 12,
color: 0xE1E3E5,
offsetX: 4,
offsetY: 4
})
.backgroundColor('#FFFFFF')
Image($r("app.media.head"))
.width(48)
.height(48)
.borderRadius(8)
}.width("100%")
.justifyContent(FlexAlign.End)
.alignItems(VerticalAlign.Top)
}
} }, (item: Chat) => item.id.toString())
}
.width("100%")
.height("80%")
Column(){}.height(400)
}
.width('100%')
.alignItems(HorizontalAlign.Start)
接着写输入框,点击按钮,角色会改变(id加1;布尔类型由true变为false),我的问题发送;
Row({ space: 6 }) {
TextInput({ placeholder: '我想问...', text: this.title })
.width('90%')
.height(50)
.backgroundColor('#CECECE')
.position({x:5,y:5})
.onChange((value: string) => {
this.title = value;
})
Image(this.button)
.position({x:690,y:12})
.width(36).height(36)
.fillColor("#5868E8")
.onClick(() => {
this.bianhua()
this.myid++
this.arr.push(new Chat(this.myid,this.title,false))
setTimeout(() => {
this.S_login()
}, 10);
this.loadingController.open();
var intervalID1 = setInterval(
() => {
this.timetext--
if(this.timetext == 0){
clearInterval(intervalID1)
this.loadingController.close();
}
}, 1000)
this.timetext = 3
})
}
同时调用方法:this.S_login()对话框中的内容来自和后端连接的问题库,存入this.arr.push(new Chat(this.myid,data.result.toString(),true)),
S_login() {
let jsondata;
let httpRequest = http.createHttp();
let url = "http://123.60.166.120:9000/zibi"
httpRequest.request(
// 填写HTTP请求的URL地址,可以带参数也可以不带参数。URL地址需要开发者自定义。请求的参数可以在extraData中指定
url,
{
method: http.RequestMethod.POST, // 可选,默认为http.RequestMethod.GET
// 开发者根据自身业务需要添加header字段
header: {
'Content-Type': 'application/json'
},
// 当使用POST请求时此字段用于传递内容
extraData: {
"username": this.title,
},
connectTimeout: 6000, // 可选,默认为60000ms
readTimeout: 6000, // 可选,默认为60000ms
}, (err, data) => {
if (!err) {
// data.result为HTTP响应内容,可根据业务需要进行解析
if (data.responseCode == 200) {
console.info("传递成功")
this.myid++
this.arr.push(new Chat(this.myid,data.result.toString(),true))
console.info("从服务器返回接口返回数据成功,传递参数" + jsondata)
console.info(this.arr[2].content.toString())
}
} } );
}
2、折线图
折线图的横竖坐标数字传参:
export default class PageResource {//页面资源传参
title?: string;
others?: string;
others_2?:string;
img_2?:Resource;
others_3?:string
number_1?:number
constructor(
title?: string,
others?: string,
others_2?:string,
img_2?:Resource,
others_3?:string,
number_1?:number
) {
this.title = title;
this.others = others;
this.others_2 = others_2;
this.img_2 = img_2;
this.others_3 = others_3;
this.number_1= number_1;
}
}
折线图的每个点的坐标数据传参:
export default class PageResource {//数据表类
number_1?: number;
number_2?: number;
number_3?: number;
number_4?:number;
number_5?:number;
number_6?:number
number_7?:number
constructor(
number_1?: number,
number_2?: number,
number_3?: number,
number_4?: number,
number_5?: number,
number_6?: number,
number_7?: number
) {
this.number_1= number_1;
this.number_2= number_2;
this.number_3= number_3;
this.number_4= number_4;
this.number_5= number_5;
this.number_6= number_6;
this.number_7= number_7;
}
}
foreach循环遍历列表:
import ItemData from './ItemData';
import ItemData_2 from '../viewmodel/ItemData_2';
export class MainViewModel {
getSettingColumnData_bg_1_1(): Array<ItemData> {
let settingListData: ItemData[] = [
new ItemData(' 105 ','2','',),
new ItemData(' 100 ','2','',),
new ItemData(' 95 ','2',''),
new ItemData(' 90 ','2',''),
new ItemData(' 85 ','2',''),
new ItemData(' 80 ','0',''),
];
return settingListData;
}
getSettingColumnData_bg_2(): Array<ItemData> {
let settingListData: ItemData[] = [
new ItemData(' ','2',''),
new ItemData(' ','2'),
new ItemData(' ','2'),
new ItemData(' ','2'),
new ItemData(' ','0'),
new ItemData(' ','0'),
];
return settingListData;
}
getSettingColumnData_bg_4_jg(num : number,num_2 : number,num_3 : number,
num_4 : number,num_5 : number,num_6 : number): Array<ItemData_2> {//动态表格数据传输_测试_折线_碳价预测
let settingListData: ItemData_2[] = [
new ItemData_2(37,74,num,num_2),
new ItemData_2(0,37,num_2,num_3),
new ItemData_2(0,37,num_3,num_4),
new ItemData_2(0,37,num_4,num_5),
new ItemData_2(0,37,num_5,num_6),
];
return settingListData;
}
}
export default new MainViewModel();
折线图背景线 (for each循环出竖轴坐标和横线)
ForEach(MainViewModel.getSettingColumnData_bg_1_1(), (Item_sj: ItemData) => {
Row({ space: 10 }) {
Text(Item_sj.title).fontSize(13)
Line()
.opacity(Item_sj.number_1)
.height(10)
.stroke(1)
.startPoint([0, 0])
.endPoint([220, 0])
.strokeDashArray([6, Item_sj.others])
}.margin({ top: 10 })
})
循环遍历横轴的坐标
Column() {
Row({ space: 30 }) {
ForEach(MainViewModel.getSettingColumnData_bg_2(), (Item_sj: ItemData) => {
Text('')
.padding({ left: 6 })
.borderWidth({ left: 0.6, })
.offset({ x: 1, y: -8 })
})
}
}
两条折线:后端传来的数据,就是折线上下波动的参数
Column() {
Stack() {
Row() {
ForEach(MainViewModel.getSettingColumnData_bg_4_jg(this.number11[0], this.number11[1], this.number11[2],
this.number11[3], this.number11[4], this.number11[5]), (Item_zx: ItemData_2) => {
Line()
.opacity(1)
.height(10)
.stroke('#DE868F')
.strokeWidth(2)
.startPoint([Item_zx.number_1, Item_zx.number_3])
.endPoint([Item_zx.number_2, Item_zx.number_4])
})
}
Row() {
ForEach(MainViewModel.getSettingColumnData_bg_4_jg(this.number22[0], this.number22[1], this.number22[2],
this.number22[3], this.number22[4], this.number22[5]), (Item_zx: ItemData_2) => {
Line()
.opacity(1)
.height(10)
.stroke('#347CAF')
.strokeWidth(2)
.startPoint([Item_zx.number_1, Item_zx.number_3])
.endPoint([Item_zx.number_2, Item_zx.number_4])
})
}
}}
3、倒计时
倒计时弹窗组件
外观:
@CustomDialog
struct CustomDialogExample {
@Link timetext: number
controller: CustomDialogController
build() {
Column() {
Row(){
Text(this.timetext.toString()).fontSize(150).fontColor("white").fontWeight(600)
}
.width(200).height(200).borderRadius(200).backgroundColor("#4095E5").opacity(0.9)
.justifyContent(FlexAlign.Center).alignItems(VerticalAlign.Center)
}
.width("100%").height("100%").justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center)
}
}
组件类型:
dialogController: CustomDialogController = new CustomDialogController({
builder: CustomDialogExample({timetext: $timetext}),
gridCount:45,
autoCancel: false
})
点击按钮,弹窗启动,开始倒计时,数字到0的时候,弹窗关闭;
.onClick(() => {
this.dialogController.open()
var intervalID1 = setInterval(
() => {
this.timetext--
if (this.timetext == 0) {
clearInterval(intervalID1)
this.dialogController.close()
}
}, 1000)
this.timetext = 3
})
未来的学习之路
我学习鸿蒙已经有一年多的时间了,已经对ArkTS这个语言有了基本的掌握;对于我自身而言,也算是有了一门自己比较擅长的语言;
目前我已完成harmonyOS应用开发者基础认证,下一步计划学习完高级认证的相关课程,并且拿到高级认证证书;在这同时我会持续开发,脚步不停,不断学习和尝试新的功能;多实操,而不是仅仅局限于了解,把每一个功能都吃透,并且做相应的拓展;
鸿蒙虽然容易上手,看起来简单,实际上有许多需要挖掘的地方,我希望我能成为一名合格的鸿蒙开发者,最终能够独立自主实现一个软件的开发;
鸿蒙的学习之路,道阻且长。