poem_page.dart 6.76 KB
import 'package:flutter/material.dart';
import 'package:one_poem/category/category_router.dart';
import 'package:one_poem/poem/poem_router.dart';
import 'package:one_poem/routers/fluro_navigator.dart';
import 'package:one_poem/tiktok/controller/tiktok_video_list_controller.dart';
import 'package:one_poem/tiktok/mock/video.dart';
import 'package:one_poem/tiktok/pages/search_page.dart';
import 'package:one_poem/tiktok/style/physics.dart';
import 'package:one_poem/tiktok/widgets/tiktok_scaffold.dart';
import 'package:one_poem/tiktok/widgets/tiktok_top_info.dart';
import 'package:one_poem/tiktok/widgets/tiktok_video.dart';
import 'package:one_poem/tiktok/widgets/tiktok_video_button_column.dart';
import 'package:one_poem/tiktok/widgets/tiktok_video_poem.dart';
import 'package:one_poem/widgets/bars/home_types_bar.dart';
import 'package:one_poem/widgets/my_app_bar.dart';
import 'package:video_player/video_player.dart';

import 'poem_detail.dart';

import 'package:one_poem/extension/int_extension.dart';

class PoemPage extends StatefulWidget {
  const PoemPage({Key? key}) : super(key: key);

  @override
  _PoemPageState createState() => _PoemPageState();
}

class _PoemPageState extends State<PoemPage> with WidgetsBindingObserver {
  TikTokScaffoldController tkController = TikTokScaffoldController();

  final PageController _pageController = PageController();

  final TikTokVideoListController _videoListController =
      TikTokVideoListController();
  List<UserVideo> videoDataList = [];

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) async {
    if (state != AppLifecycleState.resumed) {
      _videoListController.currentPlayer.pause();
    }
  }

  @override
  void dispose() {
    WidgetsBinding.instance!.removeObserver(this);
    _videoListController.currentPlayer.pause();
    super.dispose();
  }

  @override
  void initState() {
    videoDataList = UserVideo.fetchVideo();
    WidgetsBinding.instance!.addObserver(this);
    _videoListController.init(
      pageController: _pageController,
      initialList: videoDataList
          .map(
            (e) => VPVideoController(
              videoInfo: e,
              builder: () => VideoPlayerController.asset(e.url),
            ),
          )
          .toList(),
      videoProvider: (int index, List<VPVideoController> list) async {
        return videoDataList
            .map(
              (e) => VPVideoController(
                videoInfo: e,
                builder: () => VideoPlayerController.asset(e.url),
              ),
            )
            .toList();
      },
    );
    _videoListController.addListener(() {
      setState(() {});
    });
    tkController.addListener(
      () {
        if (tkController.value == TikTokPagePosition.middle) {
          _videoListController.currentPlayer.play();
        } else {
          _videoListController.currentPlayer.pause();
        }
      },
    );

    super.initState();
  }

  @override
  void setState(fn) {
    if (mounted) {
      super.setState(fn);
    }
  }

  @override
  Widget build(BuildContext context) {
    Widget? currentPage;
    double a = MediaQuery.of(context).size.aspectRatio;
    bool hasBottomPadding = a < 0.55;

    var detailPage = PoemDetailPage(
      onPop: () {
        tkController.animateToMiddle();
      },
      poemId: 1,
      poemPanelHeight: 60.px,
    );
    var searchPage = SearchPage(
      onPop: tkController.animateToMiddle,
    );

    // 组合
    return TikTokScaffold(
      controller: tkController,
      header: MyAppBar(
        isBack: false,
        isTransparent: true,
        homeMenuHeader: HomeTypesHeader(
          funcCenter: () {
            _videoListController.currentPlayer.pause();
            NavigatorUtils.push(
              context,
              CategoryRouter.categoryPage,
            );
          },
        ),
        homeActionWidgets: IconButton(
          icon: const Icon(
            Icons.search,
            color: Colors.white,
          ),
          onPressed: () {
            NavigatorUtils.push(context, PoemRouter.poemSearchPage);
            _videoListController.currentPlayer.pause();
          },
        ),
      ),
      leftPage: searchPage,
      rightPage: detailPage,
      enableGesture: true,
      page: Stack(
        children: <Widget>[
          PageView.builder(
            key: const Key('home'),
            physics: const QuickerScrollPhysics(),
            controller: _pageController,
            scrollDirection: Axis.vertical,
            itemCount: _videoListController.videoCount,
            itemBuilder: (context, i) {
              // 拼一个视频组件出来
              var player = _videoListController.playerOfIndex(i)!;
              var data = player.videoInfo!;
              // 右侧按钮列
              Widget buttons = TikTokButtonColumn(
                isFavorite: false,
                onAvatar: () {
                  tkController.animateToPage(TikTokPagePosition.right);
                },
                onFavorite: () {},
                onShare: () {},
              );
              Widget poem = TikTokVidePoem(
                title: "每日一言",
                poem:
                    "清晨入古寺,初日照高林。\n曲径通幽处,禅房花木深。\n山光悦鸟性,潭影空人心。\n万籁此都寂,但余钟磬音。\n",
                author: "----《题破山寺后禅院》常建",
                onShowDetail: () {
                  tkController.animateToPage(TikTokPagePosition.right);
                },
              );
              Widget topInfo = const TikTokTopInfoColumn(info: "早安");
              // video
              Widget currentVideo = Center(
                child: AspectRatio(
                  aspectRatio: player.controller.value.aspectRatio,
                  child: VideoPlayer(player.controller),
                ),
              );

              currentVideo = TikTokVideoPage(
                // 手势播放与自然播放都会产生暂停按钮状态变化,待处理
                hidePauseIcon: !player.showPauseIcon.value,
                aspectRatio: 9 / 16.0,
                key: Key(data.url + '$i'),
                tag: data.url,
                bottomPadding: hasBottomPadding ? 16.px : 16.px,
                onSingleTap: () async {
                  if (player.controller.value.isPlaying) {
                    await player.pause();
                  } else {
                    await player.play();
                  }
                  setState(() {});
                },
                onAddFavorite: () {},
                rightButtonColumn: buttons,
                leftPoemArea: poem,
                topInfo: topInfo,
                video: currentVideo,
              );
              return currentVideo;
            },
          ),
          currentPage ?? Container(),
        ],
      ),
    );
  }
}