|
|
|
|
@ -5,12 +5,20 @@ import 'package:test_sa/new_views/app_style/app_color.dart';
|
|
|
|
|
class CustomBadge extends StatelessWidget {
|
|
|
|
|
final Widget child; // The widget that the badge will be overlaid on.
|
|
|
|
|
final int value; // The value or text to be displayed in the badge.
|
|
|
|
|
final Color color; // The background color of the badge.
|
|
|
|
|
final Color color;
|
|
|
|
|
final double? positionR;
|
|
|
|
|
final double? positionT;
|
|
|
|
|
final double? height;
|
|
|
|
|
final double? width;
|
|
|
|
|
|
|
|
|
|
const CustomBadge({
|
|
|
|
|
CustomBadge({
|
|
|
|
|
Key? key,
|
|
|
|
|
required this.child,
|
|
|
|
|
required this.value,
|
|
|
|
|
this.height,
|
|
|
|
|
this.width,
|
|
|
|
|
this.positionR,
|
|
|
|
|
this.positionT,
|
|
|
|
|
this.color = AppColor.red30, // Default color is red
|
|
|
|
|
}) : super(key: key);
|
|
|
|
|
|
|
|
|
|
@ -22,13 +30,14 @@ class CustomBadge extends StatelessWidget {
|
|
|
|
|
child, // The main widget
|
|
|
|
|
// if (value > 0)
|
|
|
|
|
Positioned(
|
|
|
|
|
right: -6,
|
|
|
|
|
top: -6,
|
|
|
|
|
right: positionR ?? -6,
|
|
|
|
|
top: positionT ?? -6,
|
|
|
|
|
//Need to check why opacity he used here this is not correct need to make this total dynamic and responsive
|
|
|
|
|
child: Opacity(
|
|
|
|
|
opacity: value > 0 ? 1 : 0,
|
|
|
|
|
child: Container(
|
|
|
|
|
height: 23,
|
|
|
|
|
constraints: const BoxConstraints(minWidth: 23),
|
|
|
|
|
height: height ?? 23,
|
|
|
|
|
constraints: BoxConstraints(minWidth: width ?? 23),
|
|
|
|
|
padding: const EdgeInsets.all(3),
|
|
|
|
|
alignment: Alignment.center,
|
|
|
|
|
decoration: BoxDecoration(color: color, borderRadius: BorderRadius.circular(30)),
|
|
|
|
|
@ -43,3 +52,139 @@ class CustomBadge extends StatelessWidget {
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Need to use this badge every where..
|
|
|
|
|
class CustomBadge2 extends StatelessWidget {
|
|
|
|
|
final Widget child;
|
|
|
|
|
final int value;
|
|
|
|
|
final double top;
|
|
|
|
|
final double right;
|
|
|
|
|
final double left;
|
|
|
|
|
final double bottom;
|
|
|
|
|
final double minSize;
|
|
|
|
|
final Color backgroundColor;
|
|
|
|
|
final Color textColor;
|
|
|
|
|
final TextStyle? textStyle;
|
|
|
|
|
final int maxValue;
|
|
|
|
|
final Duration animationDuration;
|
|
|
|
|
|
|
|
|
|
const CustomBadge2({
|
|
|
|
|
super.key,
|
|
|
|
|
required this.child,
|
|
|
|
|
required this.value,
|
|
|
|
|
this.top = -6,
|
|
|
|
|
this.right = -6,
|
|
|
|
|
this.left = double.nan,
|
|
|
|
|
this.bottom = double.nan,
|
|
|
|
|
this.minSize = 18,
|
|
|
|
|
this.backgroundColor = AppColor.red30,
|
|
|
|
|
this.textColor = AppColor.white10,
|
|
|
|
|
this.textStyle,
|
|
|
|
|
this.maxValue = 99,
|
|
|
|
|
this.animationDuration = const Duration(milliseconds: 200),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
bool get _isVisible => value > 0;
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
|
return Stack(
|
|
|
|
|
clipBehavior: Clip.none,
|
|
|
|
|
children: [
|
|
|
|
|
child,
|
|
|
|
|
if (_isVisible)
|
|
|
|
|
Positioned(
|
|
|
|
|
top: top.isNaN ? null : top,
|
|
|
|
|
right: right.isNaN ? null : right,
|
|
|
|
|
left: left.isNaN ? null : left,
|
|
|
|
|
bottom: bottom.isNaN ? null : bottom,
|
|
|
|
|
child: AnimatedScale(
|
|
|
|
|
scale: _isVisible ? 1 : 0,
|
|
|
|
|
duration: animationDuration,
|
|
|
|
|
curve: Curves.easeOutBack,
|
|
|
|
|
child: AnimatedOpacity(
|
|
|
|
|
opacity: _isVisible ? 1 : 0,
|
|
|
|
|
duration: animationDuration,
|
|
|
|
|
child: _Badge(
|
|
|
|
|
value: value,
|
|
|
|
|
maxValue: maxValue,
|
|
|
|
|
minSize: minSize,
|
|
|
|
|
backgroundColor: backgroundColor,
|
|
|
|
|
textColor: textColor,
|
|
|
|
|
textStyle: textStyle ??
|
|
|
|
|
Theme.of(context).textTheme.labelSmall?.copyWith(
|
|
|
|
|
fontWeight: FontWeight.w700,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class _Badge extends StatelessWidget {
|
|
|
|
|
final int value;
|
|
|
|
|
final int maxValue;
|
|
|
|
|
final double minSize;
|
|
|
|
|
final Color backgroundColor;
|
|
|
|
|
final Color textColor;
|
|
|
|
|
final TextStyle? textStyle;
|
|
|
|
|
|
|
|
|
|
const _Badge({
|
|
|
|
|
required this.value,
|
|
|
|
|
required this.maxValue,
|
|
|
|
|
required this.minSize,
|
|
|
|
|
required this.backgroundColor,
|
|
|
|
|
required this.textColor,
|
|
|
|
|
this.textStyle,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
bool get _isOverflow => value > maxValue;
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
|
final TextStyle baseStyle = (textStyle ?? Theme.of(context).textTheme.labelMedium)!.copyWith(
|
|
|
|
|
color: textColor,
|
|
|
|
|
fontWeight: FontWeight.w700,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
final double badgeSize = minSize;
|
|
|
|
|
|
|
|
|
|
return IgnorePointer(
|
|
|
|
|
child: SizedBox(
|
|
|
|
|
width: badgeSize,
|
|
|
|
|
height: badgeSize,
|
|
|
|
|
child: DecoratedBox(
|
|
|
|
|
decoration: const BoxDecoration(
|
|
|
|
|
shape: BoxShape.circle,
|
|
|
|
|
),
|
|
|
|
|
child: DecoratedBox(
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
color: backgroundColor,
|
|
|
|
|
shape: BoxShape.circle,
|
|
|
|
|
),
|
|
|
|
|
child: Center(
|
|
|
|
|
child: _isOverflow
|
|
|
|
|
? FittedBox(
|
|
|
|
|
child: Text(
|
|
|
|
|
'$maxValue+',
|
|
|
|
|
style: baseStyle.copyWith(
|
|
|
|
|
fontSize: badgeSize * 0.45,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
: CounterAnimatedText(
|
|
|
|
|
value: value,
|
|
|
|
|
style: baseStyle.copyWith(
|
|
|
|
|
fontSize: badgeSize * 0.6,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|