HarmonyOS NEXT⚡️构建类似抖音的视频布局与动画

524 阅读4分钟

“本文正在参加华为鸿蒙有奖征文征文活动”

image.png

构建类似抖音的视频布局与动画

自学鸿蒙也有一段时间了,论语中有句话叫温故而知新,可以为师矣。所以在忙完手头工作之后,我觉得有必要再写一写鸿蒙代码了。士兵突击中有句经典的台词 好的枪手都是子弹喂出来的,所以我坚信好的程序员都是在N多次的代码实践中成长起来的。

闲话少说,进入正题。本文将完成抖音APP视频模块的部分仿写。围绕着静态布局分析及实践,简单的旋转动画来展开聊聊鸿蒙应用开发。

静态布局分析及实践

布局分析

根据分析抖音的布局看出,分为三大部分:

  1. 最外层容器也是视频播放区域
  2. 底部的昵称和视频描述文字
  3. 右侧头像 点赞评论收藏按钮等竖着排列的按钮
image.png

代码实践

整体布局搭建

作为一个前端,这种布局我第一个想到的就是‌子绝父相定位。但是鸿蒙文档中并没有定位的这个概念,在他文章中叫做堆叠。于是我们就要使用Stack这个堆叠容器。官方对于该容器的描述为:堆叠容器,子组件按照顺序依次入栈,后一个子组件覆盖前一个子组件。所以按照我的理解就是子组件按照从上向下的顺序层级递增。

代码

    // 与底部采用左下对齐
    Stack({
      alignContent: Alignment.BottomStart
    }) {
      // 视频主体与右侧采用右下对齐
      Stack({
        alignContent: Alignment.BottomEnd
      }) {
        // 视频主体
        Text('视频主体')
          .width('100%')
          .height('100%')
          .backgroundColor(Color.Red)
        // 右侧功能区
        Text('右侧功能区')
          .width('50vp')
          .height('50%')
          .backgroundColor(Color.Blue)
      }
      // 底部昵称以及描述
      Text('底部区域')
        .width('100%')
        .height('30vp')
        .backgroundColor(Color.Green)
    }

效果

image.png
视频布局

由于视频是可以上下滑动切换的所以我觉得使用Swiper+Video这两个组件来写应该是可以的

代码

// 视频主体
Video({
  src: item,
  previewUri: this.previewUris,
  controller: this.controller
})
  .muted(false)//设置是否静音
  .controls(false)//设置是否显示默认控制条
  .autoPlay(true)//设置是否自动播放
  .loop(true)//设置是否循环播放
  .objectFit(ImageFit.Contain) // 设置视频适配模式
右侧布局

右侧内容还是占整个模块不少的比重,我将右侧拆分为三个组件

  1. 头像组件,使用Stack布局,细分为头像图片和点击关注按钮两部分

    在Stack定位布局中,一个头像Image 一个点赞按钮Image,通过margin将点赞按钮置于头像的下面边缘处

代码

// 头像关注
@Component
struct Via {
  build() {
    Stack() {
      Image($r('app.media.touxiang'))
        .width('45vp')
        .height('45vp')
        .border({
          width: '2vp',
          color: '#ffffff',
          style: BorderStyle.Solid
        })
        .borderRadius('45vp')
      Image($r('app.media.add'))
        .width('20vp')
        .height('20vp')
        .margin({top: '45vp'})
    }
  }
}
  1. 点赞收藏分享按钮,使用Cloumn将icon和文字上下布局

    Column布局是上下布局方式,自组件自上而下排成一列,以下代码中使用一个Image容器 一个Text容器,并在组件内接受icon名称以及text文本,以便达到点赞,评论,收藏,分享按钮的组件复用

代码

// icon & 数量上下布局
@Component
struct IconAndText {
  @Prop icon:String = ''
  @Prop text:String = ''
  build() {
    Column() {
      Image($r(`app.media.${this.icon}`))
        .width('30vp')
        .margin({
          top: '5vp'
        })
        .opacity(0.8)
      Text(`${this.text}`)
        .fontColor('#ffffff')
    }.margin({top:'10vp'})

  }
}
  1. 右下角音乐旋转组件,其实就是个自转的图片

    使用animation属性动画,在.onApper()方法中改变rotatevalue的值,利用animation属性动画值改变自动执行动画特性从而达到动画的执行。在animation方法中iterations属性的值为-1 从而达到循环执行目的

代码

// 背景音乐入口
@Component
struct MusicEntry {
  @State rotateValue:number = 0
  aboutToAppear() {

  }
  build(){
    Image($r('app.media.touxiang'))
      .width('40vp')
      .height('40vp')
      .borderRadius('45vp')
      .margin({top:'15vp'})
      .rotate({ angle: this.rotateValue })
      .animation({
        curve: Curve.Linear,
        duration: 3500,
        iterations: -1
      })
      .onAppear(() => {
        this.rotateValue = 360
      })
  }
}
底部布局

底部布局就是两行文字上下布局 非常的简单

同样是使用Column布局 使两个Text容器上下排列,并且在第二个Text容器中给一个上外边距,达到两段文字隔开距离的效果

代码

// 底部昵称
@Component
struct FooterNikeName {
  build() {
    Column() {
      Text('@把梦想揉碎')
        .fontColor('#FFFFFF')
        .fontSize('18vp')
        .fontWeight(FontWeight.Medium)
      Text('哈哈哈,这条视频也太有意思了吧')
        .fontColor('#FFFFFF')
        .margin({top: '10vp'})
        .fontSize('15vp')
    }
      .margin({left: '10vp',bottom: '10vp'})
      .alignItems(HorizontalAlign.Start)
  }
}

最终效果GIF

11.mov.gif

鸿蒙应用带来的思考

ArkUI的组件化设计让我深刻体会到组件复用的重要性。在这个项目中,我将右侧功能区拆分为多个独立组件,如头像关注组件、点赞收藏组件等,这种做法不仅提高了代码的可读性和维护性,还便于在未来的开发中进行复用。通过这种方式,能够在保证功能完整的前提下,保持代码结构的清晰和模块化。

写在最后

通过本次仿写抖音视频布局的实践,我进一步熟悉了HarmonyOS中的ArkUI框架,也加深了对鸿蒙生态系统的理解。这次开发的过程让我认识到,不论是前端开发还是移动端开发,掌握一个框架的核心思想和布局模型至关重要。此外,通过不断的代码实践和总结,我也看到了自己在开发技能上的进步。

希望这篇文章能为其他开发者提供一些帮助和启发。未来,我将继续深入学习HarmonyOS,并分享更多的开发经验和心得。让我们一起在鸿蒙生态的广阔天地中探索更多的可能性。