HarmonyOS NEXT开发实战教程:聊天交友App
一早醒来Mate70上热搜了,余承东发文宣布Mate70要在本月发布,史上最强手机终于要来了。
今天分享一个交友app实战教程,是幽蓝君用整整一个周末开发的,时间有限,只做了些皮毛,不是很完善,不过拿来练手应该是足够了。
先上效果图:

下面为大家分享一下本项目的开发过程:
首页
首先当中首先要注意的是渐变色的背景,这个背景在项目的每一个页面中都有出现,这个背景我使用图片来实现,让图片充满整个页面,页面内容部分与背景图片层叠布局。相关代码如下:
Stack({alignContent:Alignment.Top}){
Image($r('app.media.backImg'))
.width('100%')
.height('100%')
.objectFit(ImageFit.Fill)
Navigation(){
//内容部分
}
}
然后进入首页的内容部分,首先是导航栏,很明显需要自定义,不过比较简单,一个横向布局搞定:
@Builder NavMenu(){
Row(){
Row({space:3}){
Image($r('app.media.location'))
.width(16)
.height(16)
.objectFit(ImageFit.Auto)
Text('西安市')
.fontSize(13)
.fontColor('#333333')
}
.width(68)
.height(26)
.backgroundColor(Color.White)
.borderRadius(13)
Row({space:12}){
ForEach(this.timeList,(str:string,index)=>{
Column(){
Text(str)
.fontSize(this.timeIndex == index?20:18)
.fontColor(this.timeIndex == index?BasicContant.TEXT_BLACK_COLOR:'rgb(129,129,129)')
.height(21)
if(this.timeIndex == index){
Image($r('app.media.s_time'))
.width(17)
.height(10)
.objectFit(ImageFit.Auto)
}
}
.height(35)
.justifyContent(FlexAlign.Start)
})
}
Row(){
Image($r('app.media.more'))
.width(16)
.height(16)
.objectFit(ImageFit.Auto)
}
.width(68)
.height(16)
.justifyContent(FlexAlign.End)
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
.alignItems(VerticalAlign.Center)
.height(44)
.padding({left:12,right:12})
}
接下来是人物列表,是一个瀑布流布局,瀑布流看起来很难,但是鸿蒙里直接提供了瀑布流组件WaterFlow,文档也比较详细,甚至直接复制过来就可以使用,需要注意的是我们首先要知道自己的数据列表里图片的尺寸。相关代码如下:
export class WaterFlowDataSource implements IDataSource {
private dataArray: Object[] = []
private listeners: DataChangeListener[] = []
cardList:CardItem[] = [
{cover:$r('app.media.girl_1'),name:'橙子',distance:'3.4km',width:358,height:495},
{cover:$r('app.media.header1'),name:'橙子',distance:'3.4km',width:854,height:1280},
{cover:$r('app.media.header2'),name:'橙子',distance:'3.4km',width:1280,height:853},
{cover:$r('app.media.header3'),name:'橙子',distance:'3.4km',width:1050,height:1280},
{cover:$r('app.media.header4'),name:'橙子',distance:'3.4km',width:853,height:1280},
{cover:$r('app.media.header5'),name:'橙子',distance:'3.4km',width:692,height:1280},
{cover:$r('app.media.header6'),name:'橙子',distance:'3.4km',width:853,height:1280},
]
constructor() {
this.dataArray = this.cardList
}
// 获取索引对应的数据
public getData(index: number): Object {
return this.dataArray[index]
}
// 通知控制器数据重新加载
notifyDataReload(): void {
this.listeners.forEach(listener => {
listener.onDataReloaded()
})
}
// 通知控制器数据增加
notifyDataAdd(index: number): void {
this.listeners.forEach(listener => {
listener.onDataAdded(index)
})
}
// 通知控制器数据变化
notifyDataChange(index: number): void {
this.listeners.forEach(listener => {
listener.onDataChanged(index)
})
}
// 通知控制器数据删除
notifyDataDelete(index: number): void {
this.listeners.forEach(listener => {
listener.onDataDeleted(index)
})
}
// 通知控制器数据位置变化
notifyDataMove(from: number, to: number): void {
this.listeners.forEach(listener => {
listener.onDataMoved(from, to)
})
}
// 获取数据总数
public totalCount(): number {
return this.dataArray.length
}
// 注册改变数据的控制器
registerDataChangeListener(listener: DataChangeListener): void {
if (this.listeners.indexOf(listener) < 0) {
this.listeners.push(listener)
}
}
// 注销改变数据的控制器
unregisterDataChangeListener(listener: DataChangeListener): void {
const pos = this.listeners.indexOf(listener)
if (pos >= 0) {
this.listeners.splice(pos, 1)
}
}
// 增加数据
public Add1stItem(): void {
this.dataArray.splice(0, 0, this.dataArray.length)
this.notifyDataAdd(0)
}
// 在数据尾部增加一个元素
public AddLastItem(): void {
this.dataArray.splice(this.dataArray.length, 0, this.dataArray.length)
this.notifyDataAdd(this.dataArray.length-1)
}
// 在指定索引位置增加一个元素
public AddItem(index: number): void {
this.dataArray.splice(index, 0, this.dataArray.length)
this.notifyDataAdd(index)
}
// 删除第一个元素
public Delete1stItem(): void {
this.dataArray.splice(0, 1)
this.notifyDataDelete(0)
}
// 删除第二个元素
public Delete2ndItem(): void {
this.dataArray.splice(1, 1)
this.notifyDataDelete(1)
}
// 删除最后一个元素
public DeleteLastItem(): void {
this.dataArray.splice(-1, 1)
this.notifyDataDelete(this.dataArray.length)
}
// 重新加载数据
public Reload(): void {
this.dataArray.splice(1, 1)
this.dataArray.splice(3, 2)
this.notifyDataReload()
}
}
WaterFlow() {
LazyForEach(this.dataSource, (item: CardItem,index:number) => {
FlowItem() {
Card({cardItem:item})
.width(this.item_width)
.height(this.item_width * item.height/item.width)
}
}, (item: string) => item)
}
.columnsTemplate("1fr 1fr")
.columnsGap(5)
.rowsGap(5)
.width('100%')
.height('100%')
聊天页面
聊天页面其实也比较简单,写页面无非那几种布局方式,这里幽蓝君想讲一下消息气泡,自己的发的消息和别人发的消息我们可以使用FlexAlign.End和FlexAlign.Start两种对齐方式来实现气泡的靠左和靠右显示,然后这个气泡还有一个最大宽度,可以使用constraintSize来实现,以自己发的消息为例贴一段具体代码:
@Component struct MsgFromMe{
build() {
Row(){
Text('这周六有空吗?一起去广场滑滑板可以吗?')
.fontColor(Color.White)
.fontSize(16)
.lineHeight(22)
.padding({left:24,right:24,top:16,bottom:16})
.backgroundColor('rgba(154, 107, 249, 1)')
.borderRadius({bottomLeft:24,topRight:24})
.constraintSize({maxWidth:BasicContant.SCREEN_WIDTH*0.6})
}
.width('100%')
.justifyContent(FlexAlign.End)
.padding({top:12})
}
}
以上就是本次交友App的简单讲解
HarmonyOS NEXT开发实战教程:聊天交友App的更多相关文章
- Swift游戏开发实战教程(霸内部信息大学)
Swift游戏开发实战教程(大学霸内部资料) 试读下载地址:http://pan.baidu.com/s/1sj7DvQH 介绍:本教程是国内第一本Swift游戏开发专向资料. 本教程具体解说记忆配对 ...
- asp.net mvc+jquery easyui开发实战教程之网站后台管理系统开发4- 后台模板html页面创建
上一篇教程<asp.net mvc+jquery easyui开发实战教程之网站后台管理系统开发3-登录模块开发>完成了本项目的登录模块,登录后就需要进入后台管理首页了,需要准备一个后台模 ...
- asp.net mvc+jquery easyui开发实战教程之网站后台管理系统开发2-Model层建立
上篇(asp.net mvc+jquery easyui开发实战教程之网站后台管理系统开发1-准备工作)文章讲解了开发过程中的准备工作,主要创建了项目数据库及项目,本文主要讲解项目M层的实现,M层这里 ...
- 微信小程序-云开发实战教程
微信小程序-云开发实战教程 云函数,云存储,云数据库,云调用 https://developers.weixin.qq.com/miniprogram/dev/wxcloud/basis/gettin ...
- Python开发实战教程(8)-向网页提交获取数据
来这里找志同道合的小伙伴!↑↑↑ Python应用现在如火如荼,应用范围很广.因其效率高开发迅速的优势,快速进入编程语言排行榜前几名.本系列文章致力于可以全面系统的介绍Python语言开发知识和相关知 ...
- React Native Android原生模块开发实战|教程|心得|怎样创建React Native Android原生模块
尊重版权,未经授权不得转载 本文出自:贾鹏辉的技术博客(http://blog.csdn.net/fengyuzhengfan/article/details/54691503) 告诉大家一个好消息. ...
- HTML5 App商业开发实战教程 基于WeX5可视化开发平台
- asp.net mvc+jquery easyui开发实战教程之网站后台管理系统开发3-登录模块开发
进行本文之前需要在数据库用户表里面增加一条用户数据,直接手动添加即可,未安全考虑密码一定要使用Md5加密后的,这里提供666666的Md5密文为(c831b04de153469d),本文完成登录模块的 ...
- asp.net mvc+jquery easyui开发实战教程之网站后台管理系统开发1-准备工作
/****** Object: 新闻表 Script Date: 2017/9/2 星期六 15:11:12 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENT ...
- android开发实战-记账本APP(二)
继昨天的开发,继续完成今天的内容. (一)开始构建一些业务逻辑,开始构建记账本的添加一笔记账的功能. ①对fab按钮的click时间进行修改,创建一个AlertDialog.Builder对象,因此我 ...
随机推荐
- .Net 配置绑定 IOptions
准备 首先准备下appsettins.json以及目标类 appsettins.json "StudentSettings": { "Id": 1023 ...
- 最新demo版 | 如何0-1开发支付宝小程序之小程序如何上线(四)
支付宝小程序开发 0-1 系列前三期详见: 最新demo版|如何0-1开发支付宝小程序之前期准备篇(一) 最新demo版 | 如何0-1开发支付宝小程序之如何调试小程序(二) 最新demo版 | 如何 ...
- nacos(五): 读取nacos配置并实现动态刷新
接上回<nacos(四): 创建第一个消费者Conumer(单体)>,这一篇将介绍如何读取nacos中的配置,并实现动态刷新. 首先,需要先引入spring-cloud-starter-a ...
- 越“挖”越有料,天翼云“息壤”助攻DeepSeek变身万能搭子!
还在为DeepSeek服务器繁忙而抓狂? 还在为API调用费用涨价而头疼? 还在为数据安全而担忧? 别急! 天翼云"息壤"算力互联调度平台出马 全面解锁DeepSeek新玩法 带你 ...
- 功率MOS管的参数说明
图解功率MOS管的每一个参数! 最大额定参数 最大额定参数,所有数值取得条件(Ta=25℃) VDSS 最大漏-源电压 在栅源短接,漏-源额定电压(VDSS)是指漏-源未发生雪崩击穿前所能施加的最 ...
- MyBatis mapper.xml中SQL处理小于号与大于号 和小于等于号
这种问题在xml处理sql的程序中经常需要我们来进行特殊处理. 其实很简单,我们只需作如下替换即可避免上述的错误: < <= > >= & ' " < ...
- 还在手动更改SpringBoot的环境yml配置文件?老鸟带你可视化配置
问题说明: 在SpringBoot开发时.SpringBoot的特性:'约定大于配置',我们只需要在**application.yml **配置当前的环境变量属与那个文件 比如测试环境 'applic ...
- 傻妞PLUS机器人教程——安装
特性 简单易用的消息搬运功能. 简单强大的自定义回复功能. 完整支持 ECMAScript 5.1 的插件系统,基于 otto. 支持通过内置的阉割版 Express / fetch ,接入互联网. ...
- 无界 | Bncr | Boundless Nodejs Chat Robot 机器人框架安装使用教程
背景:Bncr 是一个开箱即用的Nodejs Chat RoBot(会话式机器人)框架.它基于OOP函数响应式编程,具有占用小.响应快.开发易等特点,允许开发者创建高度可测试.可扩展.松散耦合且易于维 ...
- autMan奥特曼机器人--可爱猫对接微信教程
教程开始 文章底部下载可爱猫框架以及对应的微信版本 1.安装3.4.0.38版本微信,解压可爱猫框架压缩包 如果微信安装了高于3.4.0.38的版本,请先卸载 2.打开可爱猫框架,会弹微信扫码登录,机 ...