统一Badge组件 #9

This commit is contained in:
guozhigq
2023-08-15 11:09:28 +08:00
parent 3c9a97181b
commit da9bbc0e76
13 changed files with 242 additions and 152 deletions

View File

@ -1,33 +1,120 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
Widget pBadge( // Widget pBadge(
text, // text,
context, // context,
double? top, // double? top,
double? right, // double? right,
double? bottom, // double? bottom,
double? left, { // double? left, {
type = 'primary', // type = 'primary',
}) { // }) {
Color bgColor = Theme.of(context).colorScheme.primary; // Color bgColor = Theme.of(context).colorScheme.primary;
Color color = Theme.of(context).colorScheme.onPrimary; // Color color = Theme.of(context).colorScheme.onPrimary;
// if (type == 'gray') {
// bgColor = Colors.black54.withOpacity(0.4);
// color = Colors.white;
// }
// return Positioned(
// top: top,
// left: left,
// right: right,
// bottom: bottom,
// child: Container(
// padding: const EdgeInsets.symmetric(vertical: 1, horizontal: 6),
// decoration:
// BoxDecoration(borderRadius: BorderRadius.circular(4), color: bgColor),
// child: Text(
// text,
// style: TextStyle(fontSize: 11, color: color),
// ),
// ),
// );
// }
class PBadge extends StatelessWidget {
final String? text;
final double? top;
final double? right;
final double? bottom;
final double? left;
final String? type;
final String? size;
final String? stack;
final double? fs;
const PBadge({
super.key,
this.text,
this.top,
this.right,
this.bottom,
this.left,
this.type = 'primary',
this.size = 'medium',
this.stack = 'position',
this.fs = 11,
});
@override
Widget build(BuildContext context) {
ColorScheme t = Theme.of(context).colorScheme;
// 背景色
Color bgColor = t.primary;
// 前景色
Color color = t.onPrimary;
// 边框色
Color borderColor = Colors.transparent;
if (type == 'gray') { if (type == 'gray') {
bgColor = Colors.black54.withOpacity(0.4); bgColor = Colors.black54.withOpacity(0.4);
color = Colors.white; color = Colors.white;
} }
if (type == 'color') {
bgColor = t.primaryContainer.withOpacity(0.6);
color = t.primary;
}
if (type == 'line') {
bgColor = Colors.transparent;
color = t.primary;
borderColor = t.primary;
}
EdgeInsets paddingStyle =
const EdgeInsets.symmetric(vertical: 1, horizontal: 6);
double fontSize = 11;
BorderRadius br = BorderRadius.circular(4);
if (size == 'small') {
paddingStyle = const EdgeInsets.symmetric(vertical: 0, horizontal: 3);
fontSize = 11;
br = BorderRadius.circular(3);
}
Widget content = Container(
padding: paddingStyle,
decoration: BoxDecoration(
borderRadius: br,
color: bgColor,
border: Border.all(color: borderColor),
),
child: Text(
text!,
style: TextStyle(fontSize: fs ?? fontSize, color: color),
),
);
if (stack == 'position') {
return Positioned( return Positioned(
top: top, top: top,
left: left, left: left,
right: right, right: right,
bottom: bottom, bottom: bottom,
child: Container( child: content,
padding: const EdgeInsets.symmetric(vertical: 1, horizontal: 6), );
decoration: } else {
BoxDecoration(borderRadius: BorderRadius.circular(4), color: bgColor), return Padding(
child: Text( padding: const EdgeInsets.only(right: 5),
text, child: content,
style: TextStyle(fontSize: 11, color: color),
),
),
); );
} }
}
}

View File

@ -1,29 +0,0 @@
import 'package:flutter/material.dart';
class UpTag extends StatelessWidget {
final String? tagText;
const UpTag({super.key, this.tagText = 'UP'});
@override
Widget build(BuildContext context) {
Color primary = Theme.of(context).colorScheme.primary;
return Container(
padding: const EdgeInsets.fromLTRB(3, 1, 3, 1),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(3),
color: tagText == 'UP' ? primary : null,
border: Border.all(color: primary)),
margin: const EdgeInsets.only(right: 5),
child: Center(
child: Text(
tagText!,
style: TextStyle(
fontSize: 9,
color: tagText == 'UP'
? Theme.of(context).colorScheme.onPrimary
: primary,
),
),
),
);
}
}

View File

@ -82,9 +82,14 @@ class VideoCardH extends StatelessWidget {
height: maxHeight, height: maxHeight,
), ),
), ),
pBadge(Utils.timeFormat(videoItem.duration!), PBadge(
context, null, 6.0, 6.0, null, text: Utils.timeFormat(videoItem.duration!),
type: 'gray'), top: null,
right: 6.0,
bottom: 6.0,
left: null,
type: 'gray',
),
// if (videoItem.rcmdReason != null && // if (videoItem.rcmdReason != null &&
// videoItem.rcmdReason.content != '') // videoItem.rcmdReason.content != '')
// pBadge(videoItem.rcmdReason.content, context, // pBadge(videoItem.rcmdReason.content, context,

View File

@ -2,8 +2,8 @@ import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:pilipala/common/constants.dart'; import 'package:pilipala/common/constants.dart';
import 'package:pilipala/common/widgets/badge.dart';
import 'package:pilipala/common/widgets/stat/danmu.dart'; import 'package:pilipala/common/widgets/stat/danmu.dart';
import 'package:pilipala/common/widgets/stat/up.dart';
import 'package:pilipala/common/widgets/stat/view.dart'; import 'package:pilipala/common/widgets/stat/view.dart';
import 'package:pilipala/http/search.dart'; import 'package:pilipala/http/search.dart';
import 'package:pilipala/http/user.dart'; import 'package:pilipala/http/user.dart';
@ -164,35 +164,23 @@ class VideoContent extends StatelessWidget {
Row( Row(
children: [ children: [
if (videoItem.goto == 'bangumi') ...[ if (videoItem.goto == 'bangumi') ...[
UpTag( PBadge(
tagText: videoItem.bangumiBadge, text: videoItem.bangumiBadge,
), stack: 'normal',
size: 'small',
type: 'line',
fs: 9,
)
], ],
if (videoItem.rcmdReason != null && if (videoItem.rcmdReason != null &&
videoItem.rcmdReason.content != '') ...[ videoItem.rcmdReason.content != '') ...[
Container( PBadge(
padding: const EdgeInsets.fromLTRB(3, 1, 3, 1), text: videoItem.rcmdReason.content,
decoration: BoxDecoration( stack: 'normal',
color: Theme.of(context) size: 'small',
.colorScheme type: 'color',
.primaryContainer )
.withOpacity(0.6),
borderRadius: BorderRadius.circular(3)),
child: Center(
child: Text(
videoItem.rcmdReason.content,
style: TextStyle(
fontSize: 11,
color: Theme.of(context).colorScheme.primary,
),
),
)),
const SizedBox(width: 4)
], ],
if (videoItem.adInfo != null)
const UpTag(
tagText: '推广',
),
Expanded( Expanded(
child: LayoutBuilder(builder: child: LayoutBuilder(builder:
(BuildContext context, BoxConstraints constraints) { (BuildContext context, BoxConstraints constraints) {

View File

@ -161,13 +161,14 @@ class _BangumiInfoState extends State<BangumiInfo> {
), ),
if (bangumiItem != null && if (bangumiItem != null &&
bangumiItem!.rating != null) bangumiItem!.rating != null)
pBadge( PBadge(
text:
'评分 ${!widget.loadingStatus ? widget.bangumiDetail!.rating!['score']! : bangumiItem!.rating!['score']!}', '评分 ${!widget.loadingStatus ? widget.bangumiDetail!.rating!['score']! : bangumiItem!.rating!['score']!}',
context, top: null,
null, right: 6,
6, bottom: 6,
6, left: null,
null), ),
], ],
), ),
const SizedBox(width: 10), const SizedBox(width: 10),

View File

@ -97,10 +97,21 @@ class BangumiCardV extends StatelessWidget {
), ),
), ),
if (bangumiItem.badge != null) if (bangumiItem.badge != null)
pBadge(bangumiItem.badge, context, 6, 6, null, null), PBadge(
text: bangumiItem.badge,
top: 6,
right: 6,
bottom: null,
left: null),
if (bangumiItem.order != null) if (bangumiItem.order != null)
pBadge(bangumiItem.order, context, null, null, 6, 6, PBadge(
type: 'gray'), text: bangumiItem.order,
top: null,
right: null,
bottom: 6,
left: 6,
type: 'gray',
),
], ],
); );
}), }),

View File

@ -77,10 +77,21 @@ Widget liveRcmdPanel(item, context, {floor = 1}) {
src: item.modules.moduleDynamic.major.liveRcmd.cover, src: item.modules.moduleDynamic.major.liveRcmd.cover,
), ),
), ),
pBadge(watchedShow['text_large'], context, 6, 56, null, null, PBadge(
type: 'gray'), text: watchedShow['text_large'],
pBadge( top: 6,
liveStatus == 1 ? '直播中' : '直播结束', context, 6, 6, null, null), right: 56,
bottom: null,
left: null,
type: 'gray',
),
PBadge(
text: liveStatus == 1 ? '直播中' : '直播结束',
top: 6,
right: 6,
bottom: null,
left: null,
),
Positioned( Positioned(
left: 0, left: 0,
right: 0, right: 0,

View File

@ -85,7 +85,14 @@ Widget picWidget(item, context) {
children: list, children: list,
), ),
if (len == 1 && origAspectRatio < 0.4) if (len == 1 && origAspectRatio < 0.4)
pBadge('长图', context, null, null, 6.0, 6.0, type: 'gray') const PBadge(
text: '长图',
top: null,
right: null,
bottom: 6.0,
left: 6.0,
type: 'gray',
)
], ],
), ),
); );

View File

@ -89,7 +89,13 @@ Widget videoSeasonWidget(item, context, type, {floor = 1}) {
), ),
), ),
if (content.badge != null && type == 'pgc') if (content.badge != null && type == 'pgc')
pBadge(content.badge['text'], context, 8.0, 10.0, null, null), PBadge(
text: content.badge['text'],
top: 8.0,
right: 10.0,
bottom: null,
left: null,
),
Positioned( Positioned(
left: 0, left: 0,
right: 0, right: 0,

View File

@ -147,23 +147,26 @@ class HistoryItem extends StatelessWidget {
if (!BusinessType if (!BusinessType
.hiddenDurationType.hiddenDurationType .hiddenDurationType.hiddenDurationType
.contains(videoItem.history.business)) .contains(videoItem.history.business))
pBadge( PBadge(
videoItem.progress == -1 text: videoItem.progress == -1
? '已看完' ? '已看完'
: '${Utils.timeFormat(videoItem.progress!)}/${Utils.timeFormat(videoItem.duration!)}', : '${Utils.timeFormat(videoItem.progress!)}/${Utils.timeFormat(videoItem.duration!)}',
context, right: 6.0,
null, bottom: 6.0,
6.0, type: 'gray',
6.0, ),
null,
type: 'gray'),
// 右上角 // 右上角
if (BusinessType.showBadge.showBadge if (BusinessType.showBadge.showBadge
.contains(videoItem.history.business) || .contains(videoItem.history.business) ||
videoItem.history.business == videoItem.history.business ==
BusinessType.live.type) BusinessType.live.type)
pBadge(videoItem.badge, context, 6.0, 6.0, PBadge(
null, null), text: videoItem.badge,
top: 6.0,
right: 6.0,
bottom: null,
left: null,
),
], ],
); );
}, },

View File

@ -1,8 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:pilipala/common/constants.dart'; import 'package:pilipala/common/constants.dart';
import 'package:pilipala/common/widgets/badge.dart';
import 'package:pilipala/models/live/item.dart'; import 'package:pilipala/models/live/item.dart';
import 'package:pilipala/pages/video/detail/reply/widgets/reply_item.dart';
import 'package:pilipala/utils/utils.dart'; import 'package:pilipala/utils/utils.dart';
import 'package:pilipala/common/widgets/network_img_layer.dart'; import 'package:pilipala/common/widgets/network_img_layer.dart';
@ -121,7 +121,12 @@ class LiveContent extends StatelessWidget {
), ),
Row( Row(
children: [ children: [
const UpTag(), const PBadge(
text: 'UP',
size: 'small',
stack: 'normal',
fs: 9,
),
Expanded( Expanded(
child: Text( child: Text(
liveItem.uname, liveItem.uname,

View File

@ -41,8 +41,13 @@ Widget searchMbangumiPanel(BuildContext context, ctr, list) {
height: 148, height: 148,
src: i.cover, src: i.cover,
), ),
pBadge(i.mediaType == 1 ? '番剧' : '国创', context, 6.0, 4.0, PBadge(
null, null) text: i.mediaType == 1 ? '番剧' : '国创',
top: 6.0,
right: 4.0,
bottom: null,
left: null,
)
], ],
), ),
const SizedBox(width: 10), const SizedBox(width: 10),

View File

@ -2,6 +2,7 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:pilipala/common/widgets/badge.dart';
import 'package:pilipala/common/widgets/network_img_layer.dart'; import 'package:pilipala/common/widgets/network_img_layer.dart';
import 'package:pilipala/models/common/reply_type.dart'; import 'package:pilipala/models/common/reply_type.dart';
import 'package:pilipala/models/video/reply/item.dart'; import 'package:pilipala/models/video/reply/item.dart';
@ -139,7 +140,13 @@ class ReplyItem extends StatelessWidget {
height: 11, height: 11,
), ),
const SizedBox(width: 6), const SizedBox(width: 6),
if (replyItem!.isUp!) const UpTag(), if (replyItem!.isUp!)
const PBadge(
text: 'UP',
size: 'small',
stack: 'normal',
fs: 9,
),
], ],
), ),
Positioned( Positioned(
@ -209,7 +216,14 @@ class ReplyItem extends StatelessWidget {
if (replyItem!.isTop!) if (replyItem!.isTop!)
const WidgetSpan( const WidgetSpan(
alignment: PlaceholderAlignment.top, alignment: PlaceholderAlignment.top,
child: UpTag(tagText: 'TOP')), child: PBadge(
text: 'TOP',
size: 'small',
stack: 'normal',
type: 'line',
fs: 9,
),
),
buildContent(context, replyItem!, replyReply, null), buildContent(context, replyItem!, replyReply, null),
], ],
), ),
@ -392,7 +406,12 @@ class ReplyItemRow extends StatelessWidget {
if (replies![i].isUp) if (replies![i].isUp)
const WidgetSpan( const WidgetSpan(
alignment: PlaceholderAlignment.top, alignment: PlaceholderAlignment.top,
child: UpTag(), child: PBadge(
text: 'UP',
size: 'small',
stack: 'normal',
fs: 9,
),
), ),
buildContent( buildContent(
context, replies![i], replyReply, replyItem), context, replies![i], replyReply, replyItem),
@ -759,32 +778,3 @@ InlineSpan buildContent(
// spanChilds.add(TextSpan(text: matchMember)); // spanChilds.add(TextSpan(text: matchMember));
return TextSpan(children: spanChilds); return TextSpan(children: spanChilds);
} }
class UpTag extends StatelessWidget {
final String? tagText;
const UpTag({super.key, this.tagText = 'UP'});
@override
Widget build(BuildContext context) {
Color primary = Theme.of(context).colorScheme.primary;
return Container(
width: 24,
height: 14,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(3),
color: tagText == 'UP' ? primary : null,
border: Border.all(color: primary)),
margin: const EdgeInsets.only(right: 4),
child: Center(
child: Text(
tagText!,
style: TextStyle(
fontSize: 9,
color: tagText == 'UP'
? Theme.of(context).colorScheme.onPrimary
: primary,
),
),
),
);
}
}