Compare commits

...

10 Commits

Author SHA1 Message Date
d601842da0
fix(treewide): migrate to sound null safety
Signed-off-by: Sphericalkat <me@kat.bio>
2024-07-02 11:43:07 +05:30
e7317c8a07
feat: fvm init
Signed-off-by: Sphericalkat <me@kat.bio>
2024-07-02 11:41:37 +05:30
Gustavo Bonifacio Rodrigues
9f1a8d0128
Update README.md 2021-11-19 18:35:53 -05:00
Gustavo Rodrigues
3193424f8f versioning 2021-03-08 18:33:21 -05:00
Gustavo Rodrigues
573844b0b0 refactor 2021-03-08 18:32:10 -05:00
Gustavo Rodrigues
69042fd27d oof 2021-03-08 16:38:50 -05:00
Gustavo Rodrigues
6281d24c64 refactoring 2021-03-08 16:34:34 -05:00
Gustavo Bonifacio Rodrigues
11cba09e30
Update pubspec.yaml 2021-03-08 13:22:40 -05:00
Gustavo Bonifacio Rodrigues
0d7db1c890
Update pubspec.yaml 2021-03-08 13:04:24 -05:00
Gustavo Rodrigues
c1ec946371 fix 2021-03-08 12:56:35 -05:00
17 changed files with 94 additions and 84 deletions

3
.fvmrc Normal file
View File

@ -0,0 +1,3 @@
{
"flutter": "2.8.0"
}

3
.gitignore vendored
View File

@ -14,3 +14,6 @@ ios/Flutter/Generated.xcconfig
ios/Runner/GeneratedPluginRegistrant.* ios/Runner/GeneratedPluginRegistrant.*
.history/ .history/
# FVM Version Cache
.fvm/

View File

@ -1,4 +1,8 @@
## [0.1.1] - 2021-03-08 ## [0.1.2] - 2021-03-08
* Readme update
## [0.1.1-2] - 2021-03-08
* small improvement
## [0.1.1-0] - 2021-03-08
* removed deprecated call on `AnimatedCircularChartState` * removed deprecated call on `AnimatedCircularChartState`
## [0.1.0] - 2018-08-30 ## [0.1.0] - 2018-08-30

View File

@ -3,10 +3,10 @@
# Flutter Circular Chart # Flutter Circular Chart
This library is a fork of the original [flutter_circular_chart](https://pub.dartlang.org/packages/flutter_circular_chart) This library is a fork of the original [flutter_circular_chart](https://pub.dartlang.org/packages/flutter_circular_chart)
This provides fix and will keep updating based on user PR
A library for creating animated circular chart widgets with Flutter, inspired by [Zero to One with Flutter](https://medium.com/dartlang/zero-to-one-with-flutter-43b13fd7b354). This provides fix and will keep updating based on user PR, including help the migration to null-safety.
## Overview ## Overview
The original package provides the context The original package source can be found here: [flutter_circular_chart](https://pub.dartlang.org/packages/flutter_circular_chart)
[flutter_circular_chart](https://pub.dartlang.org/packages/flutter_circular_chart)
This package is abbandoned and no support is being planned. Fork, and publish as you wish with the referenc to the original. PRs will be refused.

View File

@ -57,7 +57,7 @@ class _AnimatedPieChartExampleState extends State<AnimatedPieChartExample> {
setState(() { setState(() {
sampleIndex++; sampleIndex++;
List<CircularStackEntry> data = _quarterlyProfitPieData[sampleIndex % 3]; List<CircularStackEntry> data = _quarterlyProfitPieData[sampleIndex % 3];
_chartKey.currentState.updateData(data); _chartKey.currentState!.updateData(data);
}); });
} }

View File

@ -17,13 +17,13 @@ class _AnimatedRadialChartExampleState extends State<AnimatedRadialChartExample>
final _chartSize = const Size(200.0, 200.0); final _chartSize = const Size(200.0, 200.0);
double value = 50.0; double value = 50.0;
Color labelColor = Colors.blue[200]; Color? labelColor = Colors.blue[200];
void _increment() { void _increment() {
setState(() { setState(() {
value += 10; value += 10;
List<CircularStackEntry> data = _generateChartData(value); List<CircularStackEntry> data = _generateChartData(value);
_chartKey.currentState.updateData(data); _chartKey.currentState!.updateData(data);
}); });
} }
@ -31,12 +31,12 @@ class _AnimatedRadialChartExampleState extends State<AnimatedRadialChartExample>
setState(() { setState(() {
value -= 10; value -= 10;
List<CircularStackEntry> data = _generateChartData(value); List<CircularStackEntry> data = _generateChartData(value);
_chartKey.currentState.updateData(data); _chartKey.currentState!.updateData(data);
}); });
} }
List<CircularStackEntry> _generateChartData(double value) { List<CircularStackEntry> _generateChartData(double value) {
Color dialColor = Colors.blue[200]; Color? dialColor = Colors.blue[200];
if (value < 0) { if (value < 0) {
dialColor = Colors.red[200]; dialColor = Colors.red[200];
} else if (value < 50) { } else if (value < 50) {
@ -78,7 +78,7 @@ class _AnimatedRadialChartExampleState extends State<AnimatedRadialChartExample>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
TextStyle _labelStyle = TextStyle _labelStyle =
Theme.of(context).textTheme.headline6.merge(TextStyle(color: labelColor)); Theme.of(context).textTheme.headline6!.merge(TextStyle(color: labelColor));
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(

View File

@ -19,7 +19,7 @@ class _RandomizedRadialChartExampleState extends State<RandomizedRadialChartExam
final GlobalKey<AnimatedCircularChartState> _chartKey = GlobalKey<AnimatedCircularChartState>(); final GlobalKey<AnimatedCircularChartState> _chartKey = GlobalKey<AnimatedCircularChartState>();
final _chartSize = const Size(300.0, 300.0); final _chartSize = const Size(300.0, 300.0);
final Math.Random random = Math.Random(); final Math.Random random = Math.Random();
List<CircularStackEntry> data; List<CircularStackEntry>? data;
@override @override
void initState() { void initState() {
@ -32,7 +32,7 @@ class _RandomizedRadialChartExampleState extends State<RandomizedRadialChartExam
void _randomize() { void _randomize() {
setState(() { setState(() {
data = _generateRandomData(); data = _generateRandomData();
_chartKey.currentState.updateData(data); _chartKey.currentState!.updateData(data!);
}); });
} }
@ -41,7 +41,7 @@ class _RandomizedRadialChartExampleState extends State<RandomizedRadialChartExam
List<CircularStackEntry> data = List.generate(stackCount, (i) { List<CircularStackEntry> data = List.generate(stackCount, (i) {
int segCount = random.nextInt(10); int segCount = random.nextInt(10);
List<CircularSegmentEntry> segments = List.generate(segCount, (j) { List<CircularSegmentEntry> segments = List.generate(segCount, (j) {
Color randomColor = ColorPalette.primary.random(random); Color? randomColor = ColorPalette.primary.random(random);
return CircularSegmentEntry(random.nextDouble(), randomColor); return CircularSegmentEntry(random.nextDouble(), randomColor);
}); });
return CircularStackEntry(segments); return CircularStackEntry(segments);

View File

@ -3,7 +3,7 @@ import 'dart:math';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class ColorPalette { class ColorPalette {
static final ColorPalette primary = ColorPalette(<Color>[ static final ColorPalette primary = ColorPalette(<Color?>[
Colors.blue[400], Colors.blue[400],
Colors.blue[200], Colors.blue[200],
Colors.red[400], Colors.red[400],
@ -21,15 +21,15 @@ class ColorPalette {
Colors.black, Colors.black,
]); ]);
ColorPalette(List<Color> colors) : _colors = colors { ColorPalette(List<Color?> colors) : _colors = colors {
assert(colors.isNotEmpty); assert(colors.isNotEmpty);
} }
final List<Color> _colors; final List<Color?> _colors;
Color operator [](int index) => _colors[index % length]; Color? operator [](int index) => _colors[index % length];
int get length => _colors.length; int get length => _colors.length;
Color random(Random random) => this[random.nextInt(length)]; Color? random(Random random) => this[random.nextInt(length)];
} }

View File

@ -25,9 +25,9 @@ enum SegmentEdgeStyle {
class AnimatedCircularChart extends StatefulWidget { class AnimatedCircularChart extends StatefulWidget {
AnimatedCircularChart({ AnimatedCircularChart({
Key key, Key? key,
@required this.size, required this.size,
@required this.initialChartData, required this.initialChartData,
this.chartType = CircularChartType.Radial, this.chartType = CircularChartType.Radial,
this.duration = _kDuration, this.duration = _kDuration,
this.percentageValues = false, this.percentageValues = false,
@ -51,7 +51,7 @@ class AnimatedCircularChart extends StatefulWidget {
/// will be grouped together as concentric circles. /// will be grouped together as concentric circles.
/// ///
/// If [chartType] is [CircularChartType.Pie] then length cannot be > 1. /// If [chartType] is [CircularChartType.Pie] then length cannot be > 1.
final List<CircularStackEntry> initialChartData; final List<CircularStackEntry>? initialChartData;
/// The type of chart to be rendered. /// The type of chart to be rendered.
/// Use [CircularChartType.Pie] for a circle divided into slices for each entry. /// Use [CircularChartType.Pie] for a circle divided into slices for each entry.
@ -76,7 +76,7 @@ class AnimatedCircularChart extends StatefulWidget {
/// be automatically calculated to accommodate all the data. /// be automatically calculated to accommodate all the data.
/// ///
/// Has no effect in [CircularChartType.Pie] charts. /// Has no effect in [CircularChartType.Pie] charts.
final double holeRadius; final double? holeRadius;
/// The chart gets drawn and animates clockwise from [startAngle], defaulting to the /// The chart gets drawn and animates clockwise from [startAngle], defaulting to the
/// top/center point or -90.0. In terms of a clock face these would be: /// top/center point or -90.0. In terms of a clock face these would be:
@ -92,13 +92,13 @@ class AnimatedCircularChart extends StatefulWidget {
/// in the center of the chart's hole. /// in the center of the chart's hole.
/// ///
/// See also [labelStyle] which is used to render the label. /// See also [labelStyle] which is used to render the label.
final String holeLabel; final String? holeLabel;
/// The style used when rendering the [holeLabel]. /// The style used when rendering the [holeLabel].
/// ///
/// Defaults to the active [ThemeData]'s /// Defaults to the active [ThemeData]'s
/// [ThemeData.textTheme.body2] text style. /// [ThemeData.textTheme.body2] text style.
final TextStyle labelStyle; final TextStyle? labelStyle;
/// The type of segment edges to be drawn. /// The type of segment edges to be drawn.
/// ///
@ -113,11 +113,11 @@ class AnimatedCircularChart extends StatefulWidget {
/// ```dart /// ```dart
/// AnimatedCircularChartState animatedCircularChart = AnimatedCircularChart.of(context); /// AnimatedCircularChartState animatedCircularChart = AnimatedCircularChart.of(context);
/// ``` /// ```
static AnimatedCircularChartState of(BuildContext context, {bool nullOk: false}) { static AnimatedCircularChartState? of(BuildContext context, {bool nullOk: false}) {
assert(context != null); assert(context != null);
assert(nullOk != null); assert(nullOk != null);
final AnimatedCircularChartState result = final AnimatedCircularChartState? result =
context.findAncestorStateOfType<AnimatedCircularChartState>(); context.findAncestorStateOfType<AnimatedCircularChartState>();
if (nullOk || result != null) return result; if (nullOk || result != null) return result;
@ -151,10 +151,10 @@ class AnimatedCircularChart extends StatefulWidget {
/// ``` /// ```
class AnimatedCircularChartState extends State<AnimatedCircularChart> class AnimatedCircularChartState extends State<AnimatedCircularChart>
with TickerProviderStateMixin { with TickerProviderStateMixin {
CircularChartTween _tween; late CircularChartTween _tween;
AnimationController _animation; late AnimationController _animation;
final Map<String, int> _stackRanks = <String, int>{}; final Map<String?, int> _stackRanks = <String?, int>{};
final Map<String, int> _entryRanks = <String, int>{}; final Map<String?, int> _entryRanks = <String?, int>{};
final TextPainter _labelPainter = TextPainter(); final TextPainter _labelPainter = TextPainter();
@override @override
@ -165,13 +165,13 @@ class AnimatedCircularChartState extends State<AnimatedCircularChart>
vsync: this, vsync: this,
); );
_assignRanks(widget.initialChartData); _assignRanks(widget.initialChartData!);
_tween = CircularChartTween( _tween = CircularChartTween(
CircularChart.empty(chartType: widget.chartType), CircularChart.empty(chartType: widget.chartType),
CircularChart.fromData( CircularChart.fromData(
size: widget.size, size: widget.size,
data: widget.initialChartData, data: widget.initialChartData!,
chartType: widget.chartType, chartType: widget.chartType,
stackRanks: _stackRanks, stackRanks: _stackRanks,
entryRanks: _entryRanks, entryRanks: _entryRanks,
@ -215,7 +215,7 @@ class AnimatedCircularChartState extends State<AnimatedCircularChart>
void _updateLabelPainter() { void _updateLabelPainter() {
if (widget.holeLabel != null) { if (widget.holeLabel != null) {
TextStyle _labelStyle = widget.labelStyle ?? Theme.of(context).textTheme.bodyText1; TextStyle? _labelStyle = widget.labelStyle ?? Theme.of(context).textTheme.bodyText1;
_labelPainter _labelPainter
..text = TextSpan(style: _labelStyle, text: widget.holeLabel) ..text = TextSpan(style: _labelStyle, text: widget.holeLabel)
..textDirection = Directionality.of(context) ..textDirection = Directionality.of(context)

View File

@ -17,22 +17,22 @@ class CircularChart {
final List<CircularChartStack> stacks; final List<CircularChartStack> stacks;
final CircularChartType chartType; final CircularChartType chartType;
final SegmentEdgeStyle edgeStyle; final SegmentEdgeStyle? edgeStyle;
factory CircularChart.empty({@required CircularChartType chartType}) { factory CircularChart.empty({required CircularChartType chartType}) {
return CircularChart(<CircularChartStack>[], chartType); return CircularChart(<CircularChartStack>[], chartType);
} }
factory CircularChart.fromData({ factory CircularChart.fromData({
@required Size size, required Size size,
@required List<CircularStackEntry> data, required List<CircularStackEntry> data,
@required CircularChartType chartType, required CircularChartType chartType,
@required bool percentageValues, required bool percentageValues,
@required double startAngle, required double startAngle,
Map<String, int> stackRanks, Map<String?, int>? stackRanks,
Map<String, int> entryRanks, Map<String?, int>? entryRanks,
double holeRadius, double? holeRadius,
SegmentEdgeStyle edgeStyle, SegmentEdgeStyle? edgeStyle,
}) { }) {
final double _holeRadius = holeRadius ?? size.width / (2 + data.length); final double _holeRadius = holeRadius ?? size.width / (2 + data.length);
final double stackDistance = (size.width / 2 - _holeRadius) / (2 + data.length); final double stackDistance = (size.width / 2 - _holeRadius) / (2 + data.length);
@ -42,7 +42,7 @@ class CircularChart {
List<CircularChartStack> stacks = List<CircularChartStack>.generate( List<CircularChartStack> stacks = List<CircularChartStack>.generate(
data.length, data.length,
(i) => CircularChartStack.fromData( (i) => CircularChartStack.fromData(
stackRanks[data[i].rankKey] ?? i, stackRanks![data[i].rankKey] ?? i,
data[i].entries, data[i].entries,
entryRanks, entryRanks,
percentageValues, percentageValues,
@ -66,7 +66,7 @@ class CircularChartTween extends Tween<CircularChart> {
@override @override
CircularChart lerp(double t) => CircularChart( CircularChart lerp(double t) => CircularChart(
_stacksTween.lerp(t), _stacksTween.lerp(t),
begin.chartType, begin!.chartType,
edgeStyle: end.edgeStyle, edgeStyle: end!.edgeStyle,
); );
} }

View File

@ -19,11 +19,11 @@ class CircularSegmentEntry {
final double value; final double value;
/// The color drawn in the stack for this segment. /// The color drawn in the stack for this segment.
final Color color; final Color? color;
/// An optional String key, used when animating charts to preserve semantics when /// An optional String key, used when animating charts to preserve semantics when
/// transitioning between data points. /// transitioning between data points.
final String rankKey; final String? rankKey;
String toString() { String toString() {
return '$rankKey: $value $color'; return '$rankKey: $value $color';
@ -45,5 +45,5 @@ class CircularStackEntry {
/// An optional String key, used when animating charts to preserve semantics when /// An optional String key, used when animating charts to preserve semantics when
/// transitioning between data points. /// transitioning between data points.
final String rankKey; final String? rankKey;
} }

View File

@ -9,7 +9,7 @@ class AnimatedCircularChartPainter extends CustomPainter {
AnimatedCircularChartPainter(this.animation, this.labelPainter) : super(repaint: animation); AnimatedCircularChartPainter(this.animation, this.labelPainter) : super(repaint: animation);
final Animation<CircularChart> animation; final Animation<CircularChart> animation;
final TextPainter labelPainter; final TextPainter? labelPainter;
@override @override
void paint(Canvas canvas, Size size) { void paint(Canvas canvas, Size size) {
@ -39,7 +39,7 @@ class CircularChartPainter extends CustomPainter {
const double _kRadiansPerDegree = Math.pi / 180; const double _kRadiansPerDegree = Math.pi / 180;
void _paintLabel(Canvas canvas, Size size, TextPainter labelPainter) { void _paintLabel(Canvas canvas, Size size, TextPainter? labelPainter) {
if (labelPainter != null) { if (labelPainter != null) {
labelPainter.paint( labelPainter.paint(
canvas, canvas,
@ -59,16 +59,16 @@ void _paintChart(Canvas canvas, Size size, CircularChart chart) {
for (final CircularChartStack stack in chart.stacks) { for (final CircularChartStack stack in chart.stacks) {
for (final segment in stack.segments) { for (final segment in stack.segments) {
segmentPaint.color = segment.color; segmentPaint.color = segment.color!;
segmentPaint.strokeWidth = stack.width; segmentPaint.strokeWidth = stack.width!;
canvas.drawArc( canvas.drawArc(
Rect.fromCircle( Rect.fromCircle(
center: Offset(size.width / 2, size.height / 2), center: Offset(size.width / 2, size.height / 2),
radius: stack.radius, radius: stack.radius!,
), ),
stack.startAngle * _kRadiansPerDegree, stack.startAngle! * _kRadiansPerDegree,
segment.sweepAngle * _kRadiansPerDegree, segment.sweepAngle! * _kRadiansPerDegree,
chart.chartType == CircularChartType.Pie, chart.chartType == CircularChartType.Pie,
segmentPaint, segmentPaint,
); );

View File

@ -7,8 +7,8 @@ class CircularChartSegment extends MergeTweenable<CircularChartSegment> {
CircularChartSegment(this.rank, this.sweepAngle, this.color); CircularChartSegment(this.rank, this.sweepAngle, this.color);
final int rank; final int rank;
final double sweepAngle; final double? sweepAngle;
final Color color; final Color? color;
@override @override
CircularChartSegment get empty => CircularChartSegment(rank, 0.0, color); CircularChartSegment get empty => CircularChartSegment(rank, 0.0, color);
@ -38,5 +38,5 @@ class CircularChartSegmentTween extends Tween<CircularChartSegment> {
} }
@override @override
CircularChartSegment lerp(double t) => CircularChartSegment.lerp(begin, end, t); CircularChartSegment lerp(double t) => CircularChartSegment.lerp(begin!, end!, t);
} }

View File

@ -17,15 +17,15 @@ class CircularChartStack implements MergeTweenable<CircularChartStack> {
); );
final int rank; final int rank;
final double radius; final double? radius;
final double width; final double? width;
final double startAngle; final double? startAngle;
final List<CircularChartSegment> segments; final List<CircularChartSegment> segments;
factory CircularChartStack.fromData( factory CircularChartStack.fromData(
int stackRank, int stackRank,
List<CircularSegmentEntry> entries, List<CircularSegmentEntry> entries,
Map<String, int> entryRanks, Map<String?, int>? entryRanks,
bool percentageValues, bool percentageValues,
double startRadius, double startRadius,
double stackWidth, double stackWidth,
@ -42,7 +42,7 @@ class CircularChartStack implements MergeTweenable<CircularChartStack> {
List<CircularChartSegment> segments = List<CircularChartSegment>.generate(entries.length, (i) { List<CircularChartSegment> segments = List<CircularChartSegment>.generate(entries.length, (i) {
double sweepAngle = (entries[i].value / valueSum * _kMaxAngle) + previousSweepAngle; double sweepAngle = (entries[i].value / valueSum * _kMaxAngle) + previousSweepAngle;
previousSweepAngle = sweepAngle; previousSweepAngle = sweepAngle;
int rank = entryRanks[entries[i].rankKey] ?? i; int rank = entryRanks![entries[i].rankKey] ?? i;
return CircularChartSegment(rank, sweepAngle, entries[i].color); return CircularChartSegment(rank, sweepAngle, entries[i].color);
}); });
@ -78,10 +78,10 @@ class CircularChartStackTween extends Tween<CircularChartStack> {
@override @override
CircularChartStack lerp(double t) => CircularChartStack( CircularChartStack lerp(double t) => CircularChartStack(
begin.rank, begin!.rank,
lerpDouble(begin.radius, end.radius, t), lerpDouble(begin!.radius, end!.radius, t),
lerpDouble(begin.width, end.width, t), lerpDouble(begin!.width, end!.width, t),
lerpDouble(begin.startAngle, end.startAngle, t), lerpDouble(begin!.startAngle, end!.startAngle, t),
_circularSegmentsTween.lerp(t), _circularSegmentsTween.lerp(t),
); );
} }

View File

@ -7,7 +7,7 @@ packages:
name: async name: async
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.5.0" version: "2.8.2"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
@ -21,14 +21,14 @@ packages:
name: characters name: characters
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.2.0"
charcode: charcode:
dependency: transitive dependency: transitive
description: description:
name: charcode name: charcode
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0" version: "1.3.1"
clock: clock:
dependency: transitive dependency: transitive
description: description:
@ -66,14 +66,14 @@ packages:
name: matcher name: matcher
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.12.10" version: "0.12.11"
meta: meta:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.0" version: "1.7.0"
path: path:
dependency: transitive dependency: transitive
description: description:
@ -92,7 +92,7 @@ packages:
name: source_span name: source_span
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.0" version: "1.8.1"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
@ -127,7 +127,7 @@ packages:
name: test_api name: test_api
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.2.19" version: "0.4.3"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
@ -141,6 +141,6 @@ packages:
name: vector_math name: vector_math
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0" version: "2.1.1"
sdks: sdks:
dart: ">=2.12.0-0.0 <3.0.0" dart: ">=2.14.0 <3.0.0"

View File

@ -1,7 +1,7 @@
name: flutter_circular_chart_two name: flutter_circular_chart_two
description: Animated radial and pie charts for Flutter. Forked from https://github.com/xqwzts/flutter_circular_chart description: Animated radial and pie charts for Flutter. Forked from https://github.com/xqwzts/flutter_circular_chart
version: 0.1.1-0 version: "0.1.2"
homepage: https://github.com/GusRodrigues86/circular_charts homepage: https://github.com/GusRodrigues86/flutter_circular_chart
dependencies: dependencies:
flutter: flutter:
@ -12,4 +12,4 @@ dev_dependencies:
sdk: flutter sdk: flutter
environment: environment:
sdk: ">=2.0.0 <3.0.0" sdk: '>=2.12.0 <3.0.0'