HarmonyOS APP应用开发项目- MCA助手(Day02持续更新中~)

news/2024/7/7 20:16:06 标签: harmonyos, 移动应用开发, ArkTS

简言:

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


项目构建静态页面

钱包页面

  • 效果图

image.png
image.png

  • 结构:
  • image.png
主页面: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})
  }
}

个人页面

  • 效果图

image.png
image.png
image.png

  • 结构
组件:
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
}

支付页面

  • 效果图

image.png

  • 结构
页面: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 项目结构基本搭建完成,静态页面基本编写完成



http://www.niftyadmin.cn/n/5535054.html

相关文章

系统安全体系架构规划框架

安全技术体系架构是对组织机构信息技术系统的安全体系结构的整体描述。安全技术体系架构框架是拥有信息技术系统的组织机构根据其策略的要求和风险评估的结果&#xff0c;参考相关技术体系构架的标准和最佳实践&#xff0c;结合组织机构信息技术系统的具体现状和需求&#xff0…

java通过jts获取点在线段中的位置

在Java中&#xff0c;可以使用JTS&#xff08;Java Topology Suite&#xff09;库来获取点在线段的垂足点位置。以下是一个简单的示例代码&#xff0c;展示了如何使用JTS获取点到线段的垂足点位置&#xff1a; 首先&#xff0c;确保你的项目中包含了JTS库。 import org.locati…

Python学习之小游戏--坦克大作战

今天跟视频学习了Python实现坦克大作战小游戏&#xff0c;挺有意思的&#xff0c;一起来玩吧~ 按空格发射子弹&#xff0c;上下左右键实现移动&#xff0c;ESC键无限复活。 import pygame,time,random from pygame.sprite import Sprite SCREEN_WIDTH800 SCREEN_HEIGHT500 BG…

C++(第四天----拷贝函数、类的组合、类的继承)

一、拷贝构造函数&#xff08;复制构造函数&#xff09; 1、概念 拷贝构造函数&#xff0c;它只有一个参数&#xff0c;参数类型是本类的引用。如果类的设计者不写拷贝构造函数&#xff0c;编译器就会自动生成拷贝构造函数。大多数情况下&#xff0c;其作用是实现从源对象到目…

JavaScript懒加载图像

懒加载图像是一种优化网页性能的技术&#xff0c;它将页面中的图像延迟加载&#xff0c;即在用户需要查看它们之前不会立即加载。这种技术通常用于处理大量或大尺寸图像的网页&#xff0c;特别是那些包含长页面或大量媒体内容的网站。 好处 **1. 加快页面加载速度&#xff1a…

FFmpeg 命令行 音视频格式转换

&#x1f4da;&#xff1a;FFmpeg 提供了丰富的命令行选项和功能&#xff0c;可以用来处理音视频文件、流媒体等&#xff0c;掌握命令行的使用&#xff0c;可以有效提高工作效率。 目录 一、视频转换和格式转换 &#x1f535; 将视频文件转换为另一种格式 &#x1f535; 指定…

Lombok的hashCode方法

Lombok对于重写hashCode的算法真的是很经典&#xff0c;但是目前而言有一个令人难以注意到的细节。在继承关系中&#xff0c;父类的hashCode针对父类的所有属性进行运算&#xff0c;而子类的hashCode却只是针对子类才有的属性进行运算&#xff0c;立此贴提醒自己。 目前重写ha…

某安全公司DDoS攻击防御2024年6月报告

引言&#xff1a; 在2024年6月&#xff0c;网络空间的安全挑战汹涌澎湃。分布式拒绝服务&#xff08;DDoS&#xff09;攻击频发&#xff0c;针对云服务、金融科技及在线教育平台的精密打击凸显出当前网络威胁环境的严峻性。 某安全公司作为网络安全防护的中坚力量&#xff0c…