3.gif
Flutter 仿抖音效果 (一) 全屏點愛星
Flutter 仿抖音效果 (二) 界面布局
項目地址:https://github.com/CZXBigBrother/flutter_TikTok 持續效果更新
實現抖音視頻播放列表需要解決的問題
- 1.視頻播放
- 2.切換時開始和停止視頻的播放
視頻播放
視頻播放實際實現是非常簡單的只用使用VideoPlayerController就能快速的接入
video_player: ^0.10.1+5
使用到的API
/// finished.
Future<void> play() async {
/// Sets whether or not the video should loop after playing once. See also
/// [VideoPlayerValue.isLooping].
Future<void> setLooping(bool looping) async
/// Pauses the video.
Future<void> pause() async
Snip20200113_2.png
加載完成前,使用第一幀的圖片作為預留圖,加載完成之后,隱藏預覽圖,保證短視頻加載緩慢是不會出現黑屏的情況 ,播放按鍵和預留圖都通過stack布局的方式進行.
return Stack(
children: <Widget>[
GestureDetector(
child: Stack(
children: <Widget>[
Container(
margin: EdgeInsets.only(top: ScreenService.topSafeHeight),
width: ScreenService.width,
height: h, //h/w = sh/sw
child: VideoPlayer(_controller),
),
getPauseView()
],
),
onTap: () {
if (_controller.value.isPlaying) {
_controller.pause();
_hideActionButton = false;
} else {
_controller.play();
videoPrepared = true;
_hideActionButton = true;
}
setState(() {});
}),
// this.getVideo(),
getPreviewImg(),
getLikesView(),
this.getUserAndTitle()
],
);
上下切換列表
使用Swiper
body: Container(
child: Swiper(
autoStart: false,
circular: false,
direction: Axis.vertical,
children: children,
controller: _controller,
),
color: Colors.black,
),
切換時開始和停止視頻的播放
添加 SwiperController監聽
SwiperController _controller = SwiperController();
初始化時 我們會使用
會標記 一個tag值用來判斷當前隊列的編號
然后在當滑動到某個視頻時通知開始播放
_controller.addListener(() {
if (_controller.page.floor() == _controller.page) {
eventBus.emit(keyPlayVideo + _controller.page.floor().toString(),
_controller.page.floor());
}
});
這里會用到一個東西就是eventBus.這個和iOS 的KVO 差不多的意思.添加監聽的KEY 然后注冊接受.內部存儲里一個事件的隊列.發送通知是會執行所有的接受者
在視頻controller中注冊監聽eventBus
eventBus.on(keyPlayVideo + widget.positionTag.toString(), (arg) {
if (arg == widget.positionTag) {
_controller.play();
videoPrepared = true;
_hideActionButton = true;
} else {
_controller.pause();
_hideActionButton = false;
}
setState(() {});
});
在dispose的時候必須移除eventBus 和 等等的Controller,否則會報錯
@override
void dispose() {
this.scroController.dispose();
this.timer.cancel();
_controller.dispose(); //釋放播放器資源
super.dispose();
}