简言:
gitee地址:https://gitee.com/whltaoin_admin/money-controller-app.git
端云一体化开发在线文档:
注:此App参照此教程进行二次修改:https://www.bilibili.com/video/BV1q5411v7o7
一、简介
moneyControllerApp(MCA)
这款精心打造的个人财务管理应用,是您理财路上的智慧伙伴。凭借前沿的智能化技术与直观易用的界面设计,它将化繁为简,让您的财务状况一目了然。无论是日常收支的记录,还是复杂财务的分析,都能轻松应对。它不仅帮助您有效掌控每一笔收入与支出,更助您洞悉财务趋势,科学规划未来,让财富增长之路更加清晰可见。从此,财务管理不再是难题,而是通往财务自由的桥梁。
在鸿蒙HarmonyOS Next版本的加持下,这款个人财务管理应用的性能与体验再度升级,成为您理财旅程中的超级智慧伙伴。鸿蒙系统的分布式技术,使得应用运行更加流畅稳定,数据同步更加快速准确,即使在多设备间切换,也能无缝衔接,确保您的财务信息实时更新,安全无忧。
二、什么是端云一体化开发
为丰富HarmonyOS对云端开发的支持、实现端云联动,DevEco Studio以Cloud Foundation Kit(云开发服务)为底座、在传统的“端开发”基础上新增“云开发”能力,开发者在创建工程时选择合适的云开发工程模板,即可在DevEco Studio内同时完成HarmonyOS应用的端侧与云侧开发,体验端云一体化协同开发。
三、开发环境介绍
编辑器 |
DevEco Studio NEXT Developer Beta1 |
SDK |
11 |
操作系统 |
Window 10 专业版 |
模拟器 |
HarmonyOS Emulator Version: 5.0.3.405 HarmonyOS Version: HarmonyOS NEXT Developer Beta1 |
四、项目初始化
- 步骤一:
/* 1 create project 2 application选择>>>[cloudDev] Empty Ability>>>Next */
- 步骤二:输入图中信息后>>>点击Finish
- 注意:存放路径不建议使用中文字符
- 步骤三:进入项目主页>>>点击右上角的头像进行用户登录。
- 步骤四:
// 1 进入网址并进行登录:https://developer.huawei.com/consumer/cn/ // 2 登录后在网站首页点击管理中心 // 3 点击左侧边栏(生态服务-应用服务)>>>点击AppGallery Connect // 4 进入到以下页面
- 步骤四:
// 1 点击我的项目>>>新建项目 // 2 数据处理位置选择中国并设置为默认 // 3 点击完成后并添加应用 // 4 注意:创建应用时如果想要自定义包名的话,定义的包名必须和新建项目时写的包名一致。 // 5 创建应用完成后,点击Next后,新建项目既可创建完成。
五、项目构建静态页面
1. 登录注册页面
- 效果图
结构:
// 一个页面:Login.etc // 两个组件: // 头部标题组件:titleComponent.ets // 表单组件:InputComponent.ets
- 代码
// Login.ets import InputComponent from '../components/InputComponent'; import TitleComponent from '../components/TitleComponent'; import { typeNode } from '@ohos.arkui.node'; import { TESTTYPE } from '@ohos/hypium/src/main/Constant'; @Entry @Component struct Login { @State message: string = 'Login'; // 倒计时 @State countDown :number = 60 timer :number=0 @State isRegister:boolean= false // 发送验证码 sendCode(){ this.startCountDown() } // 开始倒计时 startCountDown(){ this.timer = setInterval(()=>{ this.countDown-- if(this.countDown===0){ this.countDown=60 clearInterval(this.timer) } },1000) } build() { Column(){ // title TitleComponent({title:"登录"}) // login_content Stack({alignContent:Alignment.Top}){ Image($r("app.media.Login_icon")).width(88).height(88).offset({y:-44}).zIndex(999) Column({space:10}){ // emial InputComponent({title:"电子邮箱",inputIcon:$r("app.media.mail_icon"),placeholder:"请输入邮箱信息"}) // pwd InputComponent({title:"密码",inputIcon:$r("app.media.pwd_icon"),placeholder:"请输入密码",inputType:InputType.Password}) // VCode if(this.isRegister){ Column(){ Text("验证码").width("100%").textAlign(TextAlign.Start).fontWeight(500) .fontSize(16).fontColor(Color.Black).margin({bottom:14}) Row(){ TextInput({placeholder:"请输入验证码"}) .layoutWeight(1) .backgroundColor(Color.Transparent) .border({ width:1, color:"#ff9b9b9b" }).borderRadius(10) Button(this.countDown==60?"点击获取验证码":`${this.countDown}s`).fontSize("10").margin({left:10}).width(100).padding(0).onClick((event: ClickEvent) => { if(this.countDown===60){ this.sendCode() }else{ AlertDialog.show({ message:"正在获取验证码,请等待..." }) } }) }.width("100%").height(50) } } // login_btn Button(this.isRegister?"注册":"登录").width(228).backgroundColor("#ff09b19d").margin({top:50}) .onClick(()=>{ // 登录方法 }) // re_btn Row(){ Text(this.isRegister?"去登录":"去注册").fontSize(12).onClick(()=>{ this.isRegister= !this.isRegister }) Text("|").padding({left:10,right:10}) Text("忘记密码").fontSize(12) }.width("100%").layoutWeight(1).justifyContent(FlexAlign.Center) }.width("100%").height("100%").padding({left:14,right:14}).margin({top:44}) }.width("90%").backgroundColor(Color.White).margin({top:44}).layoutWeight(1) .borderRadius(20) }.width("100%").height("100%").backgroundColor($r("app.color.page_Color")) } }
// InputComponent.ets @Component export default struct InputComponent { @Prop title:string @Prop inputIcon:Resource @Prop placeholder:string @Prop inputType:InputType=InputType.Normal @State changeStatus:boolean =false build() { Column(){ Text(this.title).width("100%").textAlign(TextAlign.Start).fontWeight(500) .fontSize(16).fontColor(Color.Black).margin({bottom:14}) Row(){ Image(this.inputIcon).width(40).aspectRatio(1) TextInput({placeholder:this.placeholder}) .onFocus(()=>{ // 聚焦 this.changeStatus=true console.log("result>>>",this.changeStatus) }) .onBlur(()=>{ // 失去 this.changeStatus=false console.log("result>>>",this.changeStatus) }) .layoutWeight(1) .backgroundColor(Color.Transparent) .type(this.inputType) }.width("100%").height(50).padding({left:10,right:10}).borderRadius(10) .border({ width:2,color:this.changeStatus?"#002884":Color.White }) } } }
// 页面标题组件 TitleComponent.ets @Component export default struct TitleComponent { @Prop title :string build() { Row(){ Image($r("app.media.Button_left")).width("44").height(41).objectFit(ImageFit.ScaleDown) Text(this.title).fontColor("#ff403f3f").fontWeight(700).fontSize(20).height(40) Text("") }.width("100%").justifyContent(FlexAlign.SpaceBetween).padding({left:20,right:20,top:12,bottom:12}) } }
2. 主页框架及底部导航栏
- 效果图(点击底部图标后,可以切换到对应页面并修改选中图标的底色。)
- 功能点及编写思路
1 看着效果图像是多个页面编写而成的,其实就只有一个页面,通过tabs组件框架,嵌套其他组件从而形成多页面效果 2 框架编写思路: 整理和页面通用的数据并提取,在主页定义一个tabs组件, 分别定义5个页面的组件,和底部导航栏的组件 3 图标切换状态思路: 因为底部导航栏的数据是封装到了一个数组中,可以给每个对象定义一个ID属性,同时在主框架中定义一个 装饰器变量来监听tabs的onchange事件,因为ongchange事件会传递tab的下标,所有可以将传递的下标赋值给装饰器变量, 再将装饰器变量传递给底部导航栏图标组件,从而判断是否选中切换图标。
- 结构:
实体类: BtnNavData 页面: MainPage 组件: CBtnNavImage DataStatistics Home My Wallet
代码:
// MainPage import CBtnNavImage from './components/CBtnNavImage' import { createBtnNavDataList,BtnNavData } from './model/BtnNavData' @Entry @Component struct MainPage { @State btnNavItemid :number=0 @State btnNavDataList:BtnNavData[] =createBtnNavDataList() // tabBar @Builder tabItemBar(item :BtnNavData){ CBtnNavImage({btnNavData:item,isSelect:this.btnNavItemid}) } build() { Tabs({barPosition:BarPosition.End}){ ForEach(this.btnNavDataList,(item:BtnNavData,index)=>{ TabContent(){ Text(this.btnNavItemid.toString()) }.tabBar( this.tabItemBar(item)) }) }.onChange((index)=>{ // 切换图标 // console.log("result>>>>",index) if(index !=2){ this.btnNavItemid =index } }) .backgroundImage($r("app.media.Subtract")) .backgroundImagePosition(Alignment.BottomEnd) .backgroundImageSize({ width:"100%", height:50 }) } }
// BtnNavData interface IBtnNavData{ selectIcon:Resource nowIcon:Resource title:string id:number } export class BtnNavData{ selectIcon:Resource nowIcon:Resource title:string id:number isQrcode:boolean constructor(obj:IBtnNavData,isQrcode=false) { this.selectIcon=obj.selectIcon this.nowIcon=obj.nowIcon this.title=obj.title this.id=obj.id this.isQrcode =isQrcode } } export const createBtnNavDataList =():BtnNavData[]=>{ return [ new BtnNavData( { id:0, title:"首页", nowIcon:$r("app.media.home_icon_unselect"), selectIcon:$r("app.media.home_icon_select"), } ), new BtnNavData( { id:1, title:"数据展示", nowIcon:$r("app.media.data_icon_unselect"), selectIcon:$r("app.media.data_icon_select"), } ), new BtnNavData( { id:2, title:"扫一扫", nowIcon:$r("app.media.qrcode_icon"), selectIcon:$r("app.media.qrcode_icon"), },true ), new BtnNavData( { id:3, title:"钱包", nowIcon:$r("app.media.wallet_icon_unselect"), selectIcon:$r("app.media.wallet_icon_select"), } ), new BtnNavData( { id:4, title:"我的", nowIcon:$r("app.media.my_icon_unselect"), selectIcon:$r("app.media.my_icon_select"), } ) ] }
// CBtnNavImage import { createBtnNavDataList,BtnNavData } from '../model/BtnNavData' @Component export default struct CBtnNavImage { @Prop btnNavData:BtnNavData @Prop isSelect :number =0 build() { Column(){ Image(this.isSelect ==this.btnNavData.id ?this.btnNavData.selectIcon:this.btnNavData.nowIcon).width(20).height(20) .offset({ y:this.btnNavData.isQrcode? -15 :0 }) }.width("100%").justifyContent(FlexAlign.Center).height("100%") } }
// 其余文件均为占位,并未编写
day01 项目初始化、登录页及主页大框架构建
3. 钱包页面
- 效果图
- 结构:
主页面:Wallet.ets 子页面:addCard.ets 组件: BankCardComponent 银行卡片 TitleComponent 顶部标题
- 编写思路:
// 钱包页面和主页页面效果类似,复制其修改部分既可。
- 代码
// 页面三:钱包 Wallet import { BankCardComponent } from '../../components/BankCardComponent' import TitleComponent from '../../components/TitleComponent' @Component export default struct Wallet { build() { Column(){ TitleComponent({title:"钱包",is_addIcon:true}) Column(){ // Text("您好,").width("100%").fontWeight(500) // Text("欢迎回来!").width("100%").fontWeight(500).fontSize(18).margin({top:5,bottom:15}) // card Swiper(){ BankCardComponent() BankCardComponent() }.loop(true) .autoPlay(true) .indicator( Indicator.dot(). color(Color.White) .selectedColor(Color.White) .selectedItemWidth(20) ).borderRadius(20) // 功能分类 Text("最近联系").width("100%").fontWeight(500).fontSize(18).margin({top:5,bottom:15}).margin({top:30,bottom:20}) Row({space:20}){ Image($r("app.media.avatar_icon")).width(50).borderRadius(8) Image($r("app.media.avatar_icon")).width(50).borderRadius(8) Image($r("app.media.avatar_icon")).width(50).borderRadius(8) Image($r("app.media.avatar_icon")).width(50).borderRadius(8) }.width("100%") // 功能分类 Text("交易信息").width("100%").fontWeight(500).fontSize(18).margin({top:5,bottom:15}).margin({top:30,bottom:20}) Column(){ List(){ ForEach((Array.from({length:10})),()=>{ ListItem(){ Row(){ Image($r("app.media.avatar_icon")).width(36).borderRadius(18).margin({left:5,right:5}) Column(){ Text("便利店").width("100%").fontSize(14).fontColor("#666") Text("2024年6月29日").width("100%").fontSize(12).fontColor("#999") }.layoutWeight(1) Text("¥1250.50").backgroundColor("#ffffe0e0").borderRadius(20).width(100).height(35) .textAlign(TextAlign.Center).fontSize(12).fontColor("#f00") }.width("100%").height(50).backgroundColor("#fffafafa").borderRadius(10).margin({bottom:10}) } }) } }.width("100%").layoutWeight(1) }.width("100%").layoutWeight(1).padding({left:20,right:20}) }.width("100%").height("100%").backgroundColor("#ffffffff") } }
// 添加银行卡 子页面:AddCard import InputComponent from '../../components/InputComponent'; import TitleComponent from '../../components/TitleComponent'; @Extend(Text) function titleTextStyle(){ .width("100%").fontWeight(500).fontSize(18).margin({top:30,bottom:20}) } @Entry @Component struct AddCard { @State message: string = 'Hello World'; build() { Column(){ // titile TitleComponent({title:"添加新的银行卡",routerUrl:'',is_icon:true}) // content Column({space:30}){ Text("卡片信息").titleTextStyle() InputComponent({title:'银行卡号',placeholder:'XXXXXXXX XXX XXXXXX',isInputIcon:false}) InputComponent({title:'持卡人姓名',placeholder:'请输入持卡人姓名',isInputIcon:false}) Row({space:10}){ InputComponent({title:'CCV',placeholder:'2533',isInputIcon:false}).layoutWeight(1) InputComponent({title:'到期时间',placeholder:'30-06-2024',isInputIcon:false}).layoutWeight(1) } Button("下一步").width(228).backgroundColor("#ff09b19d").margin({top:50}) }.width("100%").height("100%").padding({left:20,right:20}) }.width("100%").height("100%").backgroundImage($r("app.media.pageBg")) } }
// 银行卡片组件:BankCardComponent @Component export struct BankCardComponent { build() { Column(){ Row(){ Text("中国银行").layoutWeight(1).fontColor(Color.White).fontSize(14).fontWeight(500) Image($r("app.media.card_icon")).width(36) } Text(){ Span("¥").fontSize(12) Span("25,230,00").fontSize(24).fontWeight(700) }.width("100%").fontColor(Color.White).margin({top:20}) Row(){ Text("xxxxxxxxxx xx xxxxx ").layoutWeight(1).fontColor(Color.White).fontSize(14).fontWeight(500) Text("26/24").fontColor(Color.White).fontSize(12).padding({right:40}) }.margin({top:15}) }.width("100%").height(150).backgroundColor("#ff09d7d3").padding(20) } }
// 页面标题组件: TitleComponent import text from '@ohos.graphics.text' import router from '@ohos.router' @Component export default struct TitleComponent { @Prop title :string @Prop is_icon:boolean @Prop is_addIcon:boolean @Prop routerUrl:string @Prop titleColor:string build() { Row(){ if(this.is_icon){ Image($r("app.media.Button_left")).width("44").height(30).objectFit(ImageFit.ScaleDown).borderRadius(5) .onClick(()=>{ router.back() }) } Text(this.title).fontColor(this.titleColor).fontWeight(700).fontSize(20).height(40).layoutWeight(1).textAlign(TextAlign.Center) if(this.is_addIcon){ Text("+").fontColor(Color.White).fontSize(25).fontWeight(500).border({width:2}) .borderRadius(30).width(25).height(25).fontColor(Color.Black).lineHeight(25).textAlign(TextAlign.Center).onClick(()=>{ router.pushUrl({ url:'pages/bank/AddCard' }) }) } }.width("100%").justifyContent(FlexAlign.SpaceBetween).padding({left:20,right:20,top:12,bottom:12}) } }
4. 个人页面
- 效果图
- 结构
组件: BankCardComponent 银行卡片 TitleComponent 顶部标题 InputDateComponent 选择日期弹框 InputComponent 普通表单输入框 页面: My 个人主页 InfoEdit 个人信息修改页 QrCodePage 个人信息二维码生成页 工具类:tools
- 代码
// 页面四:个人信息页 import TitleComponent from '../../components/TitleComponent' import router from '@ohos.router' import { Router } from '@kit.ArkUI' @Component export default struct My { build() { Column(){ TitleComponent({title:"个人资料",titleColor:"#ffff"}) Stack({alignContent:Alignment.Start}){ Column().width("100%").height(120) .backgroundColor("#ffc3f6e1") .margin({top:50}).borderRadius(20).shadow({radius:10,color:"#fff"}) Column(){ Image($r("app.media.user")).width(66).height(66).borderRadius(22) .border({ width:5, color:'#ff09b06d', style:BorderStyle.Solid }).shadow({radius:10,color:"#fff"}) Text("追风的少年").offset({x:80,y:-30}).width("100%") Text("财富的意义,在于分享与贡献,而非单纯的积累。").fontSize(14).fontColor("#ff969191").margin({top:10}) .offset({y:-10}).margin({right:10}) }.width("100%").alignItems(HorizontalAlign.Start).margin({left:10}) Image($r("app.media.right_i")).height(20).offset({ y:60,x:270 }) }.width("100%").padding({left:30,right:30}) Row(){ Image($r("app.media.edit_icon")).height(30).margin({right:20}) Text("编辑个人信息").layoutWeight(1).fontSize(14) Image($r("app.media.right_icon")).height(25) }.height(40).padding({left:5,right:10}).backgroundColor("#fff").margin(20) .borderRadius(10).shadow({radius:20,color:"#ff70e7d5"}).onClick(()=>{ router.pushUrl({ url:"pages/info/InfoEdit" }) }) Row(){ Image($r("app.media.qrcode_icon_external")).height(25).margin({left:5,right:30}) Text("个人二维码").layoutWeight(1).fontSize(14) Image($r("app.media.right_icon")).height(25) }.height(40).padding({left:5,right:10}).backgroundColor("#fff").margin(20) .borderRadius(10).shadow({radius:20,color:"#ff70e7d5"}).onClick(()=>{ router.pushUrl({ url :'pages/info/QrCodePage' }) }) }.width("100%").height("100%").backgroundImage($r("app.media.myPageBg")) .backgroundImageSize({width:"100%",height:"100%"}) } }
// 个人信息修改页 import InputComponent from '../../components/InputComponent'; import InputDateComponent from '../../components/InputDateComponent'; import TitleComponent from '../../components/TitleComponent'; @Extend(Text) function titleTextStyle(){ .width("100%").fontWeight(500).fontSize(18).margin({top:30,bottom:20}) } @Entry @Component struct InfoEdit { @State message: string = 'Hello World'; selectedDate: Date = new Date("2010-1-1") build() { Column(){ // titile TitleComponent({title:"编辑个人信息",routerUrl:'',is_icon:true}) // content Column({space:30}){ Text("个人信息").titleTextStyle() InputComponent({title:'姓名',placeholder:'请输入您的姓名',isInputIcon:false}) InputComponent({title:'联系电话',placeholder:'请输入你的手机号码',isInputIcon:false}) Row({space:10}){ InputComponent({title:'性别',placeholder:'2533',isInputIcon:false}).layoutWeight(1) InputDateComponent ({title:'出生日期',placeholder:'30-06-2024',isInputIcon:false}).layoutWeight(1) } Button("下一步").width(228).backgroundColor("#ff09b19d").margin({top:50}) }.width("100%").height("100%").padding({left:20,right:20}) }.width("100%").height("100%").backgroundImage($r("app.media.pageBg")) } }
// 个人信息二维码生成页 import TitleComponent from '../../components/TitleComponent'; import { randomColor } from '../../util/tools'; @Entry @Component struct QrCodePage { @State message: string = 'Hello World'; @State BgColor :string = "#ffc2f17d" build() { Column() { // titile TitleComponent({title:"",routerUrl:'',is_icon:true}) QRCode("1").margin({top:40}).height(200).aspectRatio(1).backgroundColor(Color.Transparent) Blank() Row({space:20}){ Text("换个样式").onClick(()=>{ this.BgColor = randomColor() }) Text("|") Text("保存图片") }.width("100%").justifyContent(FlexAlign.Center).margin({bottom:20}) } .height('100%').backgroundColor(this.BgColor) .width('100%') } }
// 日期选择框 @Component export default struct InputDateComponent { @Prop title:string @Prop inputIcon:Resource @Prop placeholder:string @Prop inputType:InputType=InputType.Normal @State changeStatus:boolean =false @Prop isInputIcon:boolean = true selectedDate: Date = new Date() build() { Column(){ Text(this.title).width("100%").textAlign(TextAlign.Start).fontWeight(500) .fontSize(16).fontColor(Color.Black).margin({bottom:14}) Row(){ if (this.isInputIcon) { Image(this.inputIcon).width(40).aspectRatio(1) } TextInput({placeholder:this.placeholder}) .onClick(()=>{ DatePickerDialog.show({ start: new Date("1970-1-1"), end: new Date("2100-12-31"), selected: this.selectedDate, showTime:true, useMilitaryTime:false, // disappearTextStyle: {color: Color.Pink, font: {size: '22fp', weight: FontWeight.Bold}}, // textStyle: {color: '#ff00ff00', font: {size: '18fp', weight: FontWeight.Normal}}, // selectedTextStyle: {color: '#ff182431', font: {size: '14fp', weight: FontWeight.Regular}}, onDateAccept: (value: Date) => { // 通过Date的setFullYear方法设置按下确定按钮时的日期,这样当弹窗再次弹出时显示选中的是上一次确定的日期 this.selectedDate = value console.info("DatePickerDialog:onDateAccept()" + value.toString()) }, onCancel: () => { console.info("DatePickerDialog:onCancel()") }, onDateChange: (value: Date) => { console.info("DatePickerDialog:onDateChange()" + value.toString()) } }) }) .onFocus(()=>{ // 聚焦 this.changeStatus=true console.log("result>>>",this.changeStatus) }) .onBlur(()=>{ // 失去 this.changeStatus=false console.log("result>>>",this.changeStatus) }) .layoutWeight(1) .backgroundColor(Color.Transparent) .type(this.inputType) }.width("100%").height(50).padding({left:10,right:10}).borderRadius(10) .border({ width:2,color:this.changeStatus?"#002884":Color.White }) } } }
// 普通输入框 @Component export default struct InputComponent { @Prop title:string @Prop inputIcon:Resource @Prop placeholder:string @Prop inputType:InputType=InputType.Normal @State changeStatus:boolean =false @Prop isInputIcon:boolean = true build() { Column(){ Text(this.title).width("100%").textAlign(TextAlign.Start).fontWeight(500) .fontSize(16).fontColor(Color.Black).margin({bottom:14}) Row(){ if (this.isInputIcon) { Image(this.inputIcon).width(40).aspectRatio(1) } TextInput({placeholder:this.placeholder}) .onFocus(()=>{ // 聚焦 this.changeStatus=true console.log("result>>>",this.changeStatus) }) .onBlur(()=>{ // 失去 this.changeStatus=false console.log("result>>>",this.changeStatus) }) .layoutWeight(1) .backgroundColor(Color.Transparent) .type(this.inputType) }.width("100%").height(50).padding({left:10,right:10}).borderRadius(10) .border({ width:2,color:this.changeStatus?"#002884":"#ffcbcccd" }) } } }
// 随机颜色生成方法 // 十六进制的随机颜色 export function randomColor():string{ let color:string = "#" let colors:string[] = [ "a","b", "c","d", "e","f", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" ] for (let i = 0; i <8 ; i++) { color+=colors[Math.floor(Math.random()*15)] } return color }
5. 支付页面
- 效果图
- 结构
页面:PayPage 自定义弹框组件:PayCustomDialogExample
- 代码
// 付款页 import TitleComponent from '../../components/TitleComponent'; import PayCustomDialogExample from './PayCustomDialogExample'; @Entry @Component struct PayPage { dialogController: CustomDialogController = new CustomDialogController({ builder: PayCustomDialogExample(), alignment:DialogAlignment.Bottom, customStyle:true }) onPageShow(): void { this.dialogController.open() } @State message: string = 'Hello World'; build() { Column() { TitleComponent({title:"支付",is_icon:true}) } .height('100%') .width('100%').backgroundColor("#ff5f5d5d") } }
// 付款弹框组件 import InputComponent from '../../components/InputComponent' @CustomDialog export default struct PayCustomDialogExample { controller: CustomDialogController = new CustomDialogController({ builder: PayCustomDialogExample({}), }) build() { Column() { Text("付款给").border({width:{bottom:1},color:'#ffe2e2e2'}).width("100%").lineHeight(20) .textAlign(TextAlign.Center).padding({top:10,bottom:10}) .fontWeight(500).fontColor("#ff044a6e") Stack({alignContent:Alignment.Top}){ Column().width("100%").height(80).shadow({radius:60,color:"#ffcfcfcf"}).borderRadius(20).margin({top:50}) Column({space:5}){ Image($r("app.media.HOS")).height(50).borderRadius(10).aspectRatio(2).margin({top:20}) Text("HarmonyOS APP应用开发").fontSize(14).fontWeight(700) Text("2024-06-30").fontSize(12).fontColor("#666") } }.width("100%").padding({right:50,left:50,bottom:20}) Text("支付账户").fontWeight(700).fontSize(18).height(40) .width("100%").padding({left:20}) Row(){ Column().width(50).backgroundColor("#0ff").height(30).margin(5).borderRadius(5) Column(){ Text("中国银行储蓄卡").fontColor("#ff033048").fontSize(14).width("100%") Text("xxxxxx xxxxx xxxx ").fontColor("#999").fontSize(12).width("100%") }.layoutWeight(1) Image($r("app.media.right_icon")).width(20) }.height(40).margin({left:20,right:20}).shadow({radius:60,color:"#ffcfcfcf"}).borderRadius(10) Text("支付金额").fontWeight(700).fontSize(18).height(40) .width("100%").padding({left:20}).margin({top:10,bottom:10}) Text("¥155.55").fontWeight(700).fontSize(24).height(40) Column({space:10}){ InputComponent({title:'用户订单姓名',placeholder:'输入你的名称'}) InputComponent({title:'用户订单电话号码',placeholder:'输入您的电话号码'}) }.width("100%").padding({left:20,right:20}) Button("下一步").width(228).backgroundColor("#ff09b19d").margin({top:50}) }.height("100%").width("100%").margin({top:80}).borderRadius({topLeft:20,topRight:20}).backgroundColor(Color.White) } }
day02 项目结构基本搭建完成,静态页面基本编写完成