鸿蒙next 实战项目视频播放App 小试牛刀

746 阅读3分钟

前言导读:

最新在学习鸿蒙next 开发 就写了一个demo 今天就分享给大家一下

image.png

image.png

image.png

image.png

image.png

image.png

具体实现:

  • 顶部导航实现


import { CommonConstants } from '../common/constants/CommonConstant';
import Setting from './Setting';
import SwiperIndex from './SwiperIndex';


/**
 * * Main page
 */
@Entry
@Component
struct MainPage {
  @State currentIndex: number = CommonConstants.HOME_TAB_INDEX;
  private tabsController: TabsController = new TabsController();

  @Builder TabBuilder(title: string, index: number, selectedImg: Resource, normalImg: Resource) {
    Column() {
      Image(this.currentIndex === index ? selectedImg : normalImg)
        .width(25)
        .height(25)
      Text(title)
        .margin({ top: 4 })
        .fontSize(10)
        .fontColor(this.currentIndex === index ? $r('app.color.mainPage_selected') : $r('app.color.mainPage_normal'))
    }
    .justifyContent(FlexAlign.Center)
    .height(56)
    .width(CommonConstants.FULL_PARENT)
    .onClick(() => {
      this.currentIndex = index;
      this.tabsController.changeIndex(this.currentIndex);
    })
  }

  build() {
    Tabs({
      barPosition: BarPosition.End,
      controller: this.tabsController
    }) {
      TabContent() {
        SwiperIndex()
      }
      .padding({ left: 12, right: 12 })
      .backgroundColor($r('app.color.mainPage_backgroundColor'))
      .tabBar(this.TabBuilder('首页', 0,
      $r('app.media.shouye_zhihui'), $r('app.media.shouye_zhihui_2')))

      TabContent() {
        Setting()
      }
      .padding({ left: 12, right: 12 })
      .backgroundColor($r('app.color.mainPage_backgroundColor'))
      .tabBar(this.TabBuilder("我的", 1,
      $r('app.media.wode_2'), $r('app.media.wode')))
    }
    .width(CommonConstants.FULL_PARENT)
    .backgroundColor(Color.White)
    .barHeight(56)
    .barMode(BarMode.Fixed)
    .onChange((index: number) => {
      this.currentIndex = index;
    })
  }
}
  • 首页顶部导航和页面联动



import { TopBar } from '../view/common/TopBar';
import { PageAll } from '../view/tabcontent/PageAll';
import { CommonConstants } from '../common/constants/CommonConstant';
import { PageEntertainment } from '../view/tabcontent/PageEntertainment';
import { PageMovie } from '../view/tabcontent/PageMovie';
import PageAnime from '../view/tabcontent/PageAnime';
import  PageTV from '../view/tabcontent/PageTV';

/**
 * 创建人:xuqing
 * 创建时间:2023年8月6日14:13:33
 * 类说明: 顶部导航
 */
@Entry
@Component
export default struct SwiperIndex {

  @State index: number = 0;

  build() {
    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start }) {
      TopBar({ index: $index })
      Swiper() {
        PageEntertainment()
        PageMovie()
        PageTV()
        PageAnime()

      }
      .index(this.index)
      .indicator(false)
      .loop(false)
      .duration(CommonConstants.DURATION_PAGE)
      .onChange((index: number) => {
        this.index = index;
      })
    }
    .backgroundColor($r('app.color.start_window_background'))
  }
}
  • 顶部导航实现


import { TopBarItem } from '../../common/bean/TopBarItem';
import { initializeOnStartup } from '../../viewmodel/TopBarViewModel';
import { CommonConstants } from '../../common/constants/CommonConstant';

/**
 * TopBar component.
 */
@Component
export struct TopBar {
  @Link index: number;
  private tabArray: Array<TopBarItem> = initializeOnStartup();

  build() {
    Row({ space: CommonConstants.SPACE_TOP_BAR }) {
      ForEach(this.tabArray,
        (item: TopBarItem) => {
          Text(item.name)
            .fontSize(this.index === item.id ? CommonConstants.FONT_SIZE_CHECKED : CommonConstants.FONT_SIZE_UNCHECKED)
            .fontColor(Color.Black)
            .textAlign(TextAlign.Center)
            .fontWeight(this.index === item.id ? FontWeight.Bold : FontWeight.Regular)
            .onClick(() => {
              this.index = item.id;
            })
        })
    }
    .margin({ left: CommonConstants.ADS_LEFT })
    .width(CommonConstants.FULL_WIDTH)
    .height(CommonConstants.TOP_BAR_HEIGHT)
  }
}
  • 视频播放实现



import { VideoItem } from '../common/bean/VideoItem';
import { initializeOnStartup } from '../viewmodel/VideoViewModel';
import { PlayView } from '../view/play/PlayView';
import { CommonConstants } from '../common/constants/CommonConstant';

/**
 * Video playing page.
 */
@Entry
@Component
struct PageVideo {
  @State videoArray: Array<VideoItem> = initializeOnStartup();
  @State index: number = 0; // video index.
  @State pageShow: boolean = false;

  build() {
    Column() {
      Swiper() {
        ForEach(this.videoArray, (item: VideoItem, index: number) => {
          PlayView({
            index: $index,
            pageShow: $pageShow,
            item: item,
            barPosition: index
          });
        })
      }
      .width(CommonConstants.FULL_WIDTH)
      .height(CommonConstants.FULL_HEIGHT)
      .indicator(false)
      .loop(false)
      .vertical(true)
      .onChange((index: number) => {
        this.index = index;
      })
    }
  }

  onPageShow(): void {
    this.pageShow = true;
  }

  onPageHide(): void {
    this.pageShow = false;
  }
}

播放video



import { VideoItem } from '../common/bean/VideoItem';
import { initializeOnStartup } from '../viewmodel/VideoViewModel';
import { PlayView } from '../view/play/PlayView';
import { CommonConstants } from '../common/constants/CommonConstant';

/**
 * Video playing page.
 */
@Entry
@Component
struct PageVideo {
  @State videoArray: Array<VideoItem> = initializeOnStartup();
  @State index: number = 0; // video index.
  @State pageShow: boolean = false;

  build() {
    Column() {
      Swiper() {
        ForEach(this.videoArray, (item: VideoItem, index: number) => {
          PlayView({
            index: $index,
            pageShow: $pageShow,
            item: item,
            barPosition: index
          });
        })
      }
      .width(CommonConstants.FULL_WIDTH)
      .height(CommonConstants.FULL_HEIGHT)
      .indicator(false)
      .loop(false)
      .vertical(true)
      .onChange((index: number) => {
        this.index = index;
      })
    }
  }

  onPageShow(): void {
    this.pageShow = true;
  }

  onPageHide(): void {
    this.pageShow = false;
  }
}

个人页面实现



import { VideoItem } from '../common/bean/VideoItem';
import { initializeOnStartup } from '../viewmodel/VideoViewModel';
import { PlayView } from '../view/play/PlayView';
import { CommonConstants } from '../common/constants/CommonConstant';

/**
 * Video playing page.
 */
@Entry
@Component
struct PageVideo {
  @State videoArray: Array<VideoItem> = initializeOnStartup();
  @State index: number = 0; // video index.
  @State pageShow: boolean = false;

  build() {
    Column() {
      Swiper() {
        ForEach(this.videoArray, (item: VideoItem, index: number) => {
          PlayView({
            index: $index,
            pageShow: $pageShow,
            item: item,
            barPosition: index
          });
        })
      }
      .width(CommonConstants.FULL_WIDTH)
      .height(CommonConstants.FULL_HEIGHT)
      .indicator(false)
      .loop(false)
      .vertical(true)
      .onChange((index: number) => {
        this.index = index;
      })
    }
  }

  onPageShow(): void {
    this.pageShow = true;
  }

  onPageHide(): void {
    this.pageShow = false;
  }
}

最后总结:

鸿蒙的 ark ui 非常类似flutter 这种声明式ui 所有的布局都是代码编写的和传统的布局和逻辑分开有些区别 刚开始上手的时候可能不适应,慢慢就习惯了 还有一点 代码嵌套 这个其实可以把每个组件抽离出来就可以解决鸿蒙的ark ui 网络部分也是类似前端的http 请求 解析json和前端也比较像 也有面向对象编程的思想, 对前端和移动端同学来说也比较好理解和学习。 今天的文章就讲到这里有兴趣的 关注我B站教程 了解更多鸿蒙开发的知识 可以关注坚果派公众号 。 谢谢

课程地址

www.bilibili.com/cheese/play…

项目内容:

  • 1 常用布局组件的学习
  • 2 网络请求工具类封装
  • 3 arkui 生命周期启动流程
  • 4 日志工具类的封装
  • 5 自定义组合组件的封装
  • 6 路由导航跳转的使用
  • 7 本地地数据的缓存 以及缓存工具类的封装
  • 8 欢迎页面的实现
  • 9 登录案例和自动登录效果实现
  • 10 请求网络数据分页上拉加载 下拉刷新的实现
  • 11 list数据懒加载实现
  • 12 webview组件的使用

如果使用更多好用的鸿蒙next三方库

友情链接

harmony-utils 一款功能丰富且极易上手的HarmonyOS工具库,借助众多实用工具类,致力于助力开发者迅速构建鸿蒙应用,能够满足各种不同的开发需求。

harmony-dialog 一款极为简单易用的零侵入弹窗,仅需一行代码即可轻松实现,无论在何处都能够轻松弹出。