先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新HarmonyOS鸿蒙全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip204888 (备注鸿蒙)
正文
.width(‘100%’)
.border({ width: 1 })
}
}
在题目展示及答题区组件加载之前,先去加载后台数据,获取题目列表数据进行解析,获取到题目列表和题目总数。在答题的过程中,每当用户答完一道题后,已完成数目便会+1,由于父组件与该组件之间是**@Link**进行的双向数据传递,所以在该组件中获取到的数据,以及对于变量的修改,在父组件重视可以被感知的。
//渲染之前进行网络请求
aboutToAppear(): void {
//初始化数据
let list = []
//获取网络请求
let httpRequest = http.createHttp();
httpRequest.request(“localhost:8899/homp/getAll”, (err, data) => {
if (!err) {
//数据解析
const response = data.result.toString();
const res = JSON.parse(response).data
for (let i = 0; i < res.length; i++) {
let item = res[i];
list.push({
id: item.sequenceNumber,
name: item.name,
optionA: item.optionA,
valA: item.valA,
optionB: item.optionB,
valB: item.valB,
});
// console.log(list[i].id)
}
this.allTopic = res.length //进行总题目数的修改
} else {
console.info(‘error:’ + JSON.stringify(err));
}
});
this.data = new MyDataSource(list)
}
特别注意:由于网络请求这块不算做是默认存在的,得手动开启网络访问权限之后,才可以进行网络数据的获取,主要是对src/main/路径下的module.json5文件进行添加如下代码
//网路权限
“requestPermissions”: [
{
“name”: “ohos.permission.INTERNET”,
“usedScene”: {
“when”: “always”
}
}
]
而在主体答题区呢 主要是用到了一个Swiper组件,类似于实现答一题进行自动翻页的效果,并将获取到的数据进行循环渲染。而在游标到达最后一题,并且已经答完时,跳转至结果展示界面等待后端计算返回性格测评的结果
//答题区
Swiper(this.swiperController) {
LazyForEach(this.data, (item: Topic) => {
//嵌套组件 显示题目
Column() {
//题干
Text(item.id + ". " + item.name)
//选项A
Button() {
Row() {
Text(item.optionA)
}
}
.type(ButtonType.Normal)
.optionStyle()
.onClick(() => {
let index = Number(item.id)
this.finishTopic = index
if (index === this.data.totalCount()) {
//1-保存值
this.res.push(item.valA)
let ans = this.res.join(‘’)
console.log(“ans:” + ans)
//跳转界面(携带拼接好的选项字符串)
router.replaceUrl({
url: ‘pages/ShowResPage’,
params: {
ans: ans,
}
})
} else {
//1-保存值
this.res.push(item.valA)
//2-换到下一题
this.swiperController.showNext()
}
})
//选项B
Button() {
Row() {
Text(item.optionB)
}
}.type(ButtonType.Normal)
.optionStyle()
.onClick(() => {
let index = Number(item.id)
this.finishTopic = index
if (index === this.data.totalCount()) {
//如果到最后一题了 显示提交按钮
//1-保存值
this.res.push(item.valB)
let ans = this.res.join(‘’)
console.log(“ans:” + ans)
//跳转界面
router.replaceUrl({
url: ‘pages/ShowResPage’,
params: {
ans: ans,
}
})
} else {
//1-保存值
this.res.push(item.valB)
//2-换到下一题
this.swiperController.showNext()
}
})
}.width(‘90%’)
.height(180)
.justifyContent(FlexAlign.SpaceEvenly)
}, item => item)
}
.cardStyle() //自定义卡片样式
.cachedCount(2)
.index(0)
.interval(4000)
.indicator(false)
.loop(false)
.duration(1000)
.itemSpace(0)
.disableSwipe(true)
.curve(Curve.Linear)
.onChange((index: number) => {
// console.info(index.toString() + this.res.join(‘’))
})
答题进度中,由于父组件与展示题目子组件之间数据类似于双向绑定,在答题组件进行操作,答题后,会对已完成题目这个变量进行修改,而变量的变化能够被子组件感知并单向传递给进度组件,所以整个过程中,进度组件的显示也会随答题而发生变化
/***
- 题目列表中的进度模块
*/
@Component
export struct ProgressComponent {
@Prop finishTopic: number
@Prop allTopic: number
build() {
Column() {
Row() {
Text(‘答题进度:’)
.fontSize(20)
.fontWeight(FontWeight.Bold)
Stack() {//堆叠组件,将一个进度条和两个文本框进行堆叠,展示出比较好看的效果
Progress(
{
value: this.finishTopic,
total: this.allTopic,
type: ProgressType.Ring
}).width(80)
Row() {
Text(this.finishTopic.toString())
.fontWeight(18)
.fontColor(“#36D”)
Text(’ / ’ + this.allTopic.toString())
.fontWeight(18)
.fontColor(Color.Black)
}
}
}.cardStyle()
.margin({ top: 15, left: 10, right: 10 })
.justifyContent(FlexAlign.SpaceEvenly)
.backgroundColor(“#FAEBD7”)
}
}
}
//自定义卡片样式
@Styles function cardStyle() {
.width(“95%”)
.padding(20)
.backgroundColor(Color.White)
.borderRadius(15)
.shadow({ radius: 6, color: ‘#1F000000’, offsetX: 2, offsetY: 4 })
}
那为了方便大家对于这块的理解,我做了如下的图示,方便大家理解父子组件传值在本案例中的应用
结果展示界面搭建
结果展示界面也是将一些布局以组件的形式提取出去,方便以后的复用等,为了防止一些内容显示不下,整个页面是在一个滚动组件中进行的布局,滚动布局中还是包括三段,顶部提示栏,图片展示栏,以及底部的属性面板;
在进入该页面时,在界面加载渲染之前同样是接收答题界面传递过来的答题选项字符串,在接收到这个答题选项字符串后进行后端数据的请求,请求采用post请求,携带结果字符串,经过后端接口计算后返回测试结果以及性格属性值
//post请求
aboutToAppear() {
//获取网络请求
let httpRequest = http.createHttp();
httpRequest.request(“localhost:8899/homp/submit”,
{
method: http.RequestMethod.POST,
extraData: {
“ans”: this.paramsFromIndex?.[‘ans’],
}
},
(err, data) => {
if (!err) {
const response = data.result.toString();
const res = JSON.parse(response).data
this.resShow = res;
console.log(“this.resShow.res:” + this.resShow.res)
this.resStr = this.resShow.res
console.log(“resStr:” + this.resStr)
}
})
}
这三部分分别对应着三个自定义组件,标题组件之前有提到过,在这不做过多的赘述,我们重点看一下其他两个组件
图片组件
在结果展示页面获取到后端返回的测试结果后,解析成为一个结果对象,获取到对象的性格简称,传递给图片组件,图片组件在拿到性格简称之后,通过字符串拼接获取到资源文件下的相关性格图片进行展示。同时还为图片添加了简单的动画效果
@Component
// @Entry
export struct ImageComponent {
@State clicked: boolean = false;
@Prop resStr: string
// @State resStr: string = ‘ENTP’
build() {
Row() {
Column() {
Image($rawfile(this.resStr + “.png”))
.width(“60%”)
.height(“60%”)
.objectFit(ImageFit.Contain)
// .border({ width: 1 })
.rotate({
x: 0,
y: 1,
z: 0,
angle: this.clicked ? 360 : 0
})
.scale(
this.clicked
? { x: 1.25, y: 1.25 }
: { x: 1, y: 1 }
)
.opacity(this.clicked ? 0.6 : 1)
.onClick(() => {
this.clicked = !this.clicked;
})
.animation(
{
delay: 10,
duration: 1000,
iterations: 1,
curve: Curve.Smooth,
playMode: PlayMode.Normal
}
)
Text(this.resStr)
.fontSize(25)
.width(“90%”)
.height(“20%”)
.decoration({
type: TextDecorationType.Underline,
color: Color.Orange
})
.fontWeight(FontWeight.Bold)
.textAlign(TextAlign.Center)
}.justifyContent(FlexAlign.SpaceEvenly)
}
.height(“30%”)
.cardStyle()
.margin({ top: 15 })
// .border({ width: 1 })
.alignItems(VerticalAlign.Center)
.justifyContent(FlexAlign.Center)
}
}
属性面板组件
在结果展示页面获取到后端返回的测试结果后,解析成为一个结果对象,将这个对象使用**@ObjectLink**整体作为数据进行传递到属性面板组件,在拿到这个对象后,获取相关的一些字段进行渲染即可
在进行一些占比数据的渲染时,使用到了HarmonyOs内置滑动条组件( Slider),展示一些占比情况
import { Res } from ‘…/data/RES’
//属性面板
@Component
// @Entry
export struct PropertiesPanelComponent {
@ObjectLink resReturn: Res
build() {
Column() {
Column() {
Row() {
Text(‘erate’).fontSize(12)
Slider({
value: Number(this.resReturn.erate),
min: 0,
max: 40,
style: SliderStyle.InSet
}).panelStyle()
Text(this.resReturn.erate + " %").fontSize(12)
}.width(‘80%’)
.justifyContent(FlexAlign.SpaceAround)
Row() {
Text(‘irate’).fontSize(12)
Slider({
value: Number(this.resReturn.irate),
min: 0,
max: 40,
style: SliderStyle.InSet
}).panelStyle()
Text(this.resReturn.irate + " %").fontSize(12)
}.width(‘80%’)
.justifyContent(FlexAlign.SpaceAround)
Row() {
Text(‘srate’).fontSize(12)
Slider({
value: Number(this.resReturn.srate),
min: 0,
max: 40,
style: SliderStyle.InSet
}).panelStyle()
Text(this.resReturn.srate + " %").fontSize(12)
}.width(‘80%’)
.justifyContent(FlexAlign.SpaceAround)
Row() {
Text(‘nrate’).fontSize(12)
Slider({
value: Number(this.resReturn.nrate),
min: 0,
max: 40,
style: SliderStyle.InSet
}).panelStyle()
Text(this.resReturn.nrate + " %").fontSize(12)
}.width(‘80%’)
.justifyContent(FlexAlign.SpaceAround)
Row() {
Text(‘trate’).fontSize(12)
Slider({
value: Number(this.resReturn.trate),
min: 0,
max: 40,
style: SliderStyle.InSet
}).panelStyle()
Text(this.resReturn.trate + " %").fontSize(12)
}.width(‘80%’)
.justifyContent(FlexAlign.SpaceAround)
Row() {
Text(‘frate’).fontSize(12)
Slider({
value: Number(this.resReturn.frate),
min: 0,
max: 40,
style: SliderStyle.InSet
}).panelStyle()
Text(this.resReturn.frate + " %").fontSize(12)
}.width(‘80%’)
.justifyContent(FlexAlign.SpaceAround)
Row() {
Text(‘jrate’).fontSize(12)
Slider({
value: Number(this.resReturn.jrate),
min: 0,
max: 40,
style: SliderStyle.InSet
}).panelStyle()
Text(this.resReturn.jrate + " %").fontSize(12)
}.width(‘80%’)
.justifyContent(FlexAlign.SpaceAround)
Row() {
Text(‘prate’).fontSize(12)
Slider({
value: Number(this.resReturn.prate),
min: 0,
max: 40,
style: SliderStyle.InSet
}).panelStyle()
Text(this.resReturn.prate + " %").fontSize(12)
}.width(‘80%’)
.justifyContent(FlexAlign.SpaceAround)
}.cardStyle()
.margin({ top: 15 })
Column() {
Text(‘disc’).fontSize(12).margin({ bottom: 15 })
Text(this.resReturn.disc)
.fontSize(14)
.maxLines(15)
.lineHeight(20)
}.cardStyle()
.margin({ top: 15 })
.justifyContent(FlexAlign.SpaceAround)
}.width(“100%”)
.height(“80%”)
.alignItems(HorizontalAlign.Center)
}
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注鸿蒙)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
c’).fontSize(12).margin({ bottom: 15 })
Text(this.resReturn.disc)
.fontSize(14)
.maxLines(15)
.lineHeight(20)
}.cardStyle()
.margin({ top: 15 })
.justifyContent(FlexAlign.SpaceAround)
}.width(“100%”)
.height(“80%”)
.alignItems(HorizontalAlign.Center)
}
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注鸿蒙)
[外链图片转存中…(img-ikrlLCnH-1713215876314)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!