ShortVideoApp视频播放模块四

84 阅读2分钟

一、实现滑动切换视频功能

  • 在首页使用Swiper组件
  • 实现Swiper组件与VideoView的互动
  • 实现Index与MainPage的互动
  build() {
    Column() {
      Swiper() {
        //数据懒加载,从提供的数据源中按需迭代数据
        LazyForEach(this.videoInfoDataSource, (videoInfo: VideoInfo, position) => {
          VideoView({
            videoInfo: videoInfo,
            videoInfoPosition: position,
            videoIndex: this.videoIndex,
            isShowVideoView: this.isShowVideoView
          })
        })
      }
      .width('100%')
      .height('100%')
      .indicator(false) //是否启用导航点指示器
      .loop(false)
      .vertical(true)
      .onChange((i:number)=>{
        //记录当前播放的视频索引
        this.videoIndex = i;
      })
    }.width('100%')
  }
}

使用@Link和父组件变量相关联 使用@Watch:需要定义一个函数名称,把这个名称和Watch装饰器绑定,装饰器就可以根据函数里的参数和返回值的变化做出响应 onChange方法:监听父组件数据变化。

//videoIndex记录Swiper当前显示的页的视频索引
@Link @Watch('handlePageShow') videoIndex:number;
//用于控制标识视频播放器是否显示
@Link @Watch('handlePageShow') isShowVideoView:boolean;

/*根据videoIndex、isShowVideoView和videoInfoPosition更改播放状态*/
handlePageShow():void{
  //判断视频界面是否进入前台,同时判断当前视频索引是否为swiper选中的视频,来决定是否播放
  if (this.isShowVideoView && this.videoInfoPosition === this.videoIndex) {
    this.play();
  }else{
    this.stop();
  }
}

二、实现视频数据存储

  • 基于IDataSource接口实现视频数据存储
  • 抽象类BasicDataSource--> FavoriteDataSource\FollowDataSource\FollowDataSource\ThumbsUpDataSource\VideoInfoDataSource
  • 通过LazyForEach实现视频懒加载
  • 在Index页面传递视频数据源给首页 image.png
import Constants from '../common/Constants'
import { FavoriteDataSource } from '../datasource/FavoriteDataSource'
import { FollowDataSource } from '../datasource/FollowDataSource'
import { ThumbsUpDataSource } from '../datasource/ThumbsUpDataSource'
import { VideoInfoDataSource } from '../datasource/VideoInfoDataSource'
import { MainPage } from './MainPage'
import { MePage } from './MePage'
import { VideoPublishPage } from './VideoPublishPage'

/**
 * 应用入口-主页面
 * */

@Entry
@Component
struct Index {
  @State isShowVideoView:boolean = false;
  @Provide videoInfoDataSource : VideoInfoDataSource = new VideoInfoDataSource(Constants.VIDEO_INFO_ARR)
  @Provide thumbsUpDataSource : ThumbsUpDataSource = new ThumbsUpDataSource(Constants.THUMBS_UP_ARR)
  @Provide favoriteDataSource : FavoriteDataSource = new FavoriteDataSource(Constants.FAVORITE_ARR)
  @Provide followDataSource : FollowDataSource = new FollowDataSource(Constants.FOLLOW_ARR)
  //provide--装饰器--给子组件提供数据源
  @State currentIndex:number = 0;
  private tabsController : TabsController = new TabsController();
  build() {
    //基于Tabs组件实现导航栏--底部
    Tabs({ barPosition: BarPosition.End }) {
      //TabContent--设置页签的内容
      TabContent() {
        MainPage({
          isShowVideoView:this.isShowVideoView,
          videoInfoDataSource:this.videoInfoDataSource
        })
      }.tabBar('首页')

      TabContent() {
      }.tabBar('朋友')

      TabContent() {
        VideoPublishPage()
      }.tabBar('+')

      TabContent() {
      }.tabBar('消息')

      TabContent() {
        MePage()
      }.tabBar('我')
    }
  }
}

三、通过Builder自定义导航栏的样式并在TabContent中使用TabBuilder

//自定义导航栏样式
@Builder
TabBuilder(title: string, index: number) {
  Column() {
    //设置选中和未选中的样式
    Text(title)
      .fontColor(this.currentIndex === index ? '#FFFFFF' : '#E6E6E6')
  }
  .width('100%')
  .height('100%')
  .justifyContent(FlexAlign.Center)
  .backgroundColor(Color.Black)
  .onClick(()=>{
    //记录当前索引是否是首页
    if (index === 0) {
      // 是首页
      this.isShowVideoView = true;
    } else {
      this.isShowVideoView = false;
    }

    // 如果是视频发布页面的页签索引,则跳转到视频发布页面
    if (index === 2) {
      router.pushUrl({
        url: 'pages/VideoPublishPage'
      })
    } else if (index === 1 || index === 3) {
      // 如果是页签索引为1或者3
      // 什么都不做
    } else {
      // 如果是页签索引为4或者是其他页签,则切换到该页签
      this.tabsController.changeIndex(index);
    }
  })
}