import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_aliplayer/flutter_aliplayer_factory.dart'; import 'package:flutter_aliplayer_example/config.dart'; import 'package:flutter_aliplayer_example/model/video_model.dart'; import 'package:flutter_aliplayer_example/util/network_utils.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:flutter_aliplayer/flutter_alilistplayer.dart'; class VideoGridPage extends StatefulWidget { final ModeType playMode; const VideoGridPage({Key key, this.playMode}) : super(key: key); @override _VideoGridPageState createState() => _VideoGridPageState(); } class _VideoGridPageState extends State with WidgetsBindingObserver { List _dataList = []; int _page = 1; VideoShowMode _showMode = VideoShowMode.Grid; RefreshController _refreshController = RefreshController(initialRefresh: false); RefreshController _videoListRefreshController = RefreshController(initialRefresh: false); PageController _pageController; FlutterAliListPlayer fAliListPlayer; int _curIdx = 0; int _lastCurIndex = -1; bool _isPause = false; double _playerY = 0; bool _isFirstRenderShow = false; bool _isBackgroundMode; @override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); fAliListPlayer = FlutterAliPlayerFactory.createAliListPlayer(playerId: 'aliListPlayer'); fAliListPlayer.setAutoPlay(true); fAliListPlayer.setLoop(true); var configMap = { 'mClearFrameWhenStop': true, }; fAliListPlayer.setConfig(configMap); fAliListPlayer.setOnRenderingStart((playerId) { Future.delayed(Duration(milliseconds: 50), () { setState(() { _isFirstRenderShow = true; }); }); }); fAliListPlayer.setOnStateChanged((newState, playerId) { switch (newState) { case FlutterAvpdef.AVPStatus_AVPStatusStarted: setState(() { _isBackgroundMode = false; _isPause = false; }); break; case FlutterAvpdef.AVPStatus_AVPStatusPaused: setState(() { _isPause = true; }); break; default: } }); fAliListPlayer.setOnError((errorCode, errorExtra, errorMsg, playerId) { Fluttertoast.showToast(msg: errorMsg); }); _onRefresh(); } @override void dispose() { super.dispose(); this.fAliListPlayer.clear(); this.fAliListPlayer.stop(); this.fAliListPlayer.destroy(); WidgetsBinding.instance.removeObserver(this); } @override void didChangeAppLifecycleState(AppLifecycleState state) { super.didChangeAppLifecycleState(state); if (_showMode == VideoShowMode.Grid) { return; } switch (state) { case AppLifecycleState.inactive: break; case AppLifecycleState.resumed: fAliListPlayer.play(); break; case AppLifecycleState.paused: _isBackgroundMode = true; fAliListPlayer.pause(); break; case AppLifecycleState.detached: break; } } _onRefresh() async { _page = 1; _dataList = []; _loadData(); } _onLoadMore() async { _page++; _loadData(); } _loadData() async { NetWorkUtils.instance.getHttp(HttpConstant.GET_RANDOM_USER, successCallback: (data) { String token = data['token']; NetWorkUtils.instance.getHttp(HttpConstant.GET_RECOMMEND_VIDEO_LIST, params: {'token': token, "pageIndex": _page, "pageSize": 10}, successCallback: (data) { print('data=$data'); _loadDataFinish(data); }, errorCallback: (error) { print("error"); }); }, errorCallback: (error) { print("error"); }); } _loadDataFinish(data) { VideoListModel videoListModel = VideoListModel.fromJson(data); if (videoListModel.videoList.isNotEmpty) { videoListModel.videoList.forEach((element) { if (widget.playMode == ModeType.URL) { fAliListPlayer.addUrlSource( url: element.fileUrl, uid: element.videoId); } else if (widget.playMode == ModeType.STS) { fAliListPlayer.addVidSource( vid: element.videoId, uid: element.videoId); } }); _dataList.addAll(videoListModel.videoList); } _refreshController.refreshCompleted(); _videoListRefreshController.refreshCompleted(); if (videoListModel.videoList.length < 10) { _refreshController.loadNoData(); _videoListRefreshController.loadNoData(); } else { _refreshController.loadComplete(); _videoListRefreshController.loadComplete(); } setState(() {}); } _buildGridView() { return Scaffold( appBar: AppBar( title: Text('播放列表'), ), body: SmartRefresher( enablePullDown: true, enablePullUp: true, header: ClassicHeader(), footer: ClassicFooter( loadStyle: LoadStyle.ShowWhenLoading, ), controller: _refreshController, onRefresh: _onRefresh, onLoading: _onLoadMore, child: GridView.builder( shrinkWrap: true, itemCount: _dataList.length, physics: AlwaysScrollableScrollPhysics(), padding: EdgeInsets.all(16), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, mainAxisSpacing: 10, crossAxisSpacing: 10, childAspectRatio: 9 / 16, ), itemBuilder: (context, index) { VideoModel model = _dataList[index]; return InkWell( onTap: () { setState(() { _curIdx = index; _lastCurIndex = index; _showMode = VideoShowMode.Screen; _pageController = PageController(initialPage: _curIdx); }); start(); }, child: Container( color: Colors.black, child: Image.network( model.coverUrl, fit: BoxFit.fitWidth, ), ), ); }, ), ), ); } _buildFullScreenView() { return WillPopScope( onWillPop: () async { if (_showMode == VideoShowMode.Screen) { _exitScreenMode(); return false; } return true; }, child: Scaffold( backgroundColor: Colors.black, body: NotificationListener( onNotification: (ScrollNotification notification) { if (notification.depth == 0 && notification is ScrollUpdateNotification) { final PageMetrics metrics = notification.metrics as PageMetrics; _playerY = metrics.pixels - _curIdx * MediaQuery.of(context).size.height; setState(() {}); } else if (notification is ScrollEndNotification) { _playerY = 0.0; PageMetrics metrics = notification.metrics as PageMetrics; _curIdx = metrics.page.round(); if (_lastCurIndex != _curIdx) { start(); } _lastCurIndex = _curIdx; } return false; }, child: Stack( children: [ Positioned( left: 0, bottom: _playerY, width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height, child: Container( color: Colors.black, width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height, child: AliPlayerView( onCreated: onViewPlayerCreated, x: 0, y: _playerY, width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height, ), ), ), SmartRefresher( enablePullDown: true, enablePullUp: true, header: ClassicHeader(), footer: ClassicFooter( loadStyle: LoadStyle.ShowWhenLoading, ), controller: _videoListRefreshController, onRefresh: _onRefresh, onLoading: _onLoadMore, child: CustomScrollView( physics: PageScrollPhysics(), controller: _pageController, slivers: [ SliverFillViewport( delegate: SliverChildBuilderDelegate( (BuildContext context, int index) { return _buildSingleScreen(index); }, childCount: _dataList.length, )) ], ), ), InkWell( onTap: () { _exitScreenMode(); }, child: SafeArea( child: Padding( padding: const EdgeInsets.all(16.0), child: Icon( Icons.arrow_back_ios, size: 24, color: Colors.white, ), ), ), ) ], ), ), ), ); } Widget _buildSingleScreen(int index) { VideoModel model = _dataList[index]; return GestureDetector( onTap: () { setState(() { _isPause = !_isPause; }); if (_isPause) { this.fAliListPlayer.pause(); } else { this.fAliListPlayer.play(); } }, child: Container( // color: Colors.black, child: Stack( children: [ Offstage( offstage: _curIdx == index && _isFirstRenderShow, child: Container( color: Colors.black, child: Image.network( model.coverUrl, // color:Colors.black, fit: BoxFit.contain, alignment: Alignment.center, width: double.infinity, height: double.infinity, ), ), ), Container( color: Colors.black.withAlpha(0), alignment: Alignment.center, child: Offstage( offstage: _isPause == false || _isBackgroundMode == true, child: Icon( Icons.play_circle_filled, size: 48, color: Colors.black, ), ), ), ], ), ), ); } @override Widget build(BuildContext context) { return _showMode == VideoShowMode.Screen ? _buildFullScreenView() : _buildGridView(); } void onViewPlayerCreated(viewId) async { print('onViewPlayerCreated==='); fAliListPlayer.setPlayerView(viewId); } void start() async { if (_dataList != null && _dataList.length > 0 && _curIdx < _dataList.length) { VideoModel model = _dataList[_curIdx]; setState(() { _isPause = false; _isFirstRenderShow = false; }); this.fAliListPlayer.stop(); if (widget.playMode == ModeType.URL) { this.fAliListPlayer.moveTo(uid: model.videoId); } else if (widget.playMode == ModeType.STS) { NetWorkUtils.instance.getHttp(HttpConstant.GET_STS, successCallback: (data) { this.fAliListPlayer.moveTo( uid: model.videoId, accId: data["accessKeyId"], accKey: data["accessKeySecret"], token: data["securityToken"], region: DataSourceRelated.DEFAULT_REGION); print('========${model.videoId}'); }, errorCallback: (error) { print("error"); }); } } } void _exitScreenMode() { setState(() { _showMode = VideoShowMode.Grid; }); this.fAliListPlayer.stop(); } }