247 lines
7.7 KiB
Dart
Executable File

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:star_lock/main/lockDetail/videoLog/videoLog/videoLog_entity.dart';
import 'package:star_lock/main/lockDetail/videoLog/videoLogDetail/controlsOverlay_page.dart';
import 'package:star_lock/main/lockDetail/videoLog/videoLogDetail/videoLogDetail_state.dart';
import 'package:star_lock/main/lockDetail/videoLog/widget/full_screenImage_page.dart';
import 'package:star_lock/main/lockDetail/videoLog/widget/video_thumbnail_image.dart';
import 'package:star_lock/tools/dateTool.dart';
import 'package:video_player/video_player.dart';
import '../../../../app_settings/app_colors.dart';
import '../../../../tools/titleAppBar.dart';
import 'videoLogDetail_logic.dart';
class VideoLogDetailPage extends StatefulWidget {
const VideoLogDetailPage({Key? key}) : super(key: key);
@override
State<VideoLogDetailPage> createState() => _VideoLogDetailPageState();
}
class _VideoLogDetailPageState extends State<VideoLogDetailPage> {
final VideoLogDetailLogic logic = Get.put(VideoLogDetailLogic());
final VideoLogDetailState state = Get.find<VideoLogDetailLogic>().state;
@override
void initState() {
super.initState();
state.videoController = VideoPlayerController.networkUrl(
Uri.parse(state.recordData.value.videoUrl!),
videoPlayerOptions: VideoPlayerOptions(mixWithOthers: true),
);
state.videoController.addListener(() {
setState(() {});
});
state.videoController.setLooping(false);
state.videoController.initialize();
}
void _initializeVideoPlayer(String videoUrl) async {
if (state.videoController != null) {
await state.videoController.dispose(); // 释放旧资源
}
state.videoController = VideoPlayerController.networkUrl(
Uri.parse(videoUrl),
videoPlayerOptions: VideoPlayerOptions(mixWithOthers: true),
);
// 初始化完成后通知框架重新构建界面
await state.videoController.initialize();
state.videoController.addListener(() {
setState(() {});
});
setState(() {});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: TitleAppBar(
barTitle: '视频播放'.tr,
haveBack: true,
backgroundColor: AppColors.mainColor,
),
body: state.videoController.value.isInitialized
? Column(
children: <Widget>[
Container(
color: Colors.black,
height: 500.h,
width: 1.sw,
child: Stack(
alignment: Alignment.bottomCenter,
children: <Widget>[
RotatedBox(
quarterTurns: -1,
child: AspectRatio(
aspectRatio: state.videoController.value.size.width /
state.videoController.value.size.height,
child: VideoPlayer(state.videoController),
),
),
ControlsOverlay(
controller: state.videoController,
recordData: state.recordData.value,
),
if (state.videoController.value.isPlaying ||
state.videoController.value.isBuffering)
Container()
else
VideoProgressIndicator(
state.videoController,
colors: VideoProgressColors(
playedColor: AppColors.mainColor),
allowScrubbing: true,
),
],
),
),
_buildOther(),
],
)
: Center(
child: CircularProgressIndicator(),
),
);
}
double itemW = (1.sw - 15.w * 4) / 3;
double itemH = (1.sw - 15.w * 4) / 3 + 40.h;
Widget videoItem(RecordListData recordData) {
return GestureDetector(
onTap: () {
if (recordData.videoUrl != null && recordData.videoUrl!.isNotEmpty) {
state.recordData.value = recordData;
_initializeVideoPlayer(recordData.videoUrl!);
setState(() {});
} else if (recordData.imagesUrl != null &&
recordData.imagesUrl!.isNotEmpty) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => FullScreenImagePage(
imageUrl: recordData.imagesUrl!,
),
),
);
}
},
child: SizedBox(
width: itemW,
height: itemH,
child: Column(
children: <Widget>[
Container(
width: itemW,
height: itemW,
margin: const EdgeInsets.all(0),
color: Colors.white,
child: ClipRRect(
borderRadius: BorderRadius.circular(10.w),
child: _buildImageOrVideoItem(recordData),
),
),
],
),
),
);
}
_buildImageOrVideoItem(RecordListData recordData) {
if (recordData.videoUrl != null && recordData.videoUrl!.isNotEmpty) {
return _buildVideoItem(recordData);
} else {
return _buildImageItem(recordData);
}
}
_buildVideoItem(RecordListData recordData) {
return VideoThumbnailImage(videoUrl: recordData.videoUrl!);
}
_buildImageItem(RecordListData recordData) {
return RotatedBox(
quarterTurns: -1,
child: Image.network(
recordData.imagesUrl!,
fit: BoxFit.cover,
errorBuilder:
(BuildContext context, Object error, StackTrace? stackTrace) {
// 图片加载失败时显示错误图片
return RotatedBox(
quarterTurns: -1,
child: Image.asset(
'images/icon_unHaveData.png', // 错误图片路径
fit: BoxFit.cover,
),
);
},
),
);
}
String formatString(time) {
String shortName = time.toString().substring(2, 7);
return shortName;
}
@override
void dispose() {
super.dispose();
state.videoController.dispose();
}
_buildOther() {
return Expanded(
child: ListView.builder(
itemCount: state.videoLogList.length,
itemBuilder: (BuildContext c, int index) {
CloudStorageData item = state.videoLogList[index];
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
margin: EdgeInsets.only(left: 20.w, top: 15.w, bottom: 15.w),
child: Row(
children: <Widget>[
Text(item.date ?? '', style: TextStyle(fontSize: 20.sp)),
],
),
),
mainListView(index, item),
],
);
},
),
);
}
Widget mainListView(int index, CloudStorageData itemData) {
return GridView.builder(
itemCount: itemData.recordList!.length,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
//横轴元素个数
crossAxisCount: 3,
),
itemBuilder: (BuildContext context, int index) {
return _buildItem(itemData.recordList![index]);
},
);
}
_buildItem(itemData) {
return videoItem(itemData);
}
}