From 3a344843f90b433a01f65ab820eea94a70d7e41b Mon Sep 17 00:00:00 2001 From: guozhigq Date: Wed, 19 Apr 2023 08:12:08 +0800 Subject: [PATCH] =?UTF-8?q?mod:=20=E9=A6=96=E9=A1=B5=E6=8E=A8=E8=8D=90?= =?UTF-8?q?=E8=A7=86=E9=A2=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/images/dm.svg | 3 + assets/images/dm_gray.png | Bin 0 -> 1973 bytes assets/images/dm_white.png | Bin 0 -> 1352 bytes assets/images/loading.gif | Bin 0 -> 32146 bytes assets/images/loading.png | Bin 0 -> 3028 bytes assets/images/play.svg | 1 + assets/images/tv.svg | 1 + assets/images/up.svg | 1 + assets/images/up_gray.png | Bin 0 -> 2090 bytes assets/images/view.svg | 3 + assets/images/view_gray.png | Bin 0 -> 1812 bytes assets/images/view_white.png | Bin 0 -> 1264 bytes lib/common/constants.dart | 1 + lib/common/widgets/network_img_layer.dart | 66 +++++++ lib/common/widgets/stat/danmu.dart | 34 ++++ lib/common/widgets/stat/view.dart | 34 ++++ lib/common/widgets/video_card_v.dart | 214 ++++++++++++++++++++++ lib/models/models_rec_video_item.dart | 97 ++++++++++ lib/pages/home/controller.dart | 16 +- lib/pages/home/view.dart | 12 +- lib/utils/utils.dart | 25 +++ pubspec.yaml | 6 +- 22 files changed, 499 insertions(+), 15 deletions(-) create mode 100644 assets/images/dm.svg create mode 100644 assets/images/dm_gray.png create mode 100644 assets/images/dm_white.png create mode 100644 assets/images/loading.gif create mode 100644 assets/images/loading.png create mode 100644 assets/images/play.svg create mode 100644 assets/images/tv.svg create mode 100644 assets/images/up.svg create mode 100644 assets/images/up_gray.png create mode 100644 assets/images/view.svg create mode 100644 assets/images/view_gray.png create mode 100644 assets/images/view_white.png create mode 100644 lib/common/widgets/network_img_layer.dart create mode 100644 lib/common/widgets/stat/danmu.dart create mode 100644 lib/common/widgets/stat/view.dart create mode 100644 lib/common/widgets/video_card_v.dart create mode 100644 lib/models/models_rec_video_item.dart diff --git a/assets/images/dm.svg b/assets/images/dm.svg new file mode 100644 index 00000000..2690acd2 --- /dev/null +++ b/assets/images/dm.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/assets/images/dm_gray.png b/assets/images/dm_gray.png new file mode 100644 index 0000000000000000000000000000000000000000..438cffc023b8aed48c5b5aa9cb3233ea273876cd GIT binary patch literal 1973 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 KMNUMnLSTYPsgz0p literal 0 HcmV?d00001 diff --git a/assets/images/loading.gif b/assets/images/loading.gif new file mode 100644 index 0000000000000000000000000000000000000000..7c2d1f701c1586ff5c0e425fa92b944ae74b38f0 GIT binary patch literal 32146 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 literal 0 HcmV?d00001 diff --git a/assets/images/play.svg b/assets/images/play.svg new file mode 100644 index 00000000..0032f069 --- /dev/null +++ b/assets/images/play.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/images/tv.svg b/assets/images/tv.svg new file mode 100644 index 00000000..fdb077b1 --- /dev/null +++ b/assets/images/tv.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/images/up.svg b/assets/images/up.svg new file mode 100644 index 00000000..c63989c5 --- /dev/null +++ b/assets/images/up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/images/up_gray.png b/assets/images/up_gray.png new file mode 100644 index 0000000000000000000000000000000000000000..c6d7f4ab7e9198c31ad1b66331f4a16ec928df42 GIT binary patch literal 2090 zcmV+_2-WwAP)7r1dWm+7M_}5KV0` zc+K5zeyrWy%)GCE+|2HqcQcdg;*a(iAV+IrVxUaQe7fy zc%IkHX0y$SiHXYtBe;M6{<|&9+74g~fI9#b0OW&TYq>Xmm+$~IgR24HEP&I#@1NMU zYuDe?IwlgFnVGpqDfJ@&UsypyR~$t2A~SzeO8K|g_Bf&Iy5r3JGXS>?(zq4G{{VbL zN_pIDSVXW^t35(Q#{r0x0TrTCra?qa09Tngd|s{+(G>ttN_7GwblfV0SOoygyc)m= z01(kAfDvZaABB8yrP@S9Un!MJze*%{;J|@9gb=R-xYZ!@O8`fG-~X#+S#wg#izzo6 z7#zo0g+W@hlCUgm&JcYdEQmNE0QkN?KS-li7^bZ~ zF8VT2(8_9db~bjct5&NUEz6n&@J6{@K6b4;yRN&HnLi_hs27XHGok$O;lue(r}G36 zZA|ET0l=F8PU-7f9L}9P*Ic)5okHJXJ%YVu!f~87fK@?tUP@_B*--B^fct{#7p0Uh zB;B}Ht8F5pGgt`9=UT1S#yxxXyc3L52k>Z`;Q<&x-L~yL6B85vNm6ngXHFy5mQvmV z1dNXyIg-=J0gGJ@0H{@AQ-X@aTBI!Dv0P+L$uD+F>Q``(D(g}p?}k- zsDUxPqHU^mEPaZ?cwmPBQY(A5ZO6sQ5t~C!c8ucCpi-&W>({S;nwcLAWz77C$;rtj zhmke_D5bhWMA99mM+c4jUDw^K3xX-OjhXcqiXx(?6UKPcQCZfFn zvYO7pVzKzA>oWh^h&V+E(I=S8Iq1bYu zXC&I;##&$K=h2Vx@|8+OR4NsP6qL*5WA%Fd+4=eTPYWSF$;=-lqNY;nwQjfj$2ejk zh^RzFr%k!08fw&Pwa+7Zj^Ju0lQ|hydIXEb z;(q}=t0@wIV>2@|pB=cB%Y^H?TZ!lwhWL1p#{pn$crD9%%J=;*Vc|#`PD0)=RKwOS+v!09Oq#GCy@TZpP?Nt93 zhhWdg%$^Y9a!~Fvb0i!jqFlJeQA&*xQTS)C!NMP}A3z9y)3#=cnI9>a%fCq_2mr3@ zZfE8rh<>jhX0!oJNGXq+4Y6J-l}aaw=zeBC8P`5!c%GT>jUxvv;V9R^g9q>OJa0RI z2Z-oSM9;0JyT3&5+kZJ(H&ocu>x$Ll(bSFKi8XEK?*=XrS{M4pJU0HBn* zjfleZdKl$fVGf6gE&&L4_YDAGW?u+#DJZv + + \ No newline at end of file diff --git a/assets/images/view_gray.png b/assets/images/view_gray.png new file mode 100644 index 0000000000000000000000000000000000000000..fe2b34825a7f5caea0490414d1d05ad80a544237 GIT binary patch literal 1812 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 placeholder(context), + placeholder: (context, url) => placeholder(context), + ), + ) + : placeholder(context); + } + + Widget placeholder(context) { + return SizedBox( + width: width ?? double.infinity, + height: height ?? double.infinity, + child: Center( + child: Image.asset( + 'assets/images/loading.png', + width: 300, + height: 300, + )), + ); + } +} diff --git a/lib/common/widgets/stat/danmu.dart b/lib/common/widgets/stat/danmu.dart new file mode 100644 index 00000000..44f63b21 --- /dev/null +++ b/lib/common/widgets/stat/danmu.dart @@ -0,0 +1,34 @@ +import 'package:flutter/material.dart'; +import 'package:pilipala/utils/utils.dart'; + +class StatDanMu extends StatelessWidget { + final String? theme; + final int? danmu; + final String? size; + + const StatDanMu({Key? key, this.theme, this.danmu, this.size}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return Row( + children: [ + Image.asset( + 'assets/images/dm_$theme.png', + width: size == 'medium' ? 16 : 14, + height: size == 'medium' ? 16 : 14, + ), + const SizedBox(width: 2), + Text( + Utils.numFormat(danmu!), + style: TextStyle( + fontSize: size == 'medium' ? 12 : 11, + color: theme == 'white' + ? Colors.white + : Theme.of(context).colorScheme.outline, + ), + ) + ], + ); + } +} diff --git a/lib/common/widgets/stat/view.dart b/lib/common/widgets/stat/view.dart new file mode 100644 index 00000000..6f6d1960 --- /dev/null +++ b/lib/common/widgets/stat/view.dart @@ -0,0 +1,34 @@ +import 'package:flutter/material.dart'; +import 'package:pilipala/utils/utils.dart'; + +class StatView extends StatelessWidget { + final String? theme; + final int? view; + final String? size; + + const StatView({Key? key, this.theme, this.view, this.size}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Row( + children: [ + Image.asset( + 'assets/images/view_$theme.png', + width: size == 'medium' ? 16 : 14, + height: size == 'medium' ? 16 : 14, + ), + const SizedBox(width: 2), + Text( + Utils.numFormat(view!), + // videoItem['stat']['view'].toString(), + style: TextStyle( + fontSize: size == 'medium' ? 12 : 11, + color: theme == 'white' + ? Colors.white + : Theme.of(context).colorScheme.outline, + ), + ), + ], + ); + } +} diff --git a/lib/common/widgets/video_card_v.dart b/lib/common/widgets/video_card_v.dart new file mode 100644 index 00000000..32b9c927 --- /dev/null +++ b/lib/common/widgets/video_card_v.dart @@ -0,0 +1,214 @@ +import 'package:get/get.dart'; +import 'package:flutter/material.dart'; +import 'package:pilipala/common/constants.dart'; +import 'package:pilipala/common/widgets/stat/danmu.dart'; +import 'package:pilipala/common/widgets/stat/view.dart'; +import 'package:pilipala/utils/utils.dart'; +import 'package:pilipala/pages/home/controller.dart'; +import 'package:pilipala/common/widgets/network_img_layer.dart'; + +// 视频卡片 - 垂直布局 +class VideoCardV extends StatelessWidget { + var videoItem; + + VideoCardV({Key? key, required this.videoItem}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Card( + elevation: 0.8, + clipBehavior: Clip.hardEdge, + shape: RoundedRectangleBorder( + borderRadius: StyleString.mdRadius, + ), + margin: EdgeInsets.zero, + child: InkWell( + onTap: () async { + await Future.delayed(const Duration(milliseconds: 200)); + Get.toNamed('/video?aid=${videoItem.id}', + arguments: {'videoItem': videoItem}); + }, + onLongPress: () { + print('长按'); + }, + child: Column( + children: [ + ClipRRect( + borderRadius: const BorderRadius.only( + topLeft: StyleString.imgRadius, + topRight: StyleString.imgRadius, + ), + child: AspectRatio( + aspectRatio: StyleString.aspectRatio, + child: LayoutBuilder(builder: (context, boxConstraints) { + double maxWidth = boxConstraints.maxWidth; + double maxHeight = boxConstraints.maxHeight; + double PR = MediaQuery.of(context).devicePixelRatio; + return Stack( + children: [ + NetworkImgLayer( + // 指定图片尺寸 + // src: videoItem['pic'] + '@${(maxWidth * 2).toInt() }w', + src: videoItem.pic + '@.webp', + width: maxWidth, + height: maxHeight, + ), + Positioned( + left: 0, + right: 0, + bottom: 0, + child: AnimatedOpacity( + opacity: 1, + duration: const Duration(milliseconds: 200), + child: VideoStat( + view: videoItem.stat.view, + danmaku: videoItem.stat.danmaku, + duration: videoItem.duration, + ), + ), + ) + ], + ); + }), + ), + ), + VideoContent(videoItem: videoItem) + ], + ), + ), + ); + } +} + +class VideoContent extends StatelessWidget { + final videoItem; + const VideoContent({Key? key, required this.videoItem}) : super(key: key); + @override + Widget build(BuildContext context) { + return Expanded( + child: Padding( + // 多列 + padding: const EdgeInsets.fromLTRB(8, 8, 6, 7), + // 单列 + // padding: const EdgeInsets.fromLTRB(14, 10, 4, 8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + videoItem.title, + textAlign: TextAlign.start, + style: const TextStyle( + // fontSize: + // Theme.of(context).textTheme.titleSmall!.fontSize, + fontSize: 13, + fontWeight: FontWeight.w500), + maxLines: Get.find().crossAxisCount, + overflow: TextOverflow.ellipsis, + ), + SizedBox( + height: 18, + child: Row( + children: [ + if (videoItem.rcmdReason.content != '') ...[ + Container( + padding: const EdgeInsets.fromLTRB(3, 1, 3, 1), + decoration: BoxDecoration( + color: Theme.of(context) + .colorScheme + .primaryContainer + .withOpacity(0.6), + borderRadius: BorderRadius.circular(3)), + child: Text( + videoItem.rcmdReason.content, + style: TextStyle( + fontSize: + Theme.of(context).textTheme.labelSmall!.fontSize, + color: Theme.of(context).colorScheme.primary, + ), + ), + ), + const SizedBox(width: 4) + ], + Expanded( + child: LayoutBuilder(builder: + (BuildContext context, BoxConstraints constraints) { + return SizedBox( + width: constraints.maxWidth, + child: Text( + videoItem.owner.name, + maxLines: 1, + style: TextStyle( + fontSize: Theme.of(context) + .textTheme + .labelMedium! + .fontSize, + color: Theme.of(context).colorScheme.outline, + ), + ), + ); + }), + ), + ], + ), + ), + ], + ), + ), + ); + } +} + +class VideoStat extends StatelessWidget { + final int? view; + final int? danmaku; + final int? duration; + + const VideoStat( + {Key? key, + required this.view, + required this.danmaku, + required this.duration}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + height: 45, + padding: const EdgeInsets.only(top: 22, left: 8, right: 8), + decoration: const BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Colors.transparent, + Colors.black54, + ], + tileMode: TileMode.mirror, + ), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + StatView( + theme: 'white', + view: view, + ), + const SizedBox(width: 8), + StatDanMu( + theme: 'white', + danmu: danmaku, + ), + ], + ), + Text( + Utils.timeFormat(duration!), + style: const TextStyle(fontSize: 11, color: Colors.white), + ) + ], + ), + ); + } +} diff --git a/lib/models/models_rec_video_item.dart b/lib/models/models_rec_video_item.dart new file mode 100644 index 00000000..b37988a7 --- /dev/null +++ b/lib/models/models_rec_video_item.dart @@ -0,0 +1,97 @@ +class RecVideoItemModel { + RecVideoItemModel({ + this.id, + this.bvid, + this.cid, + this.goto, + this.uri, + this.pic, + this.title, + this.duration, + this.pubdate, + this.owner, + this.stat, + this.rcmdReason, + }); + + int? id = -1; + String? bvid = ''; + int? cid = -1; + String? goto = ''; + String? uri = ''; + String? pic = ''; + String? title = ''; + int? duration = -1; + int? pubdate = -1; + Onwer? owner; + Stat? stat; + RcmdReason? rcmdReason; + + RecVideoItemModel.fromJson(Map json) { + id = json["id"]; + bvid = json["bvid"]; + cid = json["cid"]; + goto = json["goto"]; + uri = json["uri"]; + pic = json["pic"]; + title = json["title"]; + duration = json["duration"]; + pubdate = json["pubdate"]; + owner = Onwer.fromJson(json["owner"]); + stat = Stat.fromJson(json["stat"]); + rcmdReason = json["rcmd_reason"] != null + ? RcmdReason.fromJson(json["rcmd_reason"]) + : RcmdReason(content: ''); + } +} + +class Onwer { + Onwer({ + this.mid, + this.name, + this.face, + }); + + int? mid; + String? name; + String? face; + + Onwer.fromJson(Map json) { + mid = json["mid"]; + name = json["name"]; + face = json['face']; + } +} + +class Stat { + Stat({ + this.view, + this.like, + this.danmaku, + }); + + int? view; + int? like; + int? danmaku; + + Stat.fromJson(Map json) { + view = json["view"]; + like = json["like"]; + danmaku = json['danmaku']; + } +} + +class RcmdReason { + RcmdReason({ + this.reasonType, + this.content, + }); + + int? reasonType; + String? content = ''; + + RcmdReason.fromJson(Map json) { + reasonType = json["reason_type"]; + content = json["content"] ?? ''; + } +} diff --git a/lib/pages/home/controller.dart b/lib/pages/home/controller.dart index e8d98bf4..961d05c0 100644 --- a/lib/pages/home/controller.dart +++ b/lib/pages/home/controller.dart @@ -2,14 +2,16 @@ import 'package:flutter/cupertino.dart'; import 'package:get/get.dart'; import 'package:pilipala/http/api.dart'; import 'package:pilipala/http/init.dart'; +import 'package:pilipala/models/models_rec_video_item.dart'; class HomeController extends GetxController { final ScrollController scrollController = ScrollController(); int count = 12; int _currentPage = 1; int crossAxisCount = 2; - RxList videoList = [].obs; + RxList videoList = [RecVideoItemModel()].obs; bool isLoadingMore = false; + @override void onInit() { super.onInit(); @@ -22,13 +24,17 @@ class HomeController extends GetxController { Api.recommendList, data: {'feed_version': "V3", 'ps': count, 'fresh_idx': _currentPage}, ); - var data = res.data['data']['item']; + List list = []; + for (var i in res.data['data']['item']) { + print(i); + list.add(RecVideoItemModel.fromJson(i)); + } if (type == 'init') { - videoList.value = data; + videoList.value = list; } else if (type == 'onRefresh') { - videoList.insertAll(0, data); + videoList.insertAll(0, list); } else if (type == 'onLoad') { - videoList.addAll(data); + videoList.addAll(list); } _currentPage += 1; isLoadingMore = false; diff --git a/lib/pages/home/view.dart b/lib/pages/home/view.dart index 56494278..2482e465 100644 --- a/lib/pages/home/view.dart +++ b/lib/pages/home/view.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import 'package:pilipala/common/widgets/video_card_v.dart'; import './controller.dart'; import 'package:pilipala/common/constants.dart'; import 'package:pilipala/pages/home/widgets/app_bar.dart'; @@ -76,15 +77,14 @@ class _HomePageState extends State // 列数 crossAxisCount: _homeController.crossAxisCount, mainAxisExtent: MediaQuery.of(context).size.width / - _homeController.crossAxisCount * - (10 / 16) + + _homeController.crossAxisCount / + StyleString.aspectRatio + 72), delegate: SliverChildBuilderDelegate( (BuildContext context, int index) { - return Container( - color: Theme.of(context).colorScheme.surfaceVariant, - child: Text(index.toString()), - ); + return videoList.isNotEmpty + ? VideoCardV(videoItem: videoList[index]) + : const Text('加载中'); }, childCount: videoList.isNotEmpty ? videoList.length : 10, ), diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index 299fb77f..0d5918f5 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -1,5 +1,6 @@ // 工具函数 import 'dart:io'; +import 'package:get/get_utils/get_utils.dart'; import 'package:path_provider/path_provider.dart'; class Utils { @@ -13,4 +14,28 @@ class Utils { } return tempPath; } + + static String numFormat(int number) { + String res = (number / 10000).toString(); + if (int.parse(res.split('.')[0]) >= 1) { + return '${(number / 10000).toPrecision(1)}万'; + } else { + return number.toString(); + } + } + + static String timeFormat(int time) { + // 1小时内 + if (time < 3600) { + int minute = time ~/ 60; + double res = time / 60; + if (minute != res) { + return '$minute:${(time - minute * 60) < 10 ? '0${(time - minute * 60)}' : (time - minute * 60)}'; + } else { + return minute.toString(); + } + } else { + return ''; + } + } } diff --git a/pubspec.yaml b/pubspec.yaml index bb429eb2..6d3b671c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -74,10 +74,8 @@ flutter: uses-material-design: true # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - + assets: + - assets/images/ # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware