《极客快讯》app开发技术分享(一)–登录界面的实现
楔子
随着鸿蒙正式版发布的时间越来越近,发现很多观望鸿蒙的小伙伴也都跃跃欲试,准备投入到鸿蒙应用开发中来,但是苦于没有学习路线和项目进行练习,大部分人都会加群问来问去,少部分自学的同学对着小破站的项目教程也已经练习了起来,学会了各种鸿蒙开发技巧和实战经历,在浏览完网上各式各样的教学视频后发现,大部分教学到了关键的项目处都停止更新了,其中的原因大家都明白,同时也表示理解和支持。
那有没有一个完整的,难度不是那么高的项目,用来给那些已经入门鸿蒙,但是没有目标的同学一个跟练的项目呢?带着这样的想法,我开始了翻阅,结果当然是不尽人意。想了想在其他移动开发平台中有《第一行代码》 《玩安卓》等这些引路资源,那能不能在鸿蒙中去实现?同时把自己的想法、思路、经验描述成文字,帮助读者更好的理解呢?练习的目的是为了能帮助自己更好的进行开发工作,同时也不能脱离前后端交互。
带着这样的想法在Deveco Studio中创建了工程,《极客快讯》项目启动了。既然要做前后端交互,那一个稳定的后端服务是必不可少的,这里也对鸿洋大神的开放api表示感谢,借着开放api,来实现一个鸿蒙版的资讯应用,应用中的功能采用harmonyOSNEXT技术来进行开发,通过对已经掌握的组件、api的使用来逐步实现和完善应用。实现的内容也会分章节进行开放,供各位读者学习,如果有见解和问题也欢迎留言指正,同时也再次感谢鸿洋大神提供的api接口
注意!!!!本文默认您已经对arkui的相关组件有了大致的认知,如果是0基础,建议先看一下官方的入门视频,了解各个组件的实现
项目介绍
这个项目根据接口来本身会是一个纯资讯查看类型的项目,功能有首页、广场、公众号、体系、项目、个人中心、配置项等,但是对于一个想学到更多知识的应用来说,这些是不够的,我会根据一些开放api和鸿蒙api中的进阶功能进行项目内容的填充,比如一个完整的地区选择,一个小天气预报还有文字转语音、文字识别等功能,同时保证饮用场景更加倾向于商业项目,尽量保证即学即用,做到无缝衔接,项目初期会快速的搭建项目和实现功能,初具雏形之后开始对项目结构进行优化和改造,让整个项目的结构也偏向于商业项目,尽量保证对商业项目开发的熟悉程度。
当然了,文章的查看是枯燥无味的,后续会针对项目做一个开发课程,供读者去观看,同时所有的内容也都是开源的。
项目链接:https://gitee.com/Lin1001/wan-harmony
视频会在上架后同步到评论区
开发准备
虽然很多资讯内容可以直接浏览并不需要用户登录,但是我们还是按部就班的进行开发,在大部分功能实现之后我们再开启游客模式,我们首先实现应用的登陆和注册功能。
要实现登录和注册功能,我们要做如下准备
1.绘制登陆和注册的页面
2.通过网络请求对应的接口来实现注册和登录的功能
3.如果登录后有用户认证的token信息,我们要保存起来
我们要实现的主要功能就是这些
代码实现
要实现登录和注册功能,首先要进行页面的绘制,数据的监听然后是请求接口根据状态判断成功失败
想要实现这些我们需要用到如下组件:
1.textinput 输入框组件 ,可以用它来进行内容的输入
2.button 按钮组件,对输入的内容进行提交
3.网络请求,这里我们使用axios
登录页面包含的内容如上所示,接下来我们进行相关代码的实现
参数定义:
要想实现数据的监听,我们首先就要进行变量的定义,这样方便我们去根据获取的值处理业务逻辑,arkui中有@state 可以监听修饰变量的值,所以我们的变量都用它来进行修饰
@State name: string = ‘’;
@State pass: string = ‘’;
controller: TextInputController = new TextInputController()
@State handlePopup: boolean = false
@State msg: string = ‘’
@State btnenabled: boolean = true;
@State checkStatus:boolean=false
private context?: common.UIAbilityContext;
1.logo
2.文字展示
这里只需要使用Image组件来展示图片(ps:可以加载本地资源和网络图片链接,如果加载了网络图片不要忘记申请联网权限),text组件来展示文本,并且使用属性来对样式进行调整即可
Image(“https://tse2-mm.cn.bing.net/th/id/OIP-C.R6SvvWet47fnztOLem9WTAHaEn?rs=1&pid=ImgDetMain”)
.width(‘100%’)
Text(“玩鸿蒙”)
.fontSize(38)
.fontWeight(FontWeight.Bold)
.fontColor(‘#4a9deb’)
.margin({top:30})
Text(“WANHARMONY”)
.fontSize(20)
.margin({top:10})
.fontWeight(FontWeight.Bold)
.fontColor(‘#4a9deb’)
Text()
.height(60)
3.账号密码输入
Row(){
Image($r(‘app.media.yonghu’))
.height(18)
.width(18)
TextInput({ text: this.name, placeholder: ‘输入账号’, controller: this.controller })
.placeholderFont({ size: 16, weight: 400 })
.width(180)
.height(35)
.maxLength(12)
.type((InputType.Number))
.backgroundColor(“#f8f8f8”)
.onChange((value: string) => {
this.name = value
})
.margin({left:10})
}
.padding({left:20})
.width(‘80%’)
.borderRadius(20)
.backgroundColor(“#f8f8f8”)
Row(){
Image($r(‘app.media.mima’))
.height(18)
.width(18)
TextInput({ text: this.pass, placeholder: ‘输入密码’, controller: this.controller })
.placeholderFont({ size: 16, weight: 400 })
.width(180)
.height(35)
.backgroundColor(“#f8f8f8”)
.maxLength(12)
.showPasswordIcon(false)
.type((InputType.Password))
.alignRules({
middle: { anchor: ‘container’, align: HorizontalAlign.Center }
})
.onChange((value: string) => {
this.pass = value
})
}
.margin({top:20})
.padding({left:20})
.width(‘80%’)
.borderRadius(20)
.backgroundColor(“#f8f8f8”)
4.登录按钮
Button(“登 录”)
.type(ButtonType.Normal)
.backgroundColor(‘#4a9deb’)
.width(‘75%’)
.fontSize(20)
.height(50)
.margin({top:20})
.borderRadius(5)
.enabled(this.btnenabled)
.onClick(() => {
if (this.checkStatus) {
}else {
showToast("请阅读并勾选同意相关协议")
}
})
5.同意隐私协议
Row(){
Checkbox({name: ‘checkbox2’, group: ‘checkboxGroup’})
.select(false)
.selectedColor(0x39a2db)
.onChange((value: boolean) => {
if (value) {
this.checkStatus=true
}else {
this.checkStatus=false
}
})
Text(){
Span(“我已阅读并同意”)
.fontSize(12)
Span(“法律声明及隐私协议”)
.fontColor(“#4a9deb”)
.fontSize(12)
.onClick(()=>{
showToast(“隐私协议”)
})
Span(“和”)
.fontSize(12)
Span("用户协议")
.fontColor("#4a9deb")
.fontSize(12)
.onClick(()=>{
showToast("用户协议")
})
}
}
.margin({top:15})
6.注册入口
Text(“注册”)
.width(‘100%’)
.height(45)
.textAlign(TextAlign.End)
.padding({right:50,top:20})
.fontColor(“#4a9deb”)
.onClick(()=>{
router.pushUrl({url:‘pages/RegisterPage’})
})
这些组件我们统一放置到column 容器中,实现的效果如下