简言:
gitee地址:https://gitee.com/whltaoin_admin/money-controller-app.git
端云一体化开发在线文档:
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/agc-harmonyos-clouddev-view-0000001700053733-V5
注:此App参照此教程进行二次修改:https://www.bilibili.com/video/BV1q5411v7o7
项目构建静态页面
钱包页面
- 效果图
- 结构:
主页面: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})// cardSwiper(){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(){// titileTitleComponent({title:"添加新的银行卡",routerUrl:'',is_icon:true})// contentColumn({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:stringbuild() {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})}
}
个人页面
- 效果图
- 结构
组件:
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(){// titileTitleComponent({title:"编辑个人信息",routerUrl:'',is_icon:true})// contentColumn({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() {// titileTitleComponent({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 = trueselectedDate: 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 = valueconsole.info("DatePickerDialog:onDateAccept()" + value.toString())},onCancel: () => {console.info("DatePickerDialog:onCancel()")},onDateChange: (value: Date) => {console.info("DatePickerDialog:onDateChange()" + value.toString())}})}).onFocus(()=>{// 聚焦this.changeStatus=trueconsole.log("result>>>",this.changeStatus)}).onBlur(()=>{// 失去this.changeStatus=falseconsole.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 = truebuild() {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=trueconsole.log("result>>>",this.changeStatus)}).onBlur(()=>{// 失去this.changeStatus=falseconsole.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
}
支付页面
- 效果图
- 结构
页面: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 项目结构基本搭建完成,静态页面基本编写完成