纯血鸿蒙HarmonyOS NEXT 5.0聊天app应用|鸿蒙os仿造微信

纯血鸿蒙HarmonyOS NEXT 5.0聊天app应用|鸿蒙os高仿微信

最近一直捣鼓 纯血鸿蒙os框架,花了一个月高速开发了一款基于 HarmonyOS Next5.0 api12克隆微信app界面聊天室项目模板Harmony-Chatroom。

HarmonyOS-WeChat是一个基于纯血鸿蒙OS Next5.0 API12实战开发的聊天应用程序,模仿了微信的界面和功能,提供了聊天、通讯录、我、朋友圈等模块。这个项目使用了ArkUI和ArkTS技术栈,实现了类似微信的消息UI布局、输入框光标处插入文字、emoji表情图片/GIF动图、图片预览、红包、语音/位置UI、长按语音面板等功能。

动图封面

动图封面

使用版本

DevEco Studio 5.0.3.906

HarmonyOS 5.0.0 API12 Release SDK

commandline-tools-windows-x64-5.0.3.906

目前harmony-chat聊天app项目已经同步到我的原创作品集。
HarmonyOS-Next5.0-API12仿微信app聊天程序

项目结构目录

HarmonyOS-Chat项目的框架结构是基于 DevEco Studio 5.0.3.906编码工具构建。项目中所有的顶部标题导航栏都是自定义封装的ArkUI组件实现的。

https://developer.huawei.com/consumer/cn/deveco-studio/

动图封面

动图封面

开发和学习资源

对于想要快速入门到进阶开发HarmonyOS应用的开发者,建议先阅读官方文档,然后再找一个实战项目案例进行练习。华为鸿蒙os开发官网提供了HarmonyOS开发设计规范和ArkUI方舟UI框架的相关资料,这些都是宝贵的开发资源。

  • 鸿蒙os官网

https://developer.huawei.com/consumer/cn/

  • ArkUI方舟UI框架

https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/arkui-declarative-comp-V5

harmonyos登录/注册模板|60s倒计时验证码

动图封面

/**

 * 登录模板

 * @author andy

 */

 

import { router, promptAction } from '@kit.ArkUI'

 

@Entry

@Component

struct Login {

  @State name: string = ''

  @State pwd: string = ''

 

  // 提交

  handleSubmit() {

    if(this.name === '' || this.pwd === '') {

      promptAction.showToast({ message: '账号或密码不能为空' })

    }else {

      // 登录接口逻辑...

     

      promptAction.showToast({ message: '登录成功' })

      setTimeout(() => {

        router.replaceUrl({ url: 'pages/Index' })

      }, 2000)

    }

  }

 

  build() {

    Column() {

      Column({space: 10}) {

        Image('pages/assets/images/logo.png').height(50).width(50)

        Text('HarmonyOS-Chat').fontSize(18).fontColor('#0a59f7')

      }

      .margin({top: 50})

      Column({space: 15}) {

        TextInput({placeholder: '请输入账号'})

          .onChange((value) => {

            this.name = value

          })

        TextInput({placeholder: '请输入密码'}).type(InputType.Password)

          .onChange((value) => {

            this.pwd = value

          })

        Button('登录').height(45).width('100%')

          .linearGradient({ angle: 135, colors: [['#0a59f7', 0.1], ['#07c160', 1]] })

          .onClick(() => {

            this.handleSubmit()

          })

      }

      .margin({top: 30})

      .width('80%')

      Row({space: 15}) {

        Text('忘记密码').fontSize(14).opacity(0.5)

        Text('注册账号').fontSize(14).opacity(0.5)

          .onClick(() => {

            router.pushUrl({url: 'pages/views/auth/Register'})

          })

      }

      .margin({top: 20})

    }

    .height('100%')

    .width('100%')

    .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])

  }

}

Stack({alignContent: Alignment.End}) {

  TextInput({placeholder: '验证码'})

    .onChange((value) => {

      this.code = value

    })

  Button(`${this.codeText}`).enabled(!this.disabled).controlSize(ControlSize.SMALL).margin({right: 5})

    .onClick(() => {

      this.handleVCode()

    })

}

 

// 验证码参数

@State codeText: string = '获取验证码'

@State disabled: boolean = false

@State time: number = 60

 

// 获取验证码

handleVCode() {

  if(this.tel === '') {

    promptAction.showToast({ message: '请输入手机号' })

  }else if(!checkMobile(this.tel)) {

    promptAction.showToast({ message: '手机号格式错误' })

  }else {

    const timer = setInterval(() => {

      if(this.time > 0) {

        this.disabled = true

        this.codeText = `获取验证码(${this.time--})`

      }else {

        clearInterval(timer)

        this.codeText = '获取验证码'

        this.time = 5

        this.disabled = false

      }

    }, 1000)

  }

}

harmonyos arkui自定义导航条

项目中顶部导航条使用ArkUI范式开发的增强版导航条组件。

HarmonyOS NEXT 5.0自定义增强版导航栏组件|鸿蒙ArkUI自定义标题栏

基于HarmonyOS自定义弹窗组件

// 标题(支持字符串|自定义组件)

@BuilderParam title: ResourceStr | CustomBuilder = BuilderFunction

// 内容(字符串或无状态组件内容)

@BuilderParam message: ResourceStr | CustomBuilder = BuilderFunction

// 响应式组件内容(自定义@Builder组件是@State动态内容)

@BuilderParam content: () => void = BuilderFunction

// 弹窗类型(android | ios | actionSheet)

@Prop type: string

// 是否显示关闭图标

@Prop closable: boolean

// 关闭图标颜色

@Prop closeColor: ResourceColor

// 是否自定义内容

@Prop custom: boolean

// 自定义操作按钮

@BuilderParam buttons: Array | CustomBuilder = BuilderFunction

通过如下方式调用。

// 自定义退出弹窗

logoutController: CustomDialogController = new CustomDialogController({

  builder: HMPopup({

    type: 'android',

    title: '提示',

    message: '确定要退出当前登录吗?',

    buttons: [

      {

        text: '取消',

        color: '#999'

      },

      {

        text: '退出',

        color: '#fa2a2d',

        action: () => {

          router.replaceUrl({url: 'pages/views/auth/Login'})

        }

      }

    ]

  }),

  maskColor: '#99000000',

  cornerRadius: 12,

  width: '75%'

})

聊天功能模块

// 聊天模板 Q:282310962

 

Stack() {

  /**

   * 聊天主体(消息区/底部操作区)

   */

  Column() {

    /* 导航条 */

    HMNavBar({

      title: 'HarmonyOS Next 5.0',

      bgLinearGradient: { angle: 135, colors: [['#cc07c160', 0.2], ['#cc0a59f7', 1]] },

      fontColor: '#fff',

      actions: [

        {

          icon: $r('sys.symbol.more'),

          action: () => router.pushUrl({url: 'pages/views/chat/GroupInfo'})

        }

      ]

    })

 

    /* 渲染聊天消息 */

    Scroll(this.scroller) {

      Column({space: 15}) {

        ForEach(this.chatList, (item: ChatArray) => {

          // ...

        }, (item: ChatArray) => item.id)

      }

      // 倒叙显示

      .reverse(true)

      // .padding(15)

      .constraintSize({minHeight: '100%'})

      .width('100%')

    }

    // 聊天区翻转

    .rotate({angle: 180})

    .direction(Direction.Rtl)

    .padding(15)

    .width('100%')

    .layoutWeight(1)

    .scrollBar(BarState.On)

    .edgeEffect(EdgeEffect.Spring)

    .onScrollEdge((side: Edge) => {

      if(side === 0) {

        console.info('To the bottom edge')

      }else if(side === 2) {

        console.info('To the top edge')

      }

    })

    .onTouch(() => {

      this.handleChatAreaTouched()

    })

 

    /* 底部操作栏 */

    Row() {

      // ....

    }

    .width('100%')

    .backgroundColor('#f8f8f8')

  }

  .height('100%')

  .width('100%')

  .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])

 

  /**

   * 录音主体(按住说话)

   */

  Column() {

    Stack({alignContent: Alignment.Bottom}) {

      // ...

    }

    .height('100%')

    .width('100%')

  }

  .visibility(this.voicePanelEnable ? Visibility.Visible : Visibility.None)

  .height('100%')

  .width('100%')

  .backgroundColor('#99000000')

  .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])

}

.height('100%')

.width('100%')

.backgroundColor($r('sys.color.background_secondary'))

.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])

底部操作栏区域。

/* 底部操作栏 */

Row() {

  Column() {

    // 输入框模块

    Row({space: 10}) {

      Row() {

        SymbolGlyph($r('sys.symbol.mic_circle')).fontSize(24)

          .visibility(this.voiceEnable ? Visibility.None : Visibility.Visible)

        SymbolGlyph($r('sys.symbol.keyboard_circle')).fontSize(24)

          .visibility(!this.voiceEnable ? Visibility.None : Visibility.Visible)

      }

      .onClick(() => {

        this.voiceEnable = !this.voiceEnable

        this.footBarEnable = false

      })

      Row() {

        // 编辑器

        RichEditor({controller: this.richEditorController}).backgroundColor('#fff').borderRadius(4).caretColor('#0a59f7')

          .visibility(this.voiceEnable ? Visibility.None : Visibility.Visible)

        // 按住说话

        // 通过item[key]取到值的时候会报错,Indexed access is not supported for fields

        // 解决办法Object(item)[key]

        Text(`${Object(this.voiceTypeMap)[this.voiceType]}`).backgroundColor('#fff').borderRadius(4).fontSize(15).height(34).width('100%').textAlign(TextAlign.Center)

          .visibility(!this.voiceEnable ? Visibility.None : Visibility.Visible)

          .onTouch((event: TouchEvent) => {

            if(event) {

              if(event.type === TouchType.Down) {

                this.voiceType = 1

                this.voicePanelEnable = true

              }

              if(event.type === TouchType.Move) {

                ...

 

                // 触摸判断

                if(pos.y >= panY) {

                  this.voiceType = 1 // 松开发送

                }else if(pos.y < panY && pos.x < panX) {

                  this.voiceType = 2 // 左滑取消发送

                }else if(pos.y < panY && pos.x >= panX) {

                  this.voiceType = 3 // 右滑语音转文字

                }

              }

              if(event.type === TouchType.Up || event.type === TouchType.Cancel) {

                switch (this.voiceType) {

                  ...

                }

                this.voiceType = 0

              }

            }

          })

      }

      .layoutWeight(1)

      SymbolGlyph($r('sys.symbol.capture_smiles')).fontSize(24)

        .onClick(() => {

          this.handleEmoChooseState(0)

        })

      SymbolGlyph($r('sys.symbol.plus')).fontSize(24)

        .onClick(() => {

          this.handleEmoChooseState(1)

        })

      SymbolGlyph($r('sys.symbol.paperplane')).fontSize(24).fontColor(['#0a59f7'])

        .onClick(() => {

          this.handleSubmit()

        })

    }

    .padding(10)

    .alignItems(VerticalAlign.Center)

 

    // 表情/选择模块

    Column() {

      if(this.footBarIndex == 0) {

        // 表情区域

        this.renderEmoWidget()

      }else {

        // 选择区域

        this.renderChooseWidget()

      }

    }

    .height(308)

    .width('100%')

    .visibility(this.footBarEnable ? Visibility.Visible : Visibility.None)

  }

}

.width('100%')

.backgroundColor('#f8f8f8')

uniapp-vue3-oadmin手机后台实例|vite5.x+uniapp多端仿ios管理系统

tauri2.0-admin桌面端后台系统|Tauri2+Vite5+ElementPlus管理后台EXE程序

Tauri2.0+Vite5聊天室|vue3+tauri2+element-plus仿微信|tauri聊天应用

Electron32-ViteOS桌面版os系统|vue3+electron+arco客户端OS管理模板

Vite5+Electron聊天室|electron31跨平台仿微信EXE客户端|vue3聊天程序

HarmonyOS-Chat是一个展示如何在纯血鸿蒙OS Next5.0 API12上使用ArkUI和ArkTS开发聊天应用的实例。它提供了丰富的聊天功能,对于开发者来说,这是一个很好的学习和参考资源。


请使用浏览器的分享功能分享到微信等