当前位置: 首页 > news >正文

Flutter 仿抖音 TikTok 上下滑动 播放视频

Flutter 仿抖音 TikTok 上下滑动 播放视频UI框架,视频播放使用 video_player

github:GitHub - PangHaHa12138/TiktokVideo: Flutter 仿抖音 TikTok 上下滑动 播放视频UI框架

实现功能:

1.上下滑动自动播放切换视频,loading 封面图占位

2.全屏播放横竖屏切换

3.播放进度条显示

4.仿抖音评论弹窗

效果图:

001.jpg

002.jpg

003.jpg

004.jpg

005.jpg

上代码:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:video_player/video_player.dart';class VideoPage extends StatefulWidget {const VideoPage({Key? key}) : super(key: key);@overrideState createState() => _VideoPageState();
}class _VideoPageState extends State<VideoPage> {late PageController _pageController;int currentPageIndex = 0; //当前播放索引int currentIndex = 0; //当前播放索引List<VideoData> videoDataList = []; //视频数据列表List<VideoType> videoTypeList = []; //视频分类数据列表@overridevoid initState() {loadData(false);loadVideoType();_pageController = PageController(initialPage: currentIndex);_pageController.addListener(_onPageScroll);super.initState();}void _onPageScroll() {final pageIndex = _pageController.page?.round();if (pageIndex != null && pageIndex != currentPageIndex) {currentPageIndex = pageIndex;print('=========> currentPageIndex: ${currentPageIndex}');if (currentPageIndex == videoDataList.length - 2) {loadData(true);}}}/// 视频数据 API请求Future<void> loadData(bool isLoadMore) async {// 延迟200ms 模拟网络请求await Future.delayed(const Duration(milliseconds: 200));if (isLoadMore) {print('=========> loadData');List<VideoData> newVideoDataList = [];newVideoDataList.clear();newVideoDataList.addAll(videoDataList);newVideoDataList.addAll(testVideoData);setState(() {videoDataList = newVideoDataList;});} else {setState(() {videoDataList = testVideoData;});}}/// 视频类型 API请求Future<void> loadVideoType() async {// 延迟200ms 模拟网络请求await Future.delayed(const Duration(milliseconds: 200));videoTypeList = testVideoType;setState(() {});}@overridevoid dispose() {_pageController.removeListener(_onPageScroll);_pageController.dispose();super.dispose();}@overrideWidget build(BuildContext context) {var size = MediaQuery.of(context).size;return Scaffold(resizeToAvoidBottomInset: false, //很重要,不加键盘弹出视频会被挤压body: Stack(children: [PageView.builder(scrollDirection: Axis.vertical,itemCount: videoDataList.length,controller: _pageController,onPageChanged: (currentPage) {//页面发生改变的回调},itemBuilder: (context, index) {return VideoPlayerFullPage(size: size,videoData: videoDataList[index],videoTypes: videoTypeList,);},),header(context,videoTypeList,),],));}Widget header(BuildContext context, List<VideoType> videoTypes) {var size = MediaQuery.of(context).size;return Padding(padding: const EdgeInsets.only(left: 15, top: 10, bottom: 10),child: SafeArea(child: Column(children: [Row(children: [IconButton(icon: const Icon(Icons.arrow_back_ios_new,color: Colors.white,),onPressed: () {if (Navigator.canPop(context)) {Navigator.pop(context);}}),GestureDetector(onTap: () {onSearchClick();},child: Container(width: size.width - 100,padding: const EdgeInsets.only(left: 15, right: 15, top: 5, bottom: 5),decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.0),color: const Color(0x80444444),),child: Row(children: const [Icon(Icons.search,color: Colors.white,),SizedBox(width: 5,),Text('搜索社群',style: TextStyle(color: Colors.white,fontSize: 15,),),],),),),],),const SizedBox(height: 10),Wrap(spacing: 8.0, // 主轴(水平)方向间距runSpacing: 2.0, // 纵轴(垂直)方向间距children: videoTypes.map((item) {return GestureDetector(onTap: () {onVideoTypesClick(item);},child: Container(padding: const EdgeInsets.only(left: 12, right: 12, top: 4, bottom: 4),decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.0), // 设置圆角color: const Color(0xFF69DCE5), // 设置背景颜色),child: Text(item.typeName,style: const TextStyle(color: Colors.white,fontSize: 12,),textAlign: TextAlign.center,),),);}).toList(),),],),),);}/// 顶部视频类型 点击Future<void> onVideoTypesClick(VideoType videoType) async {print('=====> 点击了视频类型');}/// 搜索点击Future<void> onSearchClick() async {print('=====> 点击了搜索');}
}class VideoPlayerFullPage extends StatefulWidget {final List<VideoType> videoTypes; //视频顶部分类final VideoData? videoData;const VideoPlayerFullPage({Key? key,required this.size,required this.videoTypes,required this.videoData,}) : super(key: key);final Size size;@overrideState createState() => _VideoPlayerFullPageState();
}class _VideoPlayerFullPageState extends State<VideoPlayerFullPage> {late VideoPlayerController videoController;bool isInitPlaying = false;bool isBuffering = false;List<CommentData> comments = []; //评论数据列表double videoWidth = 0;double videoHeight = 0;double _currentSliderValue = 0.0;@overridevoid initState() {videoController = VideoPlayerController.network(widget.videoData!.videoUrl)..initialize().then((value) {videoController.play();videoController.setLooping(true);setState(() {_currentSliderValue = 0.0;isInitPlaying = true;videoWidth = videoController.value.size.width;videoHeight = videoController.value.size.height;});});videoController.addListener(videoListener);super.initState();}void videoListener() {setState(() {isBuffering = videoController.value.isBuffering;_currentSliderValue = videoController.value.position.inSeconds.toDouble();});}@overridevoid dispose() {videoController.removeListener(videoListener);videoController.dispose();super.dispose();}/// 底部视频话题 点击Future<void> onVideoTagsClick(VideoTag videoTag) async {print('=====> 点击了视频话题');}///点赞Future<void> onLikeClick(VideoData videoData) async {print('=====> 点击了点赞');}///评论Future<void> onCommentClick(BuildContext context, VideoData videoData) async {print('=====> 点击了评论');// 延迟200ms 模拟网络请求await Future.delayed(const Duration(milliseconds: 200));comments = testCommentData;showCommentBottomSheet(context, comments, videoData);}///观看人数Future<void> onWatchClick(VideoData videoData) async {print('=====> 点击了观看人数');}///分享Future<void> onShareClick(VideoData videoData) async {print('=====> 点击了分享');}///加好友Future<void> onAddFriendClick(VideoData videoData) async {print('=====> 点击了加好友');}///发布人名称点击Future<void> onUserNameClick(VideoData videoData) async {print('=====> 点击了发布人名称');}@overrideWidget build(BuildContext context) {return Container(color: Colors.grey,height: widget.size.height,width: widget.size.width,child: widget.videoData == null? Center(child: Container(width: 200,height: 200,decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.0),color: const Color(0x80444444),),child: Column(children: const [SizedBox(height: 20,),Icon(Icons.error_outline,size: 50,),SizedBox(height: 70,),Text('无数据',style: TextStyle(fontSize: 20, color: Colors.white),),],),),): GestureDetector(onTap: () {print('============>视频点击 ');setState(() {videoController.value.isPlaying? videoController.pause(): videoController.play();});},child: Container(height: widget.size.height,width: widget.size.width,decoration: const BoxDecoration(color: Colors.black),child: Stack(children: <Widget>[videoWidth > videoHeight? Center(child: AspectRatio(aspectRatio: videoController.value.aspectRatio,child: VideoPlayer(videoController),),): AspectRatio(aspectRatio: videoController.value.aspectRatio,child: VideoPlayer(videoController),),Center(child: !videoController.value.isPlaying && !isInitPlaying? Image.network(widget.videoData!.albumImg,width: widget.size.width,height: widget.size.height,fit: BoxFit.cover,): const SizedBox(),),Center(child: Container(decoration: const BoxDecoration(),child: isPlaying(),),),isBuffering || !videoController.value.isInitialized? const Center(child: SizedBox(width: 40,height: 40,child: CircularProgressIndicator(color: Color(0xFF69DCE5),),),): const SizedBox(),Padding(padding:const EdgeInsets.only(left: 0, top: 10, bottom: 10),child: SafeArea(child: Column(mainAxisAlignment: MainAxisAlignment.spaceBetween,children: <Widget>[Expanded(child: Row(children: <Widget>[bottomPanel(widget.size,widget.videoData!,),rightPanel(context,widget.size,widget.videoData!,)],),),SizedBox(height: 10,child: SliderTheme(data: SliderTheme.of(context).copyWith(trackHeight: 3, // 轨道高度trackShape:const RoundedRectSliderTrackShape(), // 轨道形状,可以自定义activeTrackColor:const Color(0xFF444444), // 激活的轨道颜色inactiveTrackColor:const Color(0x80444444), // 未激活的轨道颜色thumbColor: const Color(0xFF999999), // 滑块颜色thumbShape: const RoundSliderThumbShape(//  滑块形状,可以自定义enabledThumbRadius: 4 // 滑块大小),overlayShape: const RoundSliderOverlayShape(overlayRadius: 10, // 设置滑块的覆盖层半径),),child: Slider(value: _currentSliderValue,min: 0.0,max: videoController.value.duration.inSeconds.toDouble(),onChanged: (value) {setState(() {_currentSliderValue = value;videoController.seekTo(Duration(seconds: value.toInt()));});},),),),],),),),videoWidth > videoHeight? GestureDetector(onTap: () {Navigator.push(context,MaterialPageRoute(builder: (context) => FullScreenVideoPage(videoController: videoController)),);},child: Padding(padding:const EdgeInsets.only(top: 500, left: 150),child: SizedBox(width: 110,height: 40,child: Container(decoration: BoxDecoration(borderRadius:BorderRadius.circular(20.0),color: const Color(0x80444444),),child: Row(mainAxisAlignment:MainAxisAlignment.spaceBetween,children: const [SizedBox(width: 3,),Icon(Icons.fullscreen,color: Colors.white,),Text('全屏观看',style: TextStyle(fontSize: 14,color: Colors.white,),),SizedBox(width: 3,),],)),))): const SizedBox(),],),),),);}Widget isPlaying() {if (videoController.value.isInitialized) {return videoController.value.isPlaying? const SizedBox(): Image.asset('assets/images/icon_play.png',width: 80,height: 80,);} else {return const SizedBox();}}String _formatDuration(Duration duration) {return '${duration.inMinutes.remainder(60).toString().padLeft(2, '0')}:${(duration.inSeconds % 60).toString().padLeft(2, '0')}';}Widget bottomPanel(Size size, VideoData videoData) {return Container(width: size.width * 0.8,height: size.height,padding: const EdgeInsets.only(left: 15),decoration: const BoxDecoration(),child: Column(mainAxisAlignment: MainAxisAlignment.end,crossAxisAlignment: CrossAxisAlignment.start,children: <Widget>[GestureDetector(onTap: () {onUserNameClick(videoData);},child: Text('@${videoData.userName}',style: const TextStyle(color: Colors.white,fontWeight: FontWeight.bold,fontSize: 18),),),const SizedBox(height: 10,),Container(margin: const EdgeInsets.only(right: 30),child: Row(children: [videoData.type == "1"? Container(padding: const EdgeInsets.only(left: 4, right: 4, top: 2, bottom: 2),decoration: BoxDecoration(borderRadius: BorderRadius.circular(3.0), // 设置圆角color: const Color(0xFF8B452B), // 设置背景颜色),child: const Text('精',style: TextStyle(color: Color(0xFFF47947),fontSize: 13,fontWeight: FontWeight.bold,),textAlign: TextAlign.center,),): const SizedBox(),const SizedBox(width: 10,),Text(videoData.title,style: const TextStyle(color: Colors.white,fontSize: 16,fontWeight: FontWeight.bold,),),Text('  ·  ${videoData.time}',style: const TextStyle(color: Colors.grey,fontSize: 13,),),],),),const SizedBox(height: 5,),Container(margin: const EdgeInsets.only(right: 30),child: Text(videoData.description,style: const TextStyle(color: Colors.white,fontSize: 14,),),),const SizedBox(height: 10,),Wrap(spacing: 8.0, // 主轴(水平)方向间距runSpacing: 2.0, // 纵轴(垂直)方向间距children: videoData.videoTags.map((item) {return GestureDetector(onTap: () {onVideoTagsClick(item);},child: Container(padding: const EdgeInsets.only(left: 6, right: 6, top: 3, bottom: 3),decoration: BoxDecoration(borderRadius: BorderRadius.circular(20.0), // 设置圆角color: const Color(0xFF69DCE5), // 设置背景颜色),child: Text('#${item.tagName}',style: const TextStyle(color: Colors.white,fontSize: 12,),textAlign: TextAlign.center,),),);}).toList(),),const SizedBox(height: 10,),],),);}Widget rightPanel(BuildContext context, Size size, VideoData videoData) {return Expanded(child: SizedBox(height: size.height,child: Column(children: <Widget>[Container(height: size.height * 0.4,),Expanded(child: Column(mainAxisAlignment: MainAxisAlignment.spaceBetween,children: <Widget>[getProfile(videoData),getLike(videoData, 25.0),getComment(context, videoData, 25.0),getWatch(videoData, 25.0),getShare(videoData, 25.0),const SizedBox(height: 60,),],))],),),);}Widget getLike(VideoData videoData, double size) {return GestureDetector(onTap: () {onLikeClick(videoData);},child: Column(children: <Widget>[videoData.likeStatus == "1"?//已点赞Image.asset('assets/images/icon_like.png',width: size,height: size,)//未点赞: Image.asset('assets/images/icon_like.png',width: size,height: size,),const SizedBox(height: 5,),Text(videoData.likes,style: const TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.w700),)],),);}Widget getComment(BuildContext context, VideoData videoData, double size) {return GestureDetector(onTap: () {onCommentClick(context, videoData);},child: Column(children: <Widget>[Image.asset('assets/images/icon_comment.png',width: size,height: size,),const SizedBox(height: 5,),Text(videoData.comments,style: const TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.w700),)],),);}Widget getWatch(VideoData videoData, double size) {return GestureDetector(onTap: () {onWatchClick(videoData);},child: Column(children: <Widget>[Image.asset('assets/images/icon_watch.png',width: size,height: size,),const SizedBox(height: 5,),Text(videoData.watchers,style: const TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.w700),)],),);}Widget getShare(VideoData videoData, double size) {return GestureDetector(onTap: () {onShareClick(videoData);},child: Column(children: <Widget>[Image.asset('assets/images/icon_share.png',width: size,height: size,),const SizedBox(height: 5,),Text(videoData.shares,style: const TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.w700),)],),);}Widget getProfile(VideoData videoData) {return GestureDetector(onTap: () {onAddFriendClick(videoData);},child: SizedBox(width: 50,height: 60,child: Stack(children: <Widget>[Container(width: 50,height: 50,decoration: BoxDecoration(border: Border.all(color: Colors.white),shape: BoxShape.circle,image: DecorationImage(image: NetworkImage(videoData.userAvatarUrl),fit: BoxFit.cover)),),Positioned(bottom: 3,left: 18,child: Container(width: 20,height: 20,decoration: const BoxDecoration(shape: BoxShape.circle, color: Color(0xFF69DCE5)),child: const Center(child: Icon(Icons.add,color: Colors.white,size: 15,)),))],),),);}void showCommentBottomSheet(BuildContext context, List<CommentData> comments,VideoData videoData) async {await showModalBottomSheet(context: context,shape: const RoundedRectangleBorder(borderRadius: BorderRadius.vertical(top: Radius.circular(20)),),enableDrag: true,isScrollControlled: true,builder: (_) => CommentBottomSheet(commentData: comments,videoData: videoData,),);}
}class CommentBottomSheet extends StatefulWidget {final List<CommentData> commentData;final VideoData videoData;const CommentBottomSheet({Key? key,required this.commentData,required this.videoData,}) : super(key: key);@overrideState<CommentBottomSheet> createState() => _CommentsBottomSheetState();
}class _CommentsBottomSheetState extends State<CommentBottomSheet> {List<CommentData> comments = [];VideoData? videoData;TextEditingController textEditingController = TextEditingController();FocusNode focusNode = FocusNode();String hint = "写评论";@overridevoid initState() {comments = widget.commentData;videoData = widget.videoData;super.initState();}/// 发送评论onSendComment(String input) {print('========> 发送评论:$input');}/// 点赞评论onLikeComment(CommentData commentData) {print('========> 点赞评论');}/// 回复评论onReplayComment(CommentData commentData) {print('========> 回复评论');}/// 回复评论中的回复onReplayCommentReplay(CommentData commentData, CommentData replayComment) {print('========> 回复评论中的回复');}/// 查看全部评论onWatchAllComment(CommentData commentData) {print('========> 查看全部评论');for (int i = 0; i < comments.length; i++) {}}/// 底部输入框 点赞onBottomLike() {print('========> 底部输入框 点赞');}/// 底部输入框 分享onBottomShare() {print('========> 底部输入框 分享');}/// 底部输入框 收藏onBottomFavorite() {print('========> 底部输入框 收藏');}/// 底部输入框 评论onBottomComment() {print('========> 底部输入框 评论');}@overrideWidget build(BuildContext context) {return SizedBox(height: 500,child: Stack(children: [// 评论列表Padding(padding: const EdgeInsets.only(top: 60, bottom: 70),child: ListView.builder(shrinkWrap: true,itemCount: comments.length,itemBuilder: (BuildContext context, int index) {return CommentItem(comments[index], comments, index);},),),Align(alignment: Alignment.topCenter,child: // 评论数Container(padding: const EdgeInsets.only(top: 16, left: 16, right: 16, bottom: 0),decoration: BoxDecoration(borderRadius: BorderRadius.circular(15),color: Colors.white,),child: Column(mainAxisSize: MainAxisSize.min,children: [Row(mainAxisAlignment: MainAxisAlignment.start,children: <Widget>[Text('${comments.length}条评论',style:const TextStyle(fontSize: 15, color: Colors.grey),),],),const SizedBox(height: 15,),Container(margin: const EdgeInsets.only(left: 16, right: 16),child: const Divider(height: 1,color: Colors.grey,),)],),),),Align(alignment: Alignment.bottomCenter,child: // 输入框和操作栏Container(color: Colors.white,padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),margin: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),child: Row(children: [Flexible(child: TextField(controller: textEditingController,focusNode: focusNode,onSubmitted: submitComment,onEditingComplete: () {submitComment(textEditingController.text);},keyboardType: TextInputType.multiline,maxLines: null,textInputAction: TextInputAction.send,decoration: InputDecoration(hintText: hint,filled: true,isDense: true,border: OutlineInputBorder(borderRadius: BorderRadius.circular(20),borderSide: BorderSide.none,),),),),const SizedBox(width: 4),SizedBox(width: 40,child: GestureDetector(onTap: () {onBottomFavorite();},child: Column(mainAxisSize: MainAxisSize.min,children: [const Icon(Icons.star_border,color: Color(0xFF9F9F9F),),Text('${videoData?.favorites}',style: const TextStyle(color: Color(0xFF9F9F9F),fontSize: 12,),),],)),),SizedBox(width: 40,child: GestureDetector(onTap: () {onBottomShare();},child: Column(mainAxisSize: MainAxisSize.min,children: [const Icon(Icons.ios_share_outlined,color: Color(0xFF9F9F9F),),Text('${videoData?.shares}',style: const TextStyle(color: Color(0xFF9F9F9F),fontSize: 12,),),],)),),SizedBox(width: 40,child: GestureDetector(onTap: () {onBottomComment();},child: Column(mainAxisSize: MainAxisSize.min,children: [const Icon(Icons.comment_outlined,color: Color(0xFF9F9F9F),),Text('${videoData?.comments}',style: const TextStyle(color: Color(0xFF9F9F9F),fontSize: 12,),),],)),),SizedBox(width: 40,child: GestureDetector(onTap: () {onBottomLike();},child: Column(mainAxisSize: MainAxisSize.min,children: [const Icon(Icons.thumb_up_alt_outlined,color: Color(0xFF9F9F9F),),Text('${videoData?.likes}',style: const TextStyle(color: Color(0xFF9F9F9F),fontSize: 12,),),],)),),],),),),],),);}void submitComment(String inputText) {if (textEditingController.text.isEmpty) return;onSendComment(textEditingController.text);textEditingController.clear();hint = '写评论';focusNode.unfocus();}Widget CommentItem(CommentData commentData, List<CommentData> comments, int index) {var size = MediaQuery.of(context).size;return Container(color: Colors.white,padding: const EdgeInsets.all(16),child: Column(crossAxisAlignment: CrossAxisAlignment.center,children: <Widget>[Row(mainAxisAlignment: MainAxisAlignment.start,crossAxisAlignment: CrossAxisAlignment.start,children: <Widget>[Container(width: 45,height: 45,decoration: BoxDecoration(border: Border.all(color: Colors.white),shape: BoxShape.circle,image: DecorationImage(image: NetworkImage(commentData.userAvatarUrl),fit: BoxFit.cover)),),const SizedBox(width: 10),Column(crossAxisAlignment: CrossAxisAlignment.start,children: <Widget>[Row(mainAxisAlignment: MainAxisAlignment.spaceAround,children: [Column(crossAxisAlignment: CrossAxisAlignment.start,children: [Text(commentData.userName,style: const TextStyle(fontSize: 18, color: Colors.black),),const SizedBox(height: 2),Text(commentData.time,style: const TextStyle(fontSize: 12, color: Colors.grey),),],),const SizedBox(width: 120),// 点赞数量GestureDetector(onTap: () {onLikeComment(commentData);},child: Row(mainAxisAlignment: MainAxisAlignment.end,children: [commentData.likeStatus == "1"? const Icon(Icons.thumb_up,color: Color(0xFF67DCE7),): const Icon(Icons.thumb_up_off_alt_outlined,color: Colors.grey,),const SizedBox(width: 4),Text(commentData.likes,style: TextStyle(fontSize: 17,color: commentData.likeStatus == "1"? const Color(0xFF67DCE7): Colors.grey,),),],),),],),const SizedBox(height: 10),Row(crossAxisAlignment: CrossAxisAlignment.start,children: [commentData.type == "1"? Container(padding: const EdgeInsets.only(left: 4, right: 4, top: 2, bottom: 2),decoration: BoxDecoration(borderRadius:BorderRadius.circular(3.0), // 设置圆角color: const Color(0xFFFFF0EC), // 设置背景颜色),child: const Text('精',style: TextStyle(color: Color(0xFFED7F55),fontSize: 13,fontWeight: FontWeight.bold,),textAlign: TextAlign.center,),): const SizedBox(),const SizedBox(width: 5,),GestureDetector(onTap: () {setState(() {hint = "回复 ${commentData.userName} : ";});FocusScope.of(context).requestFocus(focusNode);onReplayComment(commentData);},child: SizedBox(width: size.width - 148,child: Text(commentData.content,style: const TextStyle(fontSize: 17,color: Colors.black,),),),),const SizedBox(width: 30),],),const SizedBox(height: 8),// 回复内容Container(padding: const EdgeInsets.all(8),decoration: BoxDecoration(borderRadius: BorderRadius.circular(5.0), // 设置圆角color: const Color(0xFFF3F3F3),),child: Column(mainAxisAlignment: MainAxisAlignment.start,crossAxisAlignment: CrossAxisAlignment.start,children: <Widget>[...List.generate(commentData.replayList.length,(index) => ReplyItem(commentData,commentData.replayList[index], size.width),),const SizedBox(height: 5,),// 查看全部回复GestureDetector(onTap: () {// 处理查看全部回复逻辑onWatchAllComment(commentData);},child: Row(children: [Text('全部${commentData.replayList.length}条回复',style: const TextStyle(color: Colors.black, fontSize: 15),),const Icon(Icons.arrow_forward_ios_rounded,size: 15, color: Colors.black),],)),],),),],),],),index == comments.length - 1? Container(margin: const EdgeInsets.only(top: 10),child: const Text('- 没有更多了哦 -',style: TextStyle(fontSize: 14,color: Colors.grey,fontWeight: FontWeight.bold),),): const SizedBox(),],),);}Widget ReplyItem(CommentData commentData, CommentData replayComment, double width) {return GestureDetector(onTap: () {setState(() {hint = "回复 ${replayComment.userName} : ";});FocusScope.of(context).requestFocus(focusNode);onReplayCommentReplay(commentData, replayComment);},child: SizedBox(width: width - 120,child: RichText(text: TextSpan(children: [TextSpan(text: replayComment.userName,style: const TextStyle(color: Color(0xFF67DCE7),fontSize: 14,),),const TextSpan(text: ' 回复 ',style: TextStyle(fontSize: 14,color: Color(0xFF707070),),),TextSpan(text: replayComment.replayName,style: const TextStyle(color: Color(0xFF67DCE7),fontSize: 14,),),TextSpan(text: ' : ${replayComment.replayContent}',style: const TextStyle(color: Color(0xFF707070),fontSize: 14,),),],),),),);}
}class FullScreenVideoPage extends StatefulWidget {final VideoPlayerController videoController;const FullScreenVideoPage({Key? key, required this.videoController}): super(key: key);@override_FullScreenVideoPageState createState() => _FullScreenVideoPageState();
}class _FullScreenVideoPageState extends State<FullScreenVideoPage> {double _currentSliderValue = 0.0;bool isBuffering = false;bool isInitPlaying = false;@overridevoid initState() {super.initState();SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft,]);setState(() {_currentSliderValue = 0.0;isInitPlaying = true;});widget.videoController.addListener(videoListener);}void videoListener() {setState(() {isBuffering = widget.videoController.value.isBuffering;_currentSliderValue =widget.videoController.value.position.inSeconds.toDouble();});}@overridevoid dispose() {widget.videoController.removeListener(videoListener);super.dispose();}Widget isPlaying() {if (widget.videoController.value.isInitialized) {return widget.videoController.value.isPlaying? const SizedBox(): Image.asset('assets/images/icon_play.png',width: 80,height: 80,);} else {return const SizedBox();}}@overrideWidget build(BuildContext context) {return WillPopScope(child: Scaffold(backgroundColor: Colors.black,body: GestureDetector(onTap: () {setState(() {widget.videoController.value.isPlaying? widget.videoController.pause(): widget.videoController.play();});},child: Stack(children: [VideoPlayer(widget.videoController),Padding(padding: const EdgeInsets.only(top: 25, right: 20),child: IconButton(icon: const Icon(Icons.close,size: 30,),color: Colors.white,onPressed: () {SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp,]);Navigator.pop(context);},),),Center(child: Container(decoration: const BoxDecoration(),child: isPlaying(),),),isBuffering || !widget.videoController.value.isInitialized? const Center(child: SizedBox(width: 50,height: 50,child: CircularProgressIndicator(color: Color(0xFF69DCE5),),),): const SizedBox(),Align(alignment: Alignment.bottomCenter,child: Container(margin: const EdgeInsets.only(bottom: 10),height: 10,child: SliderTheme(data: SliderTheme.of(context).copyWith(trackHeight: 3, // 轨道高度trackShape:const RoundedRectSliderTrackShape(), // 轨道形状,可以自定义activeTrackColor: const Color(0xFF444444), // 激活的轨道颜色inactiveTrackColor: const Color(0x80444444),thumbColor: const Color(0xFF999999), // 未激活的轨道颜色thumbShape: const RoundSliderThumbShape(//  滑块形状,可以自定义enabledThumbRadius: 4 // 滑块大小),overlayShape: const RoundSliderOverlayShape(overlayRadius: 10, // 设置滑块的覆盖层半径),),child: Slider(value: _currentSliderValue,min: 0.0,max: widget.videoController.value.duration.inSeconds.toDouble(),onChanged: (value) {setState(() {_currentSliderValue = value;widget.videoController.seekTo(Duration(seconds: value.toInt()));});},),),),),],),),),onWillPop: () async {SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp,]);Navigator.pop(context);return false;});}
}class VideoData {final String id; // 唯一idfinal String uid; // 发布人 uidfinal String type; //type = 1 视频加 精final String videoUrl; //视频地址final String albumImg; //视频第一帧封面final String userName; //发布者名final String userAvatarUrl; //发布者头像final String description; //视频描述final String title; //视频标题final String likes; //视频点赞数final String likeStatus; //0未点赞 1 已点赞final String comments; //视频评论数final String shares; //视频分享数final String watchers; //视频观看数final String favorites; //视频收藏数final String time; //视频发布时间final List<VideoTag> videoTags; //视频关联话题VideoData({required this.id,required this.uid,required this.type,required this.videoUrl,required this.albumImg,required this.userName,required this.userAvatarUrl,required this.description,required this.title,required this.likes,required this.likeStatus,required this.comments,required this.shares,required this.watchers,required this.favorites,required this.time,required this.videoTags,});
}class VideoTag {final String tagId; //视频关联话题idfinal String tagName; //视频关联话题名VideoTag({required this.tagId,required this.tagName,});
}class VideoType {final String typeId; //视频分类idfinal String typeName; //视频分类名VideoType({required this.typeId,required this.typeName,});
}class CommentData {final String id; // 唯一idfinal String uid; // 评论用户uidfinal String userName; // 评论用户uidfinal String userAvatarUrl; // 评论用户uidfinal String time; // 发布评论时间final String type; //type = 1 评论加 精final String content; //评论文案final String likes; //评论点赞数final String likeStatus; //0未点赞 1 已点赞final String replayName; //被回复者final String replayUid; //被回复者 uidfinal String replayContent; //回复内容final List<CommentData> replayList;CommentData({required this.id,required this.uid,required this.userName,required this.userAvatarUrl,required this.time,required this.type,required this.content,required this.likes,required this.likeStatus,required this.replayName,required this.replayUid,required this.replayContent,required this.replayList,});
}/// 测试数据List<CommentData> testCommentData = <CommentData>[CommentData(id: "2524525",uid: "5254453",userName: "晴子",userAvatarUrl:"https://p16-tiktokcdn-com.akamaized.net/aweme/720x720/tiktok-obj/1663771856684033.jpeg",time: "2023/01/17 14:30:22",type: "1",content: "有情趣又热爱生活的人真好有情趣又热爱生活",likes: "100",likeStatus: "1",replayName: "虾仁",replayUid: "11111",replayContent: "奔驰发布全新旅行车更适合大家出行要不要试驾",replayList: [CommentData(id: "2545",uid: "11541",userName: "用户1",userAvatarUrl:"https://p16-tiktokcdn-com.akamaized.net/aweme/720x720/tiktok-obj/1663771856684033.jpeg",time: "2023/01/17 14:30:22",type: "1",content: "有情趣又热爱生活的人真好有情趣又热爱生活",likes: "100",likeStatus: "0",replayName: "虾仁",replayUid: "11111",replayContent: "奔驰发布全新旅行车更适合大家出行要不要试驾",replayList: [],),CommentData(id: "5383",uid: "57225",userName: "用户2",userAvatarUrl:"https://p16-tiktokcdn-com.akamaized.net/aweme/720x720/tiktok-obj/1663771856684033.jpeg",time: "2023/01/17 14:30:22",type: "1",content: "有情趣又热爱生活的人真好有情趣又热爱生活",likes: "100",likeStatus: "0",replayName: "虾仁",replayUid: "11111",replayContent: "奔驰发布全新旅行车更适合大家出行要不要试驾",replayList: [],),CommentData(id: "42458",uid: "245454",userName: "用户3",userAvatarUrl:"https://p16-tiktokcdn-com.akamaized.net/aweme/720x720/tiktok-obj/1663771856684033.jpeg",time: "2023/01/17 14:30:22",type: "1",content: "有情趣又热爱生活的人真好有情趣又热爱生活",likes: "100",likeStatus: "0",replayName: "虾仁",replayUid: "11111",replayContent: "奔驰发布全新旅行车更适合大家出行要不要试驾",replayList: [],),],),CommentData(id: "56535",uid: "52482",userName: "虾仁",userAvatarUrl:"https://p16-tiktokcdn-com.akamaized.net/aweme/720x720/tiktok-obj/1663771856684033.jpeg",time: "2023/01/17 14:30:22",type: "1",content: "有情趣又热爱生活的人真好有情趣又热爱生活",likes: "100",likeStatus: "0",replayName: "虾仁",replayUid: "11111",replayContent: "奔驰发布全新旅行车更适合大家出行要不要试驾",replayList: [CommentData(id: "5353",uid: "24535",userName: "用户4",userAvatarUrl:"https://p16-tiktokcdn-com.akamaized.net/aweme/720x720/tiktok-obj/1663771856684033.jpeg",time: "2023/01/17 14:30:22",type: "1",content: "有情趣又热爱生活的人真好有情趣又热爱生活",likes: "100",likeStatus: "0",replayName: "虾仁",replayUid: "11111",replayContent: "奔驰发布全新旅行车更适合大家出行要不要试驾",replayList: [],),CommentData(id: "5355",uid: "35434",userName: "用户5",userAvatarUrl:"https://p16-tiktokcdn-com.akamaized.net/aweme/720x720/tiktok-obj/1663771856684033.jpeg",time: "2023/01/17 14:30:22",type: "1",content: "有情趣又热爱生活的人真好有情趣又热爱生活",likes: "100",likeStatus: "0",replayName: "虾仁",replayUid: "11111",replayContent: "奔驰发布全新旅行车更适合大家出行要不要试驾",replayList: [],),CommentData(id: "5452",uid: "35572",userName: "用户6",userAvatarUrl:"https://p16-tiktokcdn-com.akamaized.net/aweme/720x720/tiktok-obj/1663771856684033.jpeg",time: "2023/01/17 14:30:22",type: "1",content: "有情趣又热爱生活的人真好有情趣又热爱生活",likes: "100",likeStatus: "0",replayName: "虾仁",replayUid: "11111",replayContent: "奔驰发布全新旅行车更适合大家出行要不要试驾",replayList: [],),],),CommentData(id: "87886",uid: "6765",userName: "晴子",userAvatarUrl:"https://p16-tiktokcdn-com.akamaized.net/aweme/720x720/tiktok-obj/1663771856684033.jpeg",time: "2023/01/17 14:30:22",type: "1",content: "有情趣又热爱生活的人真好有情趣又热爱生活",likes: "100",likeStatus: "0",replayName: "虾仁",replayUid: "11111",replayContent: "奔驰发布全新旅行车更适合大家出行要不要试驾",replayList: [CommentData(id: "8768",uid: "68737",userName: "用户7",userAvatarUrl:"https://p16-tiktokcdn-com.akamaized.net/aweme/720x720/tiktok-obj/1663771856684033.jpeg",time: "2023/01/17 14:30:22",type: "1",content: "有情趣又热爱生活的人真好有情趣又热爱生活",likes: "100",likeStatus: "0",replayName: "虾仁",replayUid: "11111",replayContent: "奔驰发布全新旅行车更适合大家出行要不要试驾",replayList: [],),CommentData(id: "68727",uid: "68778",userName: "用户8",userAvatarUrl:"https://p16-tiktokcdn-com.akamaized.net/aweme/720x720/tiktok-obj/1663771856684033.jpeg",time: "2023/01/17 14:30:22",type: "1",content: "有情趣又热爱生活的人真好有情趣又热爱生活",likes: "100",likeStatus: "0",replayName: "虾仁",replayUid: "11111",replayContent: "奔驰发布全新旅行车更适合大家出行要不要试驾",replayList: [],),CommentData(id: "12821",uid: "8755",userName: "用户9",userAvatarUrl:"https://p16-tiktokcdn-com.akamaized.net/aweme/720x720/tiktok-obj/1663771856684033.jpeg",time: "2023/01/17 14:30:22",type: "1",content: "有情趣又热爱生活的人真好有情趣又热爱生活",likes: "100",likeStatus: "0",replayName: "虾仁",replayUid: "11111",replayContent: "奔驰发布全新旅行车更适合大家出行要不要试驾",replayList: [],),],),
];List<VideoType> testVideoType = <VideoType>[VideoType(typeId: "1111", typeName: "热门"),VideoType(typeId: "1111", typeName: "分类一"),VideoType(typeId: "1111", typeName: "分类二"),VideoType(typeId: "1111", typeName: "分类三"),VideoType(typeId: "1111", typeName: "分类四"),
];List<VideoData> testVideoData = <VideoData>[VideoData(id: "111",uid: "1233",type: "1",videoUrl: "https://static.ybhospital.net/test-video-2.mp4",albumImg:"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fblog%2F202107%2F05%2F20210705100427_ee4b8.thumb.1000_0.jpg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1628415177&t=87962cc902fb5925da0a4d60d4c48ca9",userName: "发布人名称",userAvatarUrl:"https://p16-tiktokcdn-com.akamaized.net/aweme/720x720/tiktok-obj/1663771856684033.jpeg",description: "春日的暖阳,花开进度80%,准备和爱车路过全世界,感受独具魅力的岭南文化!",title: "视频标题",likes: "130",likeStatus: "1",comments: "186",shares: "135",watchers: "328",favorites: "636",time: "2023年12月16日",videoTags: [VideoTag(tagId: "1111", tagName: "今天去哪玩"),VideoTag(tagId: "1111", tagName: "南京车友圈"),VideoTag(tagId: "1111", tagName: "活动名称"),]),VideoData(id: "111",uid: "1233",type: "1",videoUrl: "https://static.ybhospital.net/test-video-3.mp4",albumImg:"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fblog%2F202107%2F05%2F20210705100427_ee4b8.thumb.1000_0.jpg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1628415177&t=87962cc902fb5925da0a4d60d4c48ca9",userName: "发布人名称",userAvatarUrl:"https://p16-tiktokcdn-com.akamaized.net/aweme/720x720/tiktok-obj/1663771856684033.jpeg",description: "春日的暖阳,花开进度80%,准备和爱车路过全世界,感受独具魅力的岭南文化!",title: "视频标题",likes: "130",likeStatus: "1",comments: "165",shares: "135",watchers: "320",favorites: "105",time: "2023年12月16日",videoTags: [VideoTag(tagId: "1111", tagName: "今天去哪玩"),VideoTag(tagId: "1111", tagName: "南京车友圈"),VideoTag(tagId: "1111", tagName: "活动名称"),]),VideoData(id: "111",uid: "1233",type: "1",videoUrl: "https://static.ybhospital.net/test-video-4.mp4",albumImg:"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fblog%2F202107%2F05%2F20210705100427_ee4b8.thumb.1000_0.jpg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1628415177&t=87962cc902fb5925da0a4d60d4c48ca9",userName: "发布人名称",userAvatarUrl:"https://p16-tiktokcdn-com.akamaized.net/aweme/720x720/tiktok-obj/1663771856684033.jpeg",description: "春日的暖阳,花开进度80%,准备和爱车路过全世界,感受独具魅力的岭南文化!",title: "视频标题",likes: "150",likeStatus: "1",comments: "185",shares: "136",watchers: "280",favorites: "500",time: "2023年12月16日",videoTags: [VideoTag(tagId: "1111", tagName: "今天去哪玩"),VideoTag(tagId: "1111", tagName: "南京车友圈"),VideoTag(tagId: "1111", tagName: "活动名称"),]),VideoData(id: "111",uid: "1233",type: "1",videoUrl: "https://static.ybhospital.net/test-video-5.mp4",albumImg:"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fblog%2F202107%2F05%2F20210705100427_ee4b8.thumb.1000_0.jpg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1628415177&t=87962cc902fb5925da0a4d60d4c48ca9",userName: "发布人名称",userAvatarUrl:"https://p16-tiktokcdn-com.akamaized.net/aweme/720x720/tiktok-obj/1663771856684033.jpeg",description: "春日的暖阳,花开进度80%,准备和爱车路过全世界,感受独具魅力的岭南文化!",title: "视频标题",likes: "365",likeStatus: "1",comments: "425",shares: "253",watchers: "854",favorites: "524",time: "2023年12月16日",videoTags: [VideoTag(tagId: "1111", tagName: "今天去哪玩"),VideoTag(tagId: "1111", tagName: "南京车友圈"),VideoTag(tagId: "1111", tagName: "活动名称"),]),VideoData(id: "111",uid: "1233",type: "1",videoUrl: "https://static.ybhospital.net/test-video-6.mp4",albumImg:"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fblog%2F202107%2F05%2F20210705100427_ee4b8.thumb.1000_0.jpg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1628415177&t=87962cc902fb5925da0a4d60d4c48ca9",userName: "发布人名称",userAvatarUrl:"https://p16-tiktokcdn-com.akamaized.net/aweme/720x720/tiktok-obj/1663771856684033.jpeg",description: "春日的暖阳,花开进度80%,准备和爱车路过全世界,感受独具魅力的岭南文化!",title: "视频标题",likes: "352",likeStatus: "1",comments: "585",shares: "425",watchers: "825",favorites: "245",time: "2023年12月16日",videoTags: [VideoTag(tagId: "1111", tagName: "今天去哪玩"),VideoTag(tagId: "1111", tagName: "南京车友圈"),VideoTag(tagId: "1111", tagName: "活动名称"),]),VideoData(id: "2525",uid: "35435",type: "1",videoUrl: "https://media.w3.org/2010/05/sintel/trailer.mp4",albumImg:"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fblog%2F202107%2F05%2F20210705100427_ee4b8.thumb.1000_0.jpg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1628415177&t=87962cc902fb5925da0a4d60d4c48ca9",userName: "发布人名称",userAvatarUrl:"https://p16-tiktokcdn-com.akamaized.net/aweme/720x720/tiktok-obj/1663771856684033.jpeg",description: "春日的暖阳,花开进度80%,准备和爱车路过全世界,感受独具魅力的岭南文化!",title: "视频标题",likes: "252",likeStatus: "1",comments: "424",shares: "245",watchers: "453",favorites: "523",time: "2023年12月16日",videoTags: [VideoTag(tagId: "1111", tagName: "今天去哪玩"),VideoTag(tagId: "1111", tagName: "南京车友圈"),VideoTag(tagId: "1111", tagName: "活动名称"),]),VideoData(id: "2525",uid: "35435",type: "1",videoUrl: "https://jomin-web.web.app/resource/video/video_iu.mp4",albumImg:"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fblog%2F202107%2F05%2F20210705100427_ee4b8.thumb.1000_0.jpg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1628415177&t=87962cc902fb5925da0a4d60d4c48ca9",userName: "发布人名称",userAvatarUrl:"https://p16-tiktokcdn-com.akamaized.net/aweme/720x720/tiktok-obj/1663771856684033.jpeg",description: "春日的暖阳,花开进度80%,准备和爱车路过全世界,感受独具魅力的岭南文化!",title: "视频标题",likes: "252",likeStatus: "1",comments: "424",shares: "245",watchers: "453",favorites: "523",time: "2023年12月16日",videoTags: [VideoTag(tagId: "1111", tagName: "今天去哪玩"),VideoTag(tagId: "1111", tagName: "南京车友圈"),VideoTag(tagId: "1111", tagName: "活动名称"),]),
];

相关文章:

Flutter 仿抖音 TikTok 上下滑动 播放视频

Flutter 仿抖音 TikTok 上下滑动 播放视频UI框架&#xff0c;视频播放使用 video_player github&#xff1a;GitHub - PangHaHa12138/TiktokVideo: Flutter 仿抖音 TikTok 上下滑动 播放视频UI框架 实现功能&#xff1a; 1.上下滑动自动播放切换视频&#xff0c;loading 封面…...

计算机网络——网络层(2)

计算机网络——网络层&#xff08;2&#xff09; 小程一言专栏链接: [link](http://t.csdnimg.cn/ZUTXU)前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff0c; [跳转到网站](https://www.captainbed.…...

01-16Maven-SpringBoot入门

Maven继承Maven高级SpringSpringBoot入门 Maven 一、概念及功能 概念&#xff1a;Maven是Apache软件基金会组织维护的一款专门为Java项目提供项目构建和依赖管理的工具 1.1作用&#xff1a; 项目构建 构建&#xff1a;是一个将代码从开发阶段到生产阶段的一个过程&#xf…...

微信小程序(二十七)列表渲染改变量名

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.改变默认循环单元item变量名 2.改变默认循环下标index变量名 基础模板有问题可以先看上一篇 源码&#xff1a; index.wxml <view class"students"><view class"item"><te…...

k8s之安装部署及kuboard发布应用

目录 环境准备 系统规划 配置免密 将桥接的IPv4流量传递到iptables的链 系统基础配置 安装docker 安装docker及基础依赖 配置docker的仓库下载地址 部署k8s 添加阿里云的k8s源 安装kubeadm&#xff0c;kubelet和kubectl 初始化masteer节点 部署node节点 部署flanne…...

JProfiler for Mac:提升性能和诊断问题的终极工具

在当今的高性能计算和多线程应用中&#xff0c;性能优化和问题诊断是至关重要的。JProfiler for Mac 是一个强大的性能分析工具&#xff0c;旨在帮助开发者更好地理解其应用程序的运行情况&#xff0c;提升性能并快速诊断问题。 JProfiler for Mac 的主要特点包括&#xff1a;…...

力扣202-快乐数

快乐数 题目链接 解题思路&#xff1a; 两个指针&#xff0c;一快一慢&#xff0c;如果相遇&#xff0c;就会生成环如果环内元素为1,那么就可以返回 class Solution { public:int get(int n){int res 0;while(n){res (n%10) * (n%10);n / 10;}return res;}bool isHappy(int …...

牛客寒假训练营H题

思路&#xff1a;找出所有m的子集&#xff0c;加到价值中&#xff0c;找出最大价值即可。 代码&#xff1a; void solve(){int n, m;cin >> n >> m;vector<pii>a(n 1);for(int i 1;i < n;i )cin >> a[i].first >> a[i].second;int ans 0…...

ubuntu22.04@laptop 常用基础环境安装

ubuntu22.04laptop 常用基础环境安装 1. 源由2. 步骤2.1 安装ubuntu22.04 LTS系统2.2 必备软件安装2.3 基本远程环境2.3.1 远程ssh登录2.3.2 samba局域网2.3.3 VNC远程登录 2.4 开发环境安装 3. 总结 1. 源由 应朋友要求&#xff0c;整理下一个个人常用的工作笔记本常用开发环…...

Linux第41步_移植ST公司uboot的第2步_修改网络驱动_USB OTG设备树_LCD驱动_以及编译和烧写测试

移植ST公司uboot的第1步&#xff0c;创建配置文件、设备树、修改电源管理和sdmmc节点后&#xff0c;还需要进一部修改&#xff0c;如&#xff1a;网络驱动、USB OTG设备树、LCD驱动&#xff0c;以及编译和烧写测试。 一、在虚拟机中&#xff0c;使用VSCode打开my_uboot工作区 …...

瑞芯微1808模型转换(onnx到rknn)环境配置过程

瑞芯微1808模型转换&#xff08;onnx → \to →rknn&#xff09;环境配置 阅读本解决方案前&#xff0c;请读者确保已经根据官方的相关教程【rknn_model_zoo/common/rknn_converter at v1.5.0 airockchip/rknn_model_zoo (github.com)】完成其他配置文件的修改&#xff0c;以…...

测试ASP.NET Core项目调用EasyCaching的基本用法(InMemory)

EasyCaching属于开源缓存库&#xff0c;支持基本缓存方式及高级缓存用法&#xff0c;提高用户操作缓存的效率。EasyCaching支持的缓存方式包括以下类型&#xff0c;本文学习最基础的InMemory方式的基本用法。   EasyCaching.InMemory包属于基于内存的缓存库&#xff0c;使用的…...

机器学习系列-2 线性回归训练损失

机器学习系列-2 线性回归&训练损失 学习内容来自&#xff1a;谷歌ai学习 https://developers.google.cn/machine-learning/crash-course/framing/check-your-understanding?hlzh-cn 本文作为学习记录1 线性回归&#xff1a; 举例&#xff1a;蝉&#xff08;昆虫物种&…...

spring-boot-actuator 服务监控

1 概述 服务启动时&#xff0c;通过spring-boot-actuator 监控es等服务是否连接成功等 2 依赖 <!-- 服务监控 --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId><…...

窥探向量乘矩阵的存内计算原理—基于向量乘矩阵的存内计算

在当今计算领域中&#xff0c;存内计算技术凭借其出色的向量乘矩阵操作效能引起了广泛关注。本文将深入研究基于向量乘矩阵的存内计算原理&#xff0c;并探讨几个引人注目的代表性工作&#xff0c;如DPE、ISAAC、PRIME等&#xff0c;它们在神经网络和图计算应用中表现出色&…...

Python flask 表单详解

文章目录 1 概述1.1 request 对象 2 示例2.1 目录结构2.2 student.html2.3 result.html2.4 app.py 1 概述 1.1 request 对象 作用&#xff1a;来自客户端网页的数据作为全局请求对象发送到服务器request 对象的重要属性如下&#xff1a; 属性解释form字典对象&#xff0c;包…...

【Tomcat与网络3】Tomcat的整体架构

目录 1.演进1&#xff1a;将连接和处理服务分开 2演进2&#xff1a;Container的演进 3 再论Tomcat的容器结构 4 Tomcat处理请求的过程 5 请求的处理过程与Pipeline-Valve管道 在前面我们介绍了Servlet的基本原理&#xff0c;本文我们结合Tomcat来分析一下如何设计一个大型…...

k8s中cert-manager管理https证书

前言 目前https是刚需,但证书又很贵,虽然阿里云有免费的,但没有泛域名证书,每有一个子域名就要申请一个证书,有效期1年,1年一到全都的更换,太麻烦了。经过搜索,发现了自动更新证书神器cert-manager;当然cert-manager是基于k8s的。 安装采用Helm方式 Chart地址: ht…...

如何搭建私有云盘SeaFile并实现远程访问本地文件资料

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-hsDnDEybLME85dTx {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…...

Centos7安装Nginx-1.21

一、编译前提&#xff0c;需要安装必要的包 yum install gcc pcre-devel openssl-devel zlib-devel wget -y 二、下载对应的NGINX包 wget http://nginx.org/download/nginx-1.21.0.tar.gz 三、解压nginx tar xf nginx-1.21.0.tar.gz 四、编译并安装nginx到/usr/local/ng…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

Go 语言接口详解

Go 语言接口详解 核心概念 接口定义 在 Go 语言中&#xff0c;接口是一种抽象类型&#xff0c;它定义了一组方法的集合&#xff1a; // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的&#xff1a; // 矩形结构体…...

unix/linux,sudo,其发展历程详细时间线、由来、历史背景

sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

Python网页自动化Selenium中文文档

1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API&#xff0c;让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API&#xff0c;你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...

Spring Boot + MyBatis 集成支付宝支付流程

Spring Boot MyBatis 集成支付宝支付流程 核心流程 商户系统生成订单调用支付宝创建预支付订单用户跳转支付宝完成支付支付宝异步通知支付结果商户处理支付结果更新订单状态支付宝同步跳转回商户页面 代码实现示例&#xff08;电脑网站支付&#xff09; 1. 添加依赖 <!…...