当前位置: 首页 > news >正文

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。

1. 基础点赞功能实现

1.1 创建数据模型

// VideoModel.ets
export class VideoModel {id: string = "";title: string = "";author: string = "";coverUrl: string = "";videoUrl: string = "";likes: number = 0;isLiked: boolean = false;comments: number = 0;shares: number = 0;
}

1.2 点赞按钮组件

// LikeButton.ets
@Component
export struct LikeButton {@Prop video: VideoModel;@State private isAnimating: boolean = false;build() {Column() {// 点赞按钮Image(this.video.isLiked ? $r('app.media.ic_liked') : $r('app.media.ic_like')).width(40).height(40).scale({ x: this.isAnimating ? 1.2 : 1, y: this.isAnimating ? 1.2 : 1 }).animation({ duration: 200, curve: Curve.EaseInOut }).onClick(() => {this.handleLike();})// 点赞数Text(this.video.likes.toString()).fontSize(14).fontColor(Color.White).margin({ top: 4 })}.alignItems(HorizontalAlign.Center)}private handleLike() {// 触发动画this.isAnimating = true;setTimeout(() => {this.isAnimating = false;}, 200);// 更新点赞状态this.video.isLiked = !this.video.isLiked;this.video.likes += this.video.isLiked ? 1 : -1;// 这里可以添加网络请求,同步点赞状态到服务器this.syncLikeStatus();}private syncLikeStatus() {// 实际项目中这里应该调用API同步点赞状态console.log(`视频${this.video.id}点赞状态: ${this.video.isLiked}`);}
}

2. 双击点赞功能实现

2.1 视频组件封装

// VideoPlayer.ets
@Component
export struct VideoPlayer {@Prop video: VideoModel;@State private showLikeAnimation: boolean = false;private lastTapTime: number = 0;build() {Stack() {// 视频播放器Video({src: this.video.videoUrl,controller: new VideoController()}).width('100%').height('100%').objectFit(ImageFit.Cover).onTouch((event: TouchEvent) => {if (event.type === TouchType.Down) {this.handleTap();}})// 点赞动画if (this.showLikeAnimation) {Image($r('app.media.ic_liked')).width(80).height(80).position({ x: '50%', y: '50%' }).scale({ x: 0, y: 0 }).opacity(1).animation({duration: 1000,curve: Curve.EaseOut,onFinish: () => {this.showLikeAnimation = false;}}).scale({ x: 1.5, y: 1.5 }).opacity(0)}// 右侧互动栏Column() {LikeButton({ video: this.video }).margin({ bottom: 20 })// 其他互动按钮(评论、分享等)...}.position({ x: '85%', y: '50%' })}.width('100%').height('100%')}private handleTap() {const currentTime = new Date().getTime();const timeDiff = currentTime - this.lastTapTime;if (timeDiff < 300) { // 双击判定if (!this.video.isLiked) {this.video.isLiked = true;this.video.likes += 1;this.showLikeAnimation = true;this.syncLikeStatus();}}this.lastTapTime = currentTime;}private syncLikeStatus() {// 同步点赞状态到服务器console.log(`视频${this.video.id}通过双击点赞`);}
}

3. 点赞动画优化

3.1 粒子爆炸效果

// ParticleLikeAnimation.ets
@Component
export struct ParticleLikeAnimation {@State private particles: { id: number, x: number, y: number, scale: number, opacity: number }[] = [];private particleCount: number = 12;build() {Stack() {ForEach(this.particles, (particle) => {Image($r('app.media.ic_liked')).width(20).height(20).position({ x: `${particle.x}%`, y: `${particle.y}%` }).scale({ x: particle.scale, y: particle.scale }).opacity(particle.opacity)})}}public startAnimation() {this.particles = [];// 生成粒子for (let i = 0; i < this.particleCount; i++) {this.particles.push({id: i,x: 50,y: 50,scale: 0,opacity: 1});}// 动画效果this.particles.forEach((particle, index) => {const angle = (index * (360 / this.particleCount)) * (Math.PI / 180);const distance = 15 + Math.random() * 10;setTimeout(() => {particle.x = 50 + Math.cos(angle) * distance;particle.y = 50 + Math.sin(angle) * distance;particle.scale = 0.5 + Math.random() * 0.5;particle.opacity = 0;}, index * 50);});setTimeout(() => {this.particles = [];}, 1000);}
}

3.2 在VideoPlayer中使用粒子动画

// 修改VideoPlayer.ets
@Component
export struct VideoPlayer {@State private particleAnimRef: ParticleLikeAnimation | null = null;build() {Stack() {// ...其他组件// 替换原来的点赞动画ParticleLikeAnimation({ ref: this.particleAnimRef })// ...其他组件}}private handleTap() {const currentTime = new Date().getTime();const timeDiff = currentTime - this.lastTapTime;if (timeDiff < 300) { // 双击判定if (!this.video.isLiked) {this.video.isLiked = true;this.video.likes += 1;this.particleAnimRef?.startAnimation();this.syncLikeStatus();}}this.lastTapTime = currentTime;}
}

4. 数据持久化与同步

4.1 使用分布式数据服务

// LikeService.ets
import distributedData from '@ohos.data.distributedData';export class LikeService {private kvManager: distributedData.KVManager;private kvStore: distributedData.KVStore;async init() {const config = {bundleName: 'com.example.douyin',userInfo: {userId: 'currentUser',userType: distributedData.UserType.SAME_USER_ID}};this.kvManager = distributedData.createKVManager(config);const options = {createIfMissing: true,encrypt: false,backup: false,autoSync: true,kvStoreType: distributedData.KVStoreType.SINGLE_VERSION};this.kvStore = await this.kvManager.getKVStore('likes_store', options);}async syncLike(videoId: string, isLiked: boolean) {if (!this.kvStore) {await this.init();}try {await this.kvStore.put(videoId, isLiked);await this.kvStore.sync({deviceIds: ['all'],mode: distributedData.SyncMode.PUSH});} catch (error) {console.error('同步点赞状态失败:', JSON.stringify(error));}}async getLikeStatus(videoId: string): Promise<boolean> {if (!this.kvStore) {await this.init();}try {const result = await this.kvStore.get(videoId);return !!result;} catch (error) {console.error('获取点赞状态失败:', JSON.stringify(error));return false;}}
}

4.2 在LikeButton中集成数据服务

// 修改LikeButton.ets
@Component
export struct LikeButton {private likeService: LikeService = new LikeService();aboutToAppear() {this.loadLikeStatus();}private async loadLikeStatus() {const isLiked = await this.likeService.getLikeStatus(this.video.id);this.video.isLiked = isLiked;}private async syncLikeStatus() {await this.likeService.syncLike(this.video.id, this.video.isLiked);}
}

5. 完整视频页面实现

// DouyinPage.ets
@Entry
@Component
struct DouyinPage {@State currentVideoIndex: number = 0;@State videos: VideoModel[] = [{id: "1",title: "第一个视频",author: "创作者1",coverUrl: "resources/cover1.jpg",videoUrl: "resources/video1.mp4",likes: 1234,isLiked: false,comments: 56,shares: 12},// 更多视频...];build() {Stack() {// 视频滑动容器Swiper() {ForEach(this.videos, (video: VideoModel) => {SwiperItem() {VideoPlayer({ video: video })}})}.index(this.currentVideoIndex).autoPlay(false).indicator(false).loop(false).vertical(true).edgeEffect(EdgeEffect.Spring).onChange((index: number) => {this.currentVideoIndex = index;})// 顶部导航Row() {Text("推荐").fontSize(18).fontColor(Color.White).margin({ left: 20 })// 其他导航项...}.width('100%').height(50).position({ x: 0, y: 30 })}.width('100%').height('100%').backgroundColor(Color.Black)}
}

6. 实际项目注意事项

  1. ​性能优化​​:

    • 使用LazyForEach加载视频列表
    • 视频预加载机制
    • 动画使用硬件加速
  2. ​网络请求​​:

    • 实现点赞API接口
    • 添加请求重试机制
    • 处理网络异常情况
  3. ​用户体验​​:

    • 添加加载状态指示器
    • 实现点赞操作的防抖处理
    • 离线状态下的点赞处理
  4. ​安全考虑​​:

    • 点赞操作的身份验证
    • 防止重复点赞
    • 数据加密传输
  5. ​测试要点​​:

    • 双击手势的灵敏度测试
    • 动画性能测试
    • 多设备同步测试
  6. ​扩展功能​​:

    • 点赞列表查看
    • 点赞通知功能
    • 热门点赞视频推荐

通过以上实现,你可以在HarmonyOS 5应用中创建类似抖音的点赞功能,包括基础点赞、双击点赞、动画效果和数据同步等核心功能。

相关文章:

  • 人工操舵是如何操作的?介绍人工操舵的经验和规律
  • Unity实现不倒翁
  • Spring AI MCP
  • UVa12298 3KP-BASH Project
  • AR珠宝佩戴与传统的珠宝购物有哪些区别?​
  • Keepalived 与 Nginx 高可用部署方案详解
  • “详规一张图”——上海土地利用数据
  • Dify-6: 部署
  • PostgreSQL 的扩展pg_walinspect
  • copilot基于 DeepSeek-R1 思路构建 VLA 自动驾驶强化学习系统
  • C# vs2022 找不到指定的 SDK“Microsof.NET.Sdk
  • 第一部分 -- ①语法分析的概要
  • Flask RESTful 示例
  • 使用obsutil工具在OBS上完成基本的数据存取【玩转华为云】
  • 【WiFi帧结构】
  • github.com 链接127.0.0.1
  • 弯曲问题的几个注解
  • 参数量计算举例
  • 大数据学习(136)-数据埋点
  • Chapter03-Authentication vulnerabilities
  • 西安公司团建活动好去处/成都网站seo厂家
  • 个人网站如何建/谷歌搜索引擎入口google
  • 文化传播网站建设/单页网站
  • 个人备案能公司网站/关键词是网站seo的核心工作
  • 安徽网站推广营销设计/seo整站优化服务
  • 家乐福网上商城下载/seo搜索引擎优化课后答案