├── .github
└── workflows
│ └── dart.yml
├── .gitignore
├── README.md
├── flutter-counter.iml
├── gif
└── App.gif
├── lib
├── example
│ └── example.dart
├── src
│ └── stepper.dart
└── stepper_touch.dart
├── pubspec.lock
└── pubspec.yaml
/.github/workflows/dart.yml:
--------------------------------------------------------------------------------
1 | name: Dart CI
2 |
3 | on: [push]
4 |
5 | jobs:
6 | build:
7 |
8 | runs-on: x64
9 |
10 | container:
11 | image: google/dart:latest
12 |
13 | steps:
14 | - uses: actions/checkout@v1
15 | - name: Install dependencies
16 | run: pub get
17 | - name: Run tests
18 | run: pub run test
19 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .dart_tool/
3 | .gradle
4 | .packages
5 | .pub/
6 | build/
7 | ios/.generated/
8 | ios/Flutter/Generated.xcconfig
9 | ios/Runner/GeneratedPluginRegistrant.*
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Flutter Counter App
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Just an Counter UI using Flutter
10 |
11 | # UI
12 | 
13 |
14 | # Thank _You_!
15 | Please :star: this repo and share it with others
16 |
17 | ### Created By
18 |
19 | * [Raj Chowdhury](https://github.com/Rajchowdhury420)
20 |
--------------------------------------------------------------------------------
/flutter-counter.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/gif/App.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RajChowdhury240/Flutter-Counter-App/a62c8a1b6e239a4dd84f2cc4872fe241567d1fdb/gif/App.gif
--------------------------------------------------------------------------------
/lib/example/example.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:stepper_touch/stepper_touch.dart';
4 |
5 | void main() => runApp(
6 | MaterialApp(
7 | theme: ThemeData(
8 | scaffoldBackgroundColor: const Color(0xFF6D72FF),
9 | ),
10 | home: MyApp(),
11 | ),
12 | );
13 |
14 |
15 | // Coded By Raj Chowdhury
16 |
17 |
18 | class MyApp extends StatefulWidget {
19 | @override
20 | _MyAppState createState() => _MyAppState();
21 | }
22 |
23 | class _MyAppState extends State {
24 | @override
25 | Widget build(BuildContext context) {
26 | return Scaffold(
27 | body: SafeArea(
28 | child: Center(
29 | child: Column(
30 | mainAxisAlignment: MainAxisAlignment.center,
31 | children: [
32 | Padding(
33 | padding: const EdgeInsets.all(8.0),
34 | child: StepperTouch(
35 | initialValue: 0,
36 | direction: Axis.vertical,
37 | withSpring: false,
38 | onChanged: (int value) => print('new value $value'),
39 | ),
40 | ),
41 | Padding(
42 | padding: const EdgeInsets.all(8.0),
43 | child: StepperTouch(
44 | initialValue: 0,
45 | onChanged: (int value) => print('new value $value'),
46 | ),
47 | ),
48 | ],
49 | ),
50 | ),
51 | ),
52 | );
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/lib/src/stepper.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/physics.dart';
3 |
4 | class StepperTouch extends StatefulWidget {
5 | const StepperTouch({
6 | Key key,
7 | this.initialValue,
8 | this.onChanged,
9 | this.direction = Axis.horizontal,
10 | this.withSpring = true,
11 | }) : super(key: key);
12 |
13 |
14 | /// the orientation of the stepper its horizontal or vertical.
15 | final Axis direction;
16 |
17 | /// the initial value of the stepper
18 | final int initialValue;
19 |
20 | /// called whenever the value of the stepper changed
21 | final ValueChanged onChanged;
22 |
23 | /// if you want a springSimulation to happens the the user let go the stepper
24 | /// defaults to true
25 | final bool withSpring;
26 |
27 | // Coded By Raj Chowdhury
28 |
29 | @override
30 | _Stepper2State createState() => _Stepper2State();
31 | }
32 |
33 |
34 | class _Stepper2State extends State
35 | with SingleTickerProviderStateMixin {
36 | AnimationController _controller;
37 | Animation _animation;
38 | int _value;
39 | double _startAnimationPosX;
40 | double _startAnimationPosY;
41 |
42 |
43 | @override
44 | void initState() {
45 | super.initState();
46 | _value = widget.initialValue ?? 0;
47 | _controller =
48 | AnimationController(vsync: this, lowerBound: -0.5, upperBound: 0.5);
49 | _controller.value = 0.0;
50 | _controller.addListener(() {});
51 |
52 | if (widget.direction == Axis.horizontal) {
53 | _animation = Tween(begin: Offset(0.0, 0.0), end: Offset(1.5, 0.0))
54 | .animate(_controller);
55 | } else {
56 | _animation = Tween(begin: Offset(0.0, 0.0), end: Offset(0.0, 1.5))
57 | .animate(_controller);
58 | }
59 | }
60 |
61 |
62 | @override
63 | void dispose() {
64 | _controller?.dispose();
65 | super.dispose();
66 | }
67 |
68 |
69 | @override
70 | void didUpdateWidget(oldWidget) {
71 | super.didUpdateWidget(oldWidget);
72 | if (widget.direction == Axis.horizontal) {
73 | _animation = Tween(begin: Offset(0.0, 0.0), end: Offset(1.5, 0.0))
74 | .animate(_controller);
75 | } else {
76 | _animation = Tween(begin: Offset(0.0, 0.0), end: Offset(0.0, 1.5))
77 | .animate(_controller);
78 | }
79 | }
80 |
81 | // !test = init();
82 |
83 | @override
84 | Widget build(BuildContext context) {
85 | return FittedBox(
86 | child: Container(
87 | width: widget.direction == Axis.horizontal ? 280.0 : 120.0,
88 | height: widget.direction == Axis.horizontal ? 120.0 : 280.0,
89 | child: Material(
90 | type: MaterialType.canvas,
91 | clipBehavior: Clip.antiAlias,
92 | borderRadius: BorderRadius.circular(60.0),
93 | color: Colors.white.withOpacity(0.2),
94 | child: Stack(
95 | alignment: Alignment.center,
96 | children: [
97 | Positioned(
98 | left: widget.direction == Axis.horizontal ? 10.0 : null,
99 | bottom: widget.direction == Axis.horizontal ? null : 10.0,
100 | child: Icon(Icons.remove, size: 40.0, color: Colors.white),
101 | ),
102 | Positioned(
103 | right: widget.direction == Axis.horizontal ? 10.0 : null,
104 | top: widget.direction == Axis.horizontal ? null : 10.0,
105 | child: Icon(Icons.add, size: 40.0, color: Colors.white),
106 | ),
107 | GestureDetector(
108 | onHorizontalDragStart: _onPanStart,
109 | onHorizontalDragUpdate: _onPanUpdate,
110 | onHorizontalDragEnd: _onPanEnd,
111 | child: SlideTransition(
112 | position: _animation,
113 | child: Material(
114 | color: Colors.white,
115 | shape: const CircleBorder(),
116 | elevation: 5.0,
117 | child: Center(
118 | child: AnimatedSwitcher(
119 | duration: const Duration(milliseconds: 500),
120 | transitionBuilder:
121 | (Widget child, Animation animation) {
122 | return ScaleTransition(
123 | child: child, scale: animation);
124 | },
125 | child: Text(
126 | '$_value',
127 | key: ValueKey(_value),
128 | style: TextStyle(
129 | color: Color(0xFF6D72FF), fontSize: 56.0),
130 | ),
131 | ),
132 | ),
133 | ),
134 | ),
135 | ),
136 | ],
137 | ),
138 | ),
139 | ),
140 | );
141 | }
142 |
143 |
144 | double offsetFromGlobalPos(Offset globalPosition) {
145 | RenderBox box = context.findRenderObject() as RenderBox;
146 | Offset local = box.globalToLocal(globalPosition);
147 | _startAnimationPosX = ((local.dx * 0.75) / box.size.width) - 0.4;
148 | _startAnimationPosY = ((local.dy * 0.75) / box.size.height) - 0.4;
149 | if (widget.direction == Axis.horizontal) {
150 | return ((local.dx * 0.75) / box.size.width) - 0.4;
151 | } else {
152 | return ((local.dy * 0.75) / box.size.height) - 0.4;
153 | }
154 | }
155 |
156 |
157 | void _onPanStart(DragStartDetails details) {
158 | _controller.stop();
159 | _controller.value = offsetFromGlobalPos(details.globalPosition);
160 | }
161 |
162 | void _onPanUpdate(DragUpdateDetails details) {
163 | _controller.value = offsetFromGlobalPos(details.globalPosition);
164 | }
165 |
166 |
167 | void _onPanEnd(DragEndDetails details) {
168 | _controller.stop();
169 | bool isHor = widget.direction == Axis.horizontal;
170 | bool changed = false;
171 | if (_controller.value <= -0.20) {
172 | setState(() => isHor ? _value-- : _value++);
173 | changed = true;
174 | } else if (_controller.value >= 0.20) {
175 | setState(() => isHor ? _value++ : _value--);
176 | changed = true;
177 | }
178 | if (widget.withSpring) {
179 | final SpringDescription _kDefaultSpring =
180 | new SpringDescription.withDampingRatio(
181 | mass: 0.9,
182 | stiffness: 250.0,
183 | ratio: 0.6,
184 | );
185 | if (widget.direction == Axis.horizontal) {
186 | _controller.animateWith(
187 | SpringSimulation(_kDefaultSpring, _startAnimationPosX, 0.0, 0.0));
188 | } else {
189 | _controller.animateWith(
190 | SpringSimulation(_kDefaultSpring, _startAnimationPosY, 0.0, 0.0));
191 | }
192 | } else {
193 | _controller.animateTo(0.0,
194 | curve: Curves.bounceOut, duration: Duration(milliseconds: 500));
195 | }
196 |
197 | if (changed && widget.onChanged != null) {
198 | widget.onChanged(_value);
199 | }
200 | }
201 | }
202 |
203 |
204 | // != carbon.sh
205 |
--------------------------------------------------------------------------------
/lib/stepper_touch.dart:
--------------------------------------------------------------------------------
1 | library stepper_touch;
2 | export 'src/stepper.dart';
3 |
4 | var aquaticNames = steps
5 | .where((steps) => steps.isAquatic)
6 | .map((steps) => steps.name);
7 |
--------------------------------------------------------------------------------
/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://www.dartlang.org/tools/pub/glossary#lockfile
3 | packages:
4 | analyzer:
5 | dependency: transitive
6 | description:
7 | name: analyzer
8 | url: "https://pub.dartlang.org"
9 | source: hosted
10 | version: "0.32.4"
11 | args:
12 | dependency: transitive
13 | description:
14 | name: args
15 | url: "https://pub.dartlang.org"
16 | source: hosted
17 | version: "1.5.0"
18 | async:
19 | dependency: transitive
20 | description:
21 | name: async
22 | url: "https://pub.dartlang.org"
23 | source: hosted
24 | version: "2.0.8"
25 | boolean_selector:
26 | dependency: transitive
27 | description:
28 | name: boolean_selector
29 | url: "https://pub.dartlang.org"
30 | source: hosted
31 | version: "1.0.4"
32 | charcode:
33 | dependency: transitive
34 | description:
35 | name: charcode
36 | url: "https://pub.dartlang.org"
37 | source: hosted
38 | version: "1.1.2"
39 | collection:
40 | dependency: transitive
41 | description:
42 | name: collection
43 | url: "https://pub.dartlang.org"
44 | source: hosted
45 | version: "1.14.11"
46 | convert:
47 | dependency: transitive
48 | description:
49 | name: convert
50 | url: "https://pub.dartlang.org"
51 | source: hosted
52 | version: "2.0.2"
53 | crypto:
54 | dependency: transitive
55 | description:
56 | name: crypto
57 | url: "https://pub.dartlang.org"
58 | source: hosted
59 | version: "2.0.6"
60 | csslib:
61 | dependency: transitive
62 | description:
63 | name: csslib
64 | url: "https://pub.dartlang.org"
65 | source: hosted
66 | version: "0.14.5"
67 | flutter:
68 | dependency: "direct main"
69 | description: flutter
70 | source: sdk
71 | version: "0.0.0"
72 | flutter_test:
73 | dependency: "direct dev"
74 | description: flutter
75 | source: sdk
76 | version: "0.0.0"
77 | front_end:
78 | dependency: transitive
79 | description:
80 | name: front_end
81 | url: "https://pub.dartlang.org"
82 | source: hosted
83 | version: "0.1.4"
84 | glob:
85 | dependency: transitive
86 | description:
87 | name: glob
88 | url: "https://pub.dartlang.org"
89 | source: hosted
90 | version: "1.1.7"
91 | html:
92 | dependency: transitive
93 | description:
94 | name: html
95 | url: "https://pub.dartlang.org"
96 | source: hosted
97 | version: "0.13.3+3"
98 | http:
99 | dependency: transitive
100 | description:
101 | name: http
102 | url: "https://pub.dartlang.org"
103 | source: hosted
104 | version: "0.11.3+17"
105 | http_multi_server:
106 | dependency: transitive
107 | description:
108 | name: http_multi_server
109 | url: "https://pub.dartlang.org"
110 | source: hosted
111 | version: "2.0.5"
112 | http_parser:
113 | dependency: transitive
114 | description:
115 | name: http_parser
116 | url: "https://pub.dartlang.org"
117 | source: hosted
118 | version: "3.1.3"
119 | io:
120 | dependency: transitive
121 | description:
122 | name: io
123 | url: "https://pub.dartlang.org"
124 | source: hosted
125 | version: "0.3.3"
126 | js:
127 | dependency: transitive
128 | description:
129 | name: js
130 | url: "https://pub.dartlang.org"
131 | source: hosted
132 | version: "0.6.1+1"
133 | json_rpc_2:
134 | dependency: transitive
135 | description:
136 | name: json_rpc_2
137 | url: "https://pub.dartlang.org"
138 | source: hosted
139 | version: "2.0.9"
140 | kernel:
141 | dependency: transitive
142 | description:
143 | name: kernel
144 | url: "https://pub.dartlang.org"
145 | source: hosted
146 | version: "0.3.4"
147 | logging:
148 | dependency: transitive
149 | description:
150 | name: logging
151 | url: "https://pub.dartlang.org"
152 | source: hosted
153 | version: "0.11.3+2"
154 | matcher:
155 | dependency: transitive
156 | description:
157 | name: matcher
158 | url: "https://pub.dartlang.org"
159 | source: hosted
160 | version: "0.12.3+1"
161 | meta:
162 | dependency: transitive
163 | description:
164 | name: meta
165 | url: "https://pub.dartlang.org"
166 | source: hosted
167 | version: "1.1.6"
168 | mime:
169 | dependency: transitive
170 | description:
171 | name: mime
172 | url: "https://pub.dartlang.org"
173 | source: hosted
174 | version: "0.9.6+2"
175 | multi_server_socket:
176 | dependency: transitive
177 | description:
178 | name: multi_server_socket
179 | url: "https://pub.dartlang.org"
180 | source: hosted
181 | version: "1.0.2"
182 | node_preamble:
183 | dependency: transitive
184 | description:
185 | name: node_preamble
186 | url: "https://pub.dartlang.org"
187 | source: hosted
188 | version: "1.4.4"
189 | package_config:
190 | dependency: transitive
191 | description:
192 | name: package_config
193 | url: "https://pub.dartlang.org"
194 | source: hosted
195 | version: "1.0.5"
196 | package_resolver:
197 | dependency: transitive
198 | description:
199 | name: package_resolver
200 | url: "https://pub.dartlang.org"
201 | source: hosted
202 | version: "1.0.4"
203 | path:
204 | dependency: transitive
205 | description:
206 | name: path
207 | url: "https://pub.dartlang.org"
208 | source: hosted
209 | version: "1.6.2"
210 | plugin:
211 | dependency: transitive
212 | description:
213 | name: plugin
214 | url: "https://pub.dartlang.org"
215 | source: hosted
216 | version: "0.2.0+3"
217 | pool:
218 | dependency: transitive
219 | description:
220 | name: pool
221 | url: "https://pub.dartlang.org"
222 | source: hosted
223 | version: "1.3.6"
224 | pub_semver:
225 | dependency: transitive
226 | description:
227 | name: pub_semver
228 | url: "https://pub.dartlang.org"
229 | source: hosted
230 | version: "1.4.2"
231 | quiver:
232 | dependency: transitive
233 | description:
234 | name: quiver
235 | url: "https://pub.dartlang.org"
236 | source: hosted
237 | version: "2.0.0+1"
238 | shelf:
239 | dependency: transitive
240 | description:
241 | name: shelf
242 | url: "https://pub.dartlang.org"
243 | source: hosted
244 | version: "0.7.3+3"
245 | shelf_packages_handler:
246 | dependency: transitive
247 | description:
248 | name: shelf_packages_handler
249 | url: "https://pub.dartlang.org"
250 | source: hosted
251 | version: "1.0.4"
252 | shelf_static:
253 | dependency: transitive
254 | description:
255 | name: shelf_static
256 | url: "https://pub.dartlang.org"
257 | source: hosted
258 | version: "0.2.8"
259 | shelf_web_socket:
260 | dependency: transitive
261 | description:
262 | name: shelf_web_socket
263 | url: "https://pub.dartlang.org"
264 | source: hosted
265 | version: "0.2.2+4"
266 | sky_engine:
267 | dependency: transitive
268 | description: flutter
269 | source: sdk
270 | version: "0.0.99"
271 | source_map_stack_trace:
272 | dependency: transitive
273 | description:
274 | name: source_map_stack_trace
275 | url: "https://pub.dartlang.org"
276 | source: hosted
277 | version: "1.1.5"
278 | source_maps:
279 | dependency: transitive
280 | description:
281 | name: source_maps
282 | url: "https://pub.dartlang.org"
283 | source: hosted
284 | version: "0.10.7"
285 | source_span:
286 | dependency: transitive
287 | description:
288 | name: source_span
289 | url: "https://pub.dartlang.org"
290 | source: hosted
291 | version: "1.4.1"
292 | stack_trace:
293 | dependency: transitive
294 | description:
295 | name: stack_trace
296 | url: "https://pub.dartlang.org"
297 | source: hosted
298 | version: "1.9.3"
299 | stream_channel:
300 | dependency: transitive
301 | description:
302 | name: stream_channel
303 | url: "https://pub.dartlang.org"
304 | source: hosted
305 | version: "1.6.8"
306 | string_scanner:
307 | dependency: transitive
308 | description:
309 | name: string_scanner
310 | url: "https://pub.dartlang.org"
311 | source: hosted
312 | version: "1.0.4"
313 | term_glyph:
314 | dependency: transitive
315 | description:
316 | name: term_glyph
317 | url: "https://pub.dartlang.org"
318 | source: hosted
319 | version: "1.0.1"
320 | test:
321 | dependency: transitive
322 | description:
323 | name: test
324 | url: "https://pub.dartlang.org"
325 | source: hosted
326 | version: "1.3.0"
327 | typed_data:
328 | dependency: transitive
329 | description:
330 | name: typed_data
331 | url: "https://pub.dartlang.org"
332 | source: hosted
333 | version: "1.1.6"
334 | utf:
335 | dependency: transitive
336 | description:
337 | name: utf
338 | url: "https://pub.dartlang.org"
339 | source: hosted
340 | version: "0.9.0+5"
341 | vector_math:
342 | dependency: transitive
343 | description:
344 | name: vector_math
345 | url: "https://pub.dartlang.org"
346 | source: hosted
347 | version: "2.0.8"
348 | vm_service_client:
349 | dependency: transitive
350 | description:
351 | name: vm_service_client
352 | url: "https://pub.dartlang.org"
353 | source: hosted
354 | version: "0.2.6"
355 | watcher:
356 | dependency: transitive
357 | description:
358 | name: watcher
359 | url: "https://pub.dartlang.org"
360 | source: hosted
361 | version: "0.9.7+10"
362 | web_socket_channel:
363 | dependency: transitive
364 | description:
365 | name: web_socket_channel
366 | url: "https://pub.dartlang.org"
367 | source: hosted
368 | version: "1.0.9"
369 | yaml:
370 | dependency: transitive
371 | description:
372 | name: yaml
373 | url: "https://pub.dartlang.org"
374 | source: hosted
375 | version: "2.1.15"
376 | sdks:
377 | dart: ">=2.0.0-dev.68.0 <3.0.0"
378 |
379 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: Counter App
2 | description: a flutter stepper widget with nice aniamtion
3 | version: 0.0.1
4 | author: Raj Chowdhury
5 | homepage: https://github.com/Rajchowdhury420
6 | environment:
7 | sdk: ">=2.0.0-dev.68.0 <3.0.0"
8 |
9 | dependencies:
10 | flutter:
11 | sdk: flutter
12 |
13 | dev_dependencies:
14 | flutter_test:
15 | sdk: flutter
16 |
17 | flutter:
18 |
19 | // add your own requirement if u want
20 |
--------------------------------------------------------------------------------