1、新建播放组件(预览图和文案可以删除也可以重新自定义,主要是视频地址)
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:midou_ee/car_video/page/car_video_page.dart';
import 'package:midou_ee/common/event_bus.dart';
import 'package:midou_ee/mall/mall_router.dart';
import 'package:midou_ee/routers/navigator_util.dart';
import 'package:midou_ee/utils/screen_util.dart';
import 'package:midou_ee/utils/toast.dart';
import 'package:midou_ee/widgets/load_image.dart';
import 'package:video_player/video_player.dart';
class CarShortVideo extends StatefulWidget {
final String url;
final String previewImageUrl; //预览图片的地址
final bool showProgressBar; //是否显示进度条
final bool showProgressText; //是否显示进度文本
final int positionTag;
final String title;
final int carId;
final int productId;
final int putawayForm;
const CarShortVideo(
this.url, {
Key key,
this.previewImageUrl: '',
this.showProgressBar: true,
this.showProgressText: true,
this.positionTag,
this.title,
this.carId,
this.productId,
this.putawayForm,
}) : super(key: key);
@override
_CarShortVideoState createState() => _CarShortVideoState();
}
class _CarShortVideoState extends State<CarShortVideo> {
VideoPlayerController _controller;
bool _hideActionButton = true;
bool videoPrepared = false; //视频是否初始化
double aspectRatio = 1;
Future _initializeVideoPlayerFuture;
@override
void initState() {
super.initState();
eventBus.on(EventVideoPlayPosition + widget.positionTag.toString(), (arg) {
setState(() {
if (arg == widget.positionTag) {
_controller.play();
videoPrepared = true;
} else {
_controller.pause();
}
});
});
_controller = VideoPlayerController.network(widget.url)
..setLooping(true).then((_) {
if (widget.positionTag == 0 && CarVideoPage.firstInitTimes == 1) {
CarVideoPage.firstInitTimes = 2;
_controller.play();
videoPrepared = true;
setState(() {});
}
});
_initializeVideoPlayerFuture = _controller.initialize();
}
@override
Widget build(BuildContext context) {
aspectRatio = _controller.value.aspectRatio;
return Stack(
children: <Widget>[
Container(
// padding: EdgeInsets.only(top: 20),
color: Color(0XFF333333),
// padding: EdgeInsets.all(20),
child: GestureDetector(
child: Stack(
children: <Widget>[
FutureBuilder(
future: _initializeVideoPlayerFuture,
builder: (context, snapshot) {
// print(snapshot.connectionState);
if (snapshot.connectionState == ConnectionState.done) {
return Center(
child: AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: VideoPlayer(_controller),
),
);
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
),
_getPauseView(),
],
),
onTap: () {
if (_controller.value.isPlaying) {
_controller.pause();
_hideActionButton = false;
setState(() {});
} else {
_controller.play();
videoPrepared = true;
_hideActionButton = true;
setState(() {});
}
},
),
),
_getPreviewImage(), //预览图
_getRightActionView(), //右侧转发,评论按钮
_getLeftActionView(), //左侧文案
],
);
}
Widget _getPreviewImage() {
return Offstage(
offstage: videoPrepared,
child: Container(
width: ScreenUtil.screenWidth,
height: ScreenUtil.screenHeight,
color: Color(0XFF333333),
child: Center(
child: Image.network(
widget.previewImageUrl,
fit: BoxFit.fill,
width: ScreenUtil.screenWidth,
// height: ScreenUtil.screenHeight,
),
),
),
);
}
Widget _getPauseView() {
return Offstage(
offstage: _hideActionButton,
child: Stack(
children: <Widget>[
Align(
child: Container(
height: 50.0,
width: 50.0,
child: LoadAssetImage('icon/icon_video_playing'),
),
alignment: Alignment.center,
),
],
),
);
}
//分享、转发等功能按钮
Widget _getRightActionView() {
return Positioned(
bottom: 0,
right: 0,
child: Container(
// margin: const EdgeInsets.fromLTRB(0, 0, 15, 120.0),
// child: Column(
// children: <Widget>[
// Container(
// child: Column(children: <Widget>[
// LoadAssetImage('icon/icon_video_praise',
// width: 36, height: 36),
// Text(
// "1.6w",
// style: TextStyle(
// fontSize: 15,
// color: Colors.white,
// decoration: TextDecoration.none),
// ),
// ]),
// ),
// SizedBox(height: 8),
// Container(
// child: Column(children: <Widget>[
// LoadAssetImage('icon/icon_video_msg',
// width: 36, height: 36),
// Text(
// "1.3w",
// style: TextStyle(
// fontSize: 15,
// color: Colors.white,
// decoration: TextDecoration.none),
// ),
// ]),
// ),
// SizedBox(height: 8),
// Container(
// child: Column(children: <Widget>[
// LoadAssetImage('icon/icon_video_share',
// width: 36, height: 36),
// Text(
// "2.1w",
// style: TextStyle(
// fontSize: 15,
// color: Colors.white,
// decoration: TextDecoration.none),
// ),
// ]),
// ),
// ],
// ),
),
);
}
//左侧文案
Widget _getLeftActionView() {
return Positioned(
bottom: 0,
child: Container(
padding: EdgeInsets.all(30),
width: ScreenUtil.screenWidth,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: Text(
widget.title,
style: TextStyle(fontSize: 16, color: Colors.white),
overflow: TextOverflow.ellipsis,
),
),
GestureDetector(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 11, vertical: 6),
alignment: Alignment.center,
decoration: BoxDecoration(
color: Color(0XFF000000),
borderRadius: BorderRadius.all(Radius.circular(5))),
margin: const EdgeInsets.only(left: 1.0),
child: Text(
'查看详情',
style: TextStyle(
fontSize: 12.0,
color: Color(0XFFF36926),
decoration: TextDecoration.none),
),
),
onTap: () {
if (widget.putawayForm == 1) {
//一口价
NavigatorUtil.push(context,
'${MallRouter.goodDetailPage}?productId=${widget.productId}&carId=${widget.carId}');
} else if (widget.putawayForm == 2) {
//拍卖
NavigatorUtil.push(context,
'${MallRouter.auctionDetailsPage}?productId=${widget.productId}&carId=${widget.carId}');
}
},
),
SizedBox(
width: 20,
),
GestureDetector(
child: LoadAssetImage('icon/icon_video_praise',
width: 21, height: 20),
onTap: () {
Toast.show('该功能暂未开放敬请期待!');
},
),
],
),
),
);
}
@override
void dispose() {
super.dispose();
eventBus.off(EventVideoPlayPosition + widget.positionTag.toString());
_controller.dispose(); //释放播放器资源
}
}
2.分页功能实现(positionTag ,是当前滚动视频自动播放的下标一定要有,否则无法自动播放)
import 'package:flutter/material.dart';
import 'package:midou_ee/car_video/model/car_videos_entity.dart';
import 'package:midou_ee/car_video/widget/car_short_video.dart';
import 'package:midou_ee/common/constants.dart';
import 'package:midou_ee/common/event_bus.dart';
import 'package:midou_ee/net/dio_util.dart';
import 'package:midou_ee/net/http_api.dart';
class CarVideoPage extends StatefulWidget {
static int firstInitTimes = 1;
@override
_CarVideoPageState createState() => _CarVideoPageState();
}
class _CarVideoPageState extends State<CarVideoPage> {
// SwiperController _controller = SwiperController();
PageController _controller = PageController();
List<CarVideosEntity> carList = [];
int pageNum = 1;
bool _pageState = true;
@override
void initState() {
super.initState();
// _controller.addListener(() {
// if (_controller.page.floor() == _controller.page) {
// if(_controller.page%9 == 0){
// _loadData();
// }
// eventBus.emit(
// EventVideoPlayPosition + _controller.page.floor().toString(),
// _controller.page.floor());
// }
// });
// _pageController = PageController(initialPage: 0);
setState(() {
_loadData();
});
}
List<Widget> _buildListItem() {
List<Widget> items = List<Widget>();
if (carList.length > 0) {
var _i = 0;
carList.forEach((value) {
items.add(CarShortVideo(
value.playURL,
previewImageUrl: value.imageUrl,
positionTag: _i,
title: value.productName,
productId:value.productId,
carId: value.carId,
putawayForm: value.putawayForm,
));
_i++;
});
}
// carList = [];
return items;
}
@override
Widget build(BuildContext context) {
return carList.length > 0
? Scaffold(
// body: Swiper(
// autoStart: false,
// circular: false,
// direction: Axis.vertical,
// children: _buildListItem(),
// controller: _controller,
// ),
body: PageView(
children: _buildListItem(),
controller: _controller,
scrollDirection: Axis.vertical,
onPageChanged: (int index){
if(_pageState){
if(index%9 == 0){
_loadData();
}
}
eventBus.emit(
EventVideoPlayPosition + index.toString(),
index);
setState(() {
});
},
),
)
:Scaffold(
body: Container(),
) ;
}
Future _loadData() async {
var params = {
"pageNum": pageNum,
"pageSize": Constants.pageSize,
};
await DioUtil.instance.requestNetWork<CarVideosEntity>(
Method.post, '${HttpApi.PRODUCT_QUERYBYVIDEO}',
params: params, isList: true, onSuccessList: (data) {
if (data != null) {
setState(() {
if(data.length > 0){
var i = 0;
data.forEach((item){
item.index = (pageNum-1)*10+i;
carList.add(item);
i++;
});
pageNum ++;
// carList;
}else{
// setState(() {
_pageState = false;
// });
}
});
}
});
}
@override
void dispose() {
super.dispose();
CarVideoPage.firstInitTimes = 1;
}
}