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 createState() => _VideoLogDetailPageState(); } class _VideoLogDetailPageState extends State { final VideoLogDetailLogic logic = Get.put(VideoLogDetailLogic()); final VideoLogDetailState state = Get.find().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: [ Container( color: Colors.black, height: 500.h, width: 1.sw, child: Stack( alignment: Alignment.bottomCenter, children: [ 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: [ 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: [ Container( margin: EdgeInsets.only(left: 20.w, top: 15.w, bottom: 15.w), child: Row( children: [ 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); } }