Skip to content

Commit 6e6f7dd

Browse files
committed
Bubble Sort Animated
1 parent 00aa78c commit 6e6f7dd

2 files changed

Lines changed: 133 additions & 119 deletions

File tree

lib/src/simulations/bubble_sort.dart

Lines changed: 132 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'dart:math';
22
import 'dart:io';
33
import 'package:flutter/material.dart';
4+
import 'package:flutter/rendering.dart';
45
import 'package:flutter/services.dart';
56
import 'package:flutter_screenutil/flutter_screenutil.dart';
67

@@ -10,24 +11,25 @@ class BubbleSortBars extends StatefulWidget {
1011
}
1112

1213
class _BubbleSortBarsState extends State<BubbleSortBars> {
13-
int _numberOfElements;
14+
int _numberOfElements = 5;
1415
List<int> _elements = [];
1516
int i = 0, counter = 0;
16-
int n;
17-
int tmp, delay = 0, delay2 = 0;
18-
bool swap = false;
19-
double barwidth;
20-
List<Widget> containerList = [];
21-
bool doNotRefresh = false;
22-
int finalIterator = 0;
17+
int n = 5;
18+
int delay = 500, delay2 = 500;
19+
bool animating = false;
20+
bool sorted = false;
21+
double barwidth = 0;
22+
bool refresh = true, resetIndex = true;
23+
List<dynamic> barColor = [];
24+
List<int> _index = [];
2325

2426
@override
2527
void initState() {
26-
_numberOfElements = 2;
28+
_numberOfElements = 5;
2729
i = 0;
2830
counter = 0;
29-
swap = false;
30-
doNotRefresh = false;
31+
animating = false;
32+
refresh = true;
3133
SystemChrome.setPreferredOrientations([
3234
DeviceOrientation.portraitUp,
3335
DeviceOrientation.portraitDown,
@@ -46,82 +48,59 @@ class _BubbleSortBarsState extends State<BubbleSortBars> {
4648
super.dispose();
4749
}
4850

49-
_containerList() {
50-
containerList.clear();
51-
if (!doNotRefresh) {
51+
_initialize() {
52+
if (refresh) {
53+
barColor.clear();
5254
_elements.clear();
55+
_index.clear();
5356
i = 0;
5457
var rng = new Random();
5558
for (int i = 0; i < _numberOfElements; i++) {
5659
_elements.add(rng.nextInt(400));
60+
_index.add(i);
61+
barColor.add(Theme.of(context).primaryColor);
5762
}
5863
n = _elements.length;
5964
}
6065
this.barwidth = MediaQuery.of(context).size.width / (_elements.length + 1);
61-
if (n != 1) {
62-
for (int k = 0; k < _elements.length; ++k) {
63-
if (k == i) {
64-
containerList.add(Container(
65-
color: Colors.red,
66-
height: _elements[k] + 0.5,
67-
width: barwidth,
68-
));
69-
} else if (k == i - 1) {
70-
containerList.add(Container(
71-
color: Colors.blue,
72-
height: _elements[k] + 0.5,
73-
width: barwidth,
74-
));
75-
} else {
76-
containerList.add(Container(
77-
color: Theme.of(context).primaryColor,
78-
height: _elements[k] + 0.5,
79-
width: barwidth,
80-
));
81-
}
82-
}
83-
} else {
84-
containerList.clear();
85-
finalIterator++;
86-
87-
for (int k = 0; k < _elements.length; ++k) {
88-
if (k <= finalIterator) {
89-
containerList.add(Container(
90-
color: Colors.greenAccent[400],
91-
height: _elements[k] + 0.5,
92-
width: barwidth,
93-
));
94-
} else {
95-
containerList.add(Container(
96-
color: Theme.of(context).primaryColor,
97-
height: _elements[k] + 0.5,
98-
width: barwidth,
99-
));
100-
}
101-
}
102-
if (finalIterator == _elements.length) {
103-
finalIterator = 0;
104-
}
105-
}
10666
}
10767

108-
nextStep() {
109-
sleep(Duration(milliseconds: delay));
68+
nextStep() async {
69+
await Future.delayed(Duration(milliseconds: delay));
11070
setState(() {
71+
barColor.clear();
72+
for (int j = 0; j < _elements.length; j++) {
73+
if (n == 1)
74+
barColor.add(Colors.greenAccent[400]);
75+
else
76+
barColor.add(Theme.of(context).primaryColor);
77+
if (resetIndex) _index[j] = j;
78+
}
11179
if (n == 1) {
112-
swap = false;
80+
animating = false;
11381
return;
11482
}
11583
counter++;
11684
if (i == n - 1) {
11785
i = 0;
11886
n--;
11987
}
88+
barColor[i] = Colors.blue;
12089
if (_elements[i] > _elements[i + 1]) {
121-
tmp = _elements[i];
122-
_elements[i] = _elements[i + 1];
123-
_elements[i + 1] = tmp;
124-
i++;
90+
if (resetIndex) {
91+
resetIndex = false;
92+
} else {
93+
barColor[i] = Colors.red;
94+
barColor[i + 1] = Colors.red;
95+
final temp = _index[i];
96+
_index[i] = _index[i + 1];
97+
_index[i + 1] = temp;
98+
final tmp = _elements[i];
99+
_elements[i] = _elements[i + 1];
100+
_elements[i + 1] = tmp;
101+
i++;
102+
resetIndex = true;
103+
}
125104
} else {
126105
i++;
127106
}
@@ -132,15 +111,16 @@ class _BubbleSortBarsState extends State<BubbleSortBars> {
132111
Widget build(BuildContext context) {
133112
ScreenUtil.init(
134113
context,
135-
width: 512.0,
136-
height: 1024.0,
114+
width: 720.0,
115+
height: 1600.0,
137116
allowFontScaling: true,
138117
);
139-
_containerList();
140-
if (swap == true || finalIterator != 0) {
141-
WidgetsBinding.instance.addPostFrameCallback((_) => nextStep());
118+
_initialize();
119+
if (animating) {
120+
WidgetsBinding.instance.addPostFrameCallback((_) {
121+
nextStep();
122+
});
142123
}
143-
144124
return Scaffold(
145125
appBar: AppBar(
146126
automaticallyImplyLeading: false,
@@ -150,50 +130,81 @@ class _BubbleSortBarsState extends State<BubbleSortBars> {
150130
Navigator.pop(context);
151131
},
152132
),
153-
centerTitle: true,
154133
title: Text(
155134
'Bubble Sort',
156135
style: Theme.of(context).textTheme.headline6,
157136
),
137+
centerTitle: true,
158138
),
159-
floatingActionButton: FloatingActionButton(
160-
backgroundColor: Colors.white,
161-
child: (!swap)
162-
? Icon(
163-
Icons.play_arrow,
164-
color: Colors.black,
165-
)
166-
: Icon(
167-
Icons.pause,
168-
color: Colors.black,
169-
),
170-
onPressed: () {
171-
doNotRefresh = true;
172-
swap = !swap;
173-
setState(() {});
174-
}),
175139
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
140+
floatingActionButton: Padding(
141+
padding: const EdgeInsets.all(8.0),
142+
child: Row(
143+
mainAxisAlignment: MainAxisAlignment.spaceBetween,
144+
children: <Widget>[
145+
FloatingActionButton(
146+
heroTag: null,
147+
backgroundColor: Colors.white,
148+
child: (!animating)
149+
? Icon(
150+
Icons.play_arrow,
151+
color: Colors.black,
152+
)
153+
: Icon(
154+
Icons.pause,
155+
color: Colors.black,
156+
),
157+
onPressed: () {
158+
setState(() {
159+
refresh = false;
160+
animating = !animating;
161+
});
162+
}),
163+
FloatingActionButton(
164+
heroTag: null,
165+
backgroundColor: Colors.white,
166+
child: Icon(
167+
Icons.highlight_off,
168+
color: Colors.black,
169+
),
170+
onPressed: () {
171+
setState(() {
172+
counter = 0;
173+
i = 0;
174+
refresh = true;
175+
animating = false;
176+
_initialize();
177+
});
178+
},
179+
)
180+
],
181+
),
182+
),
176183
bottomNavigationBar: Container(
177-
height: ScreenUtil().setHeight(1024/5.0),
184+
height: ScreenUtil().setHeight(1600 / 4.0),
178185
child: Material(
179186
elevation: 30,
180187
color: Theme.of(context).primaryColor,
181-
child: Column(
188+
child: ListView(
189+
padding: EdgeInsets.all(8.0),
182190
children: <Widget>[
183-
Spacer(flex: 2),
191+
SizedBox(
192+
height: 30,
193+
),
184194
Slider(
185-
min: 2,
186-
max: 200,
195+
min: 5,
196+
max: 100,
187197
activeColor: Theme.of(context).accentColor,
188198
inactiveColor: Colors.grey,
189-
onChanged: (value) {
190-
doNotRefresh = false;
191-
counter = 0;
192-
swap = false;
193-
setState(() {
194-
_numberOfElements = value.toInt();
195-
});
196-
},
199+
onChanged: (animating)
200+
? null
201+
: (value) {
202+
refresh = true;
203+
counter = 0;
204+
setState(() {
205+
_numberOfElements = value.toInt();
206+
});
207+
},
197208
value: _numberOfElements.toDouble(),
198209
),
199210
Center(
@@ -205,13 +216,10 @@ class _BubbleSortBarsState extends State<BubbleSortBars> {
205216
),
206217
),
207218
),
208-
Spacer(
209-
flex: 1,
210-
),
211219
Slider(
212220
min: 0,
213-
max: 100,
214-
divisions: 10,
221+
max: 2000,
222+
divisions: 8,
215223
activeColor: Theme.of(context).accentColor,
216224
inactiveColor: Colors.grey,
217225
onChanged: (value) {
@@ -221,39 +229,45 @@ class _BubbleSortBarsState extends State<BubbleSortBars> {
221229
},
222230
onChangeEnd: (value) {
223231
setState(() {
224-
doNotRefresh = true;
232+
refresh = false;
225233
delay = value.toInt();
226234
});
227235
},
228236
value: delay2.roundToDouble(),
229237
),
230238
Center(
231239
child: Text(
232-
"Delay: ${delay2.toInt()} ms",
240+
"Delay: ${delay2 / 1000.toInt()} s",
233241
style: TextStyle(
234242
fontSize: 18,
235243
fontFamily: 'Ubuntu',
236244
),
237245
),
238246
),
239-
Spacer(),
240247
],
241248
),
242249
),
243250
),
244251
body: Stack(
245252
children: <Widget>[
246253
Container(
247-
color: Colors.grey[900],
248-
child: Column(
254+
color: Theme.of(context).accentColor,
255+
child: Stack(
249256
children: <Widget>[
250-
Spacer(),
251-
Row(
252-
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
253-
children: containerList,
254-
),
255-
Spacer(),
257+
for (var k = 0; k < _elements.length; k++)
258+
AnimatedPositioned(
259+
duration: Duration(milliseconds: delay),
260+
left: _index[k] * barwidth +
261+
((_index[k] + 1) * barwidth / (_numberOfElements + 1)),
262+
curve: Curves.elasticOut,
263+
child: Container(
264+
color: barColor[k],
265+
height: _elements[_index[k]] + 0.5,
266+
width: barwidth,
267+
),
268+
),
256269
],
270+
alignment: AlignmentDirectional.center,
257271
),
258272
),
259273
Positioned(

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ description: A new Flutter project.
1414
version: 1.0.0+1
1515

1616
environment:
17-
sdk: ">=2.1.0 <3.0.0"
17+
sdk: ">=2.2.2 <3.0.0"
1818

1919
dependencies:
2020
flutter:

0 commit comments

Comments
 (0)