Skip to content

Commit

Permalink
3.1.0 (#109)
Browse files Browse the repository at this point in the history
* feat: add triangle badge shape (#107)

* feat: add triangle badge shape

* Add widget tests for triangle badge shape

* fix: set all custom shapes  to fixed-size proportions  (#108)

* Update custom painter for all custom shapes to set fixed-size proportions

* Return default value of child content for verified account widgets

* Resize the shape depending on the child widget in the same proportions

* Fix git check errors

* Resize all types of shapes depending on the size child widget

* Add method for calculate default badge content padding value

* Change method for calculate default badge content padding value

* Add unit tests for calculateBadgeContentPadding method

* Version bump to 3.1.0

---------

Co-authored-by: Vitaliy Hnidenko <[email protected]>
  • Loading branch information
yadaniyil and sawel24 authored Apr 11, 2023
1 parent 7182cf4 commit bdc035a
Show file tree
Hide file tree
Showing 13 changed files with 393 additions and 109 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## [3.1.0] - [April 11, 2023]
* Add BadgeShape.triangle
* Fix custom shapes deformation depending on the badge content

## [3.0.3] - [March 24, 2023]
* Fix transparent color for the badge

Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
In your pubspec.yaml
```yaml
dependencies:
badges: ^3.0.3
badges: ^3.1.0
```
Attention! In Flutter 3.7 the Badge widget was introduced in the Material library, so to escape the ambiguous imports you need to import the package like this:
```dart
Expand Down Expand Up @@ -104,6 +104,7 @@ From left to right:<br>
2) BadgeShape.square
3) BadgeShape.twitter
4) BadgeShape.instagram
5) BadgeShape.triangle
<br><br>

---
Expand Down
2 changes: 1 addition & 1 deletion example/.flutter-plugins-dependencies
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"integration_test","path":"/Users/yadaniyil/flutter/packages/integration_test/","native_build":true,"dependencies":[]}],"android":[{"name":"integration_test","path":"/Users/yadaniyil/flutter/packages/integration_test/","native_build":true,"dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"integration_test","dependencies":[]}],"date_created":"2023-03-24 12:03:15.082040","version":"3.7.6"}
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"integration_test","path":"/Users/yadaniyil/flutter/packages/integration_test/","native_build":true,"dependencies":[]}],"android":[{"name":"integration_test","path":"/Users/yadaniyil/flutter/packages/integration_test/","native_build":true,"dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"integration_test","dependencies":[]}],"date_created":"2023-04-11 18:51:47.132592","version":"3.7.9"}
23 changes: 16 additions & 7 deletions example/lib/alarm_app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,27 @@ class _AlarmAppState extends State<AlarmApp> {
@override
Widget build(BuildContext context) {
return badges.Badge(
badgeStyle: badges.BadgeStyle(padding: EdgeInsets.all(7)),
badgeStyle: badges.BadgeStyle(
borderSide: BorderSide(color: Colors.white, width: 2),
shape: badges.BadgeShape.triangle,
badgeGradient: badges.BadgeGradient.linear(
colors: [
Colors.red,
Colors.orange,
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
badgeAnimation: badges.BadgeAnimation.fade(
animationDuration: Duration(seconds: 1),
loopAnimation: _isLooped,
),
// onTap: () {
// setState(() => _isLooped = !_isLooped);
// },
ignorePointer: false,
// toAnimate: false,
badgeContent:
Text(counter.toString(), style: TextStyle(color: Colors.white)),
badgeContent: Text(
'!',
style: TextStyle(color: Colors.white),
),
position: badges.BadgePosition.topEnd(top: -12),
child: GestureDetector(
onTap: () {
Expand Down
125 changes: 79 additions & 46 deletions lib/src/badge.dart
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,21 @@ class BadgeState extends State<Badge> with TickerProviderStateMixin {
return _appearanceController.value;
}

EdgeInsets calculateBadgeContentPadding(
Widget? badgeContent,
BadgeShape shape,
) {
final isTextContent = badgeContent is Text;
final isTriangleShape = shape == BadgeShape.triangle;
if (isTriangleShape) {
return const EdgeInsets.symmetric(horizontal: 10.0);
} else if (isTextContent) {
return const EdgeInsets.symmetric(horizontal: 8.0);
} else {
return const EdgeInsets.symmetric(horizontal: 5.0);
}
}

Widget _getBadge() {
final border = widget.badgeStyle.shape == BadgeShape.circle
? CircleBorder(
Expand All @@ -157,7 +172,8 @@ class BadgeState extends State<Badge> with TickerProviderStateMixin {
borderRadius: widget.badgeStyle.borderRadius,
);
final isCustomShape = widget.badgeStyle.shape == BadgeShape.twitter ||
widget.badgeStyle.shape == BadgeShape.instagram;
widget.badgeStyle.shape == BadgeShape.instagram ||
widget.badgeStyle.shape == BadgeShape.triangle;

final gradientBorder = widget.badgeStyle.borderGradient != null
? BadgeBorderGradient(
Expand All @@ -173,52 +189,69 @@ class BadgeState extends State<Badge> with TickerProviderStateMixin {
builder: (context, child) {
return Opacity(
opacity: _getOpacity(),
child: isCustomShape
? CustomPaint(
painter: DrawingUtils.drawBadgeShape(
shape: widget.badgeStyle.shape,
color: widget.badgeStyle.badgeColor,
badgeGradient: widget.badgeStyle.badgeGradient,
borderGradient: widget.badgeStyle.borderGradient,
borderSide: widget.badgeStyle.borderSide,
),
child: Padding(
padding: widget.badgeStyle.padding,
child: widget.badgeContent,
),
)
: Material(
shape: border,
elevation: widget.badgeStyle.elevation,
// Without this Colors.transparent will be ignored
type: MaterialType.transparency,
child: AnimatedContainer(
curve: widget.badgeAnimation.colorChangeAnimationCurve,
duration: widget.badgeAnimation.toAnimate
? widget.badgeAnimation.colorChangeAnimationDuration
: Duration.zero,
decoration: widget.badgeStyle.shape == BadgeShape.circle
? BoxDecoration(
color: widget.badgeStyle.badgeColor,
border: gradientBorder,
gradient:
widget.badgeStyle.badgeGradient?.gradient(),
shape: BoxShape.circle,
)
: BoxDecoration(
color: widget.badgeStyle.badgeColor,
gradient:
widget.badgeStyle.badgeGradient?.gradient(),
shape: BoxShape.rectangle,
borderRadius: widget.badgeStyle.borderRadius,
border: gradientBorder,
child: UnconstrainedBox(
child: IntrinsicWidth(
child: AspectRatio(
aspectRatio:
widget.badgeStyle.shape == BadgeShape.square ? 1.5 : 1.0,
child: isCustomShape
? CustomPaint(
painter: DrawingUtils.drawBadgeShape(
shape: widget.badgeStyle.shape,
color: widget.badgeStyle.badgeColor,
badgeGradient: widget.badgeStyle.badgeGradient,
borderGradient: widget.badgeStyle.borderGradient,
borderSide: widget.badgeStyle.borderSide,
),
child: Padding(
padding: widget.badgeStyle.padding ??
calculateBadgeContentPadding(
widget.badgeContent,
widget.badgeStyle.shape,
),
child: Center(child: widget.badgeContent),
),
)
: Material(
shape: border,
elevation: widget.badgeStyle.elevation,
// Without this Colors.transparent will be ignored
type: MaterialType.transparency,
child: AnimatedContainer(
curve:
widget.badgeAnimation.colorChangeAnimationCurve,
duration: widget.badgeAnimation.toAnimate
? widget
.badgeAnimation.colorChangeAnimationDuration
: Duration.zero,
decoration: widget.badgeStyle.shape ==
BadgeShape.circle
? BoxDecoration(
color: widget.badgeStyle.badgeColor,
border: gradientBorder,
gradient: widget.badgeStyle.badgeGradient
?.gradient(),
shape: BoxShape.circle,
)
: BoxDecoration(
color: widget.badgeStyle.badgeColor,
gradient: widget.badgeStyle.badgeGradient
?.gradient(),
shape: BoxShape.rectangle,
borderRadius:
widget.badgeStyle.borderRadius,
border: gradientBorder,
),
child: Padding(
padding: widget.badgeStyle.padding ??
const EdgeInsets.symmetric(horizontal: 5.0),
child: Center(child: widget.badgeContent),
),
child: Padding(
padding: widget.badgeStyle.padding,
child: widget.badgeContent,
),
),
),
),
),
),
),
),
);
},
);
Expand Down
5 changes: 5 additions & 0 deletions lib/src/badge_shape.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:badges/badges.dart' as badges;
import 'package:badges/src/painters/triangle_badge_shape_painter.dart';
import 'package:flutter/material.dart';

/// Set of shapes that you can use for your [badges.Badge] widget.
Expand All @@ -15,6 +16,10 @@ enum BadgeShape {
/// * [RoundedRectangleBorder]
square,

/// To make the triangle badge .
/// See [TriangleBadgeShapePainter] for more details.
triangle,

/// To make the twitter badge .
/// See [TwitterBadgeShapePainter] for more details.
twitter,
Expand Down
4 changes: 2 additions & 2 deletions lib/src/badge_style.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class BadgeStyle {

/// Specifies padding for [badgeContent].
/// The default value is EdgeInsets.all(5.0).
final EdgeInsetsGeometry padding;
final EdgeInsetsGeometry? padding;

const BadgeStyle({
this.shape = BadgeShape.circle,
Expand All @@ -41,6 +41,6 @@ class BadgeStyle {
this.elevation = 2,
this.badgeGradient,
this.borderGradient,
this.padding = const EdgeInsets.all(5.0),
this.padding,
});
}
64 changes: 35 additions & 29 deletions lib/src/painters/instagram_badge_shape_painter.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:math' as math;

import 'package:badges/badges.dart';
import 'package:badges/src/utils/gradient_utils.dart';
import 'package:flutter/material.dart';
Expand All @@ -21,15 +23,19 @@ class InstagramBadgeShapePainter extends CustomPainter {
final width = size.width;
final height = size.height;

final double maxSize = math.max(width, height);

canvas.clipRect(Offset.zero & Size(maxSize, maxSize));

Path path = Path();
Paint paint = Paint();
Paint paintBorder = Paint();

if (badgeGradient != null) {
paint.shader = GradientUtils.getGradientShader(
badgeGradient: badgeGradient!,
width: width,
height: height,
width: maxSize,
height: maxSize,
);
}
paintBorder
Expand All @@ -41,36 +47,36 @@ class InstagramBadgeShapePainter extends CustomPainter {
if (borderGradient != null) {
paintBorder.shader = GradientUtils.getGradientShader(
badgeGradient: borderGradient!,
width: width,
height: height,
width: maxSize,
height: maxSize,
);
}

path.moveTo(width * 0.14, height * 0.14);
path.lineTo(width * 0.3, height * 0.14);
path.lineTo(width * 0.385, 0);
path.lineTo(width * 0.515, height * 0.08);
path.lineTo(width * 0.627, height * 0.012);
path.lineTo(width * 0.7, height * 0.134);
path.lineTo(width * 0.867, height * 0.134);
path.lineTo(width * 0.867, height * 0.3);
path.lineTo(width, height * 0.38);
path.lineTo(width * 0.922, height * 0.505);
path.lineTo(width * 0.995, height * 0.629);
path.lineTo(width * 0.866, height * 0.706);
path.lineTo(width * 0.866, height * 0.868);
path.lineTo(width * 0.697, height * 0.868);
path.lineTo(width * 0.618, height * 0.996);
path.lineTo(width * 0.5, height * 0.924);
path.lineTo(width * 0.379, height * 0.996);
path.lineTo(width * 0.302, height * 0.868);
path.lineTo(width * 0.14, height * 0.868);
path.lineTo(width * 0.14, height * 0.702);
path.lineTo(width * 0.004, height * 0.618);
path.lineTo(width * 0.08, height * 0.494);
path.lineTo(width * 0.012, height * 0.379);
path.lineTo(width * 0.14, height * 0.306);
path.lineTo(width * 0.14, height * 0.14);
path.moveTo(maxSize * 0.14, maxSize * 0.14);
path.lineTo(maxSize * 0.3, maxSize * 0.14);
path.lineTo(maxSize * 0.385, 0);
path.lineTo(maxSize * 0.515, maxSize * 0.08);
path.lineTo(maxSize * 0.627, maxSize * 0.012);
path.lineTo(maxSize * 0.7, maxSize * 0.134);
path.lineTo(maxSize * 0.867, maxSize * 0.134);
path.lineTo(maxSize * 0.867, maxSize * 0.3);
path.lineTo(maxSize, maxSize * 0.38);
path.lineTo(maxSize * 0.922, maxSize * 0.505);
path.lineTo(maxSize * 0.995, maxSize * 0.629);
path.lineTo(maxSize * 0.866, maxSize * 0.706);
path.lineTo(maxSize * 0.866, maxSize * 0.868);
path.lineTo(maxSize * 0.697, maxSize * 0.868);
path.lineTo(maxSize * 0.618, maxSize * 0.996);
path.lineTo(maxSize * 0.5, maxSize * 0.924);
path.lineTo(maxSize * 0.379, maxSize * 0.996);
path.lineTo(maxSize * 0.302, maxSize * 0.868);
path.lineTo(maxSize * 0.14, maxSize * 0.868);
path.lineTo(maxSize * 0.14, maxSize * 0.702);
path.lineTo(maxSize * 0.004, maxSize * 0.618);
path.lineTo(maxSize * 0.08, maxSize * 0.494);
path.lineTo(maxSize * 0.012, maxSize * 0.379);
path.lineTo(maxSize * 0.14, maxSize * 0.306);
path.lineTo(maxSize * 0.14, maxSize * 0.14);

paint.color = color!;
canvas.drawPath(path, paint);
Expand Down
Loading

0 comments on commit bdc035a

Please sign in to comment.