Circular progress button based on hold (flutter)
I'm trying to make a button where when user hold it, there will be a progress, but if the user unpress the button before it finish, the progress will decrease. somthing like the one on the picture
dart
add a comment |
I'm trying to make a button where when user hold it, there will be a progress, but if the user unpress the button before it finish, the progress will decrease. somthing like the one on the picture
dart
add a comment |
I'm trying to make a button where when user hold it, there will be a progress, but if the user unpress the button before it finish, the progress will decrease. somthing like the one on the picture
dart
I'm trying to make a button where when user hold it, there will be a progress, but if the user unpress the button before it finish, the progress will decrease. somthing like the one on the picture
dart
dart
asked Nov 22 '18 at 6:03
aliali
699
699
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
As said by Arnold Parge, you can use the GestureDetector and listen to onTapDown and onTapUp. To create your desired LoadingButton, you can use the following Widget Structure:
- GetureDetector
- Stack
- CircularProgressIndicator // background circle
- CircularProgressIndicator // foreground circle
- Icon
To create the animation, you can add an AnimationController and bind the value of the foreground CircularProgressIndicator to AnimationController.value. Now you'll just have to the add the two listeners to to the GestureDetector:
onTapDown: When tapping on the button, the animation should start. Therefore we callAnimationController.forward()
onTapUp: When releasing the press, we want to check if the animation is already finished. We can use AnimationController.status to check the status. If it isAnimationStatus.forwardit is still running. Hence we want to reverse the animation with callingAnimationController.reverse().
Here is the resulting button:

And the complete source code:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(),
home: Scaffold(
body: Center(child: LoadingButton()),
),
);
}
}
class LoadingButton extends StatefulWidget {
@override
LoadingButtonState createState() => LoadingButtonState();
}
class LoadingButtonState extends State<LoadingButton>
with SingleTickerProviderStateMixin {
AnimationController controller;
@override
void initState() {
super.initState();
controller =
AnimationController(vsync: this, duration: Duration(seconds: 1));
controller.addListener(() {
setState(() {});
});
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTapDown: (_) => controller.forward(),
onTapUp: (_) {
if (controller.status == AnimationStatus.forward) {
controller.reverse();
}
},
child: Stack(
alignment: Alignment.center,
children: <Widget>[
CircularProgressIndicator(
value: 1.0,
valueColor: AlwaysStoppedAnimation<Color>(Colors.grey),
),
CircularProgressIndicator(
value: controller.value,
valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
),
Icon(Icons.add)
],
),
);
}
}
might be a bit late, but how do i trigger it once the progress is finish during tap down? because right now i can trigger it only if the user tap up the button.
– ali
Jan 23 at 10:50
@ali you can also add a conditional to theonTapDownhandler. If I didn't got your question right, would you mind specifying what you exactly need? :)
– Niklas
Jan 24 at 10:44
add a comment |
Use GestureDetector.
Start the progress in onTapDown and reverse the progress in onTapUp if the progress is not complete or whatever your conditions are.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53424764%2fcircular-progress-button-based-on-hold-flutter%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
As said by Arnold Parge, you can use the GestureDetector and listen to onTapDown and onTapUp. To create your desired LoadingButton, you can use the following Widget Structure:
- GetureDetector
- Stack
- CircularProgressIndicator // background circle
- CircularProgressIndicator // foreground circle
- Icon
To create the animation, you can add an AnimationController and bind the value of the foreground CircularProgressIndicator to AnimationController.value. Now you'll just have to the add the two listeners to to the GestureDetector:
onTapDown: When tapping on the button, the animation should start. Therefore we callAnimationController.forward()
onTapUp: When releasing the press, we want to check if the animation is already finished. We can use AnimationController.status to check the status. If it isAnimationStatus.forwardit is still running. Hence we want to reverse the animation with callingAnimationController.reverse().
Here is the resulting button:

And the complete source code:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(),
home: Scaffold(
body: Center(child: LoadingButton()),
),
);
}
}
class LoadingButton extends StatefulWidget {
@override
LoadingButtonState createState() => LoadingButtonState();
}
class LoadingButtonState extends State<LoadingButton>
with SingleTickerProviderStateMixin {
AnimationController controller;
@override
void initState() {
super.initState();
controller =
AnimationController(vsync: this, duration: Duration(seconds: 1));
controller.addListener(() {
setState(() {});
});
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTapDown: (_) => controller.forward(),
onTapUp: (_) {
if (controller.status == AnimationStatus.forward) {
controller.reverse();
}
},
child: Stack(
alignment: Alignment.center,
children: <Widget>[
CircularProgressIndicator(
value: 1.0,
valueColor: AlwaysStoppedAnimation<Color>(Colors.grey),
),
CircularProgressIndicator(
value: controller.value,
valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
),
Icon(Icons.add)
],
),
);
}
}
might be a bit late, but how do i trigger it once the progress is finish during tap down? because right now i can trigger it only if the user tap up the button.
– ali
Jan 23 at 10:50
@ali you can also add a conditional to theonTapDownhandler. If I didn't got your question right, would you mind specifying what you exactly need? :)
– Niklas
Jan 24 at 10:44
add a comment |
As said by Arnold Parge, you can use the GestureDetector and listen to onTapDown and onTapUp. To create your desired LoadingButton, you can use the following Widget Structure:
- GetureDetector
- Stack
- CircularProgressIndicator // background circle
- CircularProgressIndicator // foreground circle
- Icon
To create the animation, you can add an AnimationController and bind the value of the foreground CircularProgressIndicator to AnimationController.value. Now you'll just have to the add the two listeners to to the GestureDetector:
onTapDown: When tapping on the button, the animation should start. Therefore we callAnimationController.forward()
onTapUp: When releasing the press, we want to check if the animation is already finished. We can use AnimationController.status to check the status. If it isAnimationStatus.forwardit is still running. Hence we want to reverse the animation with callingAnimationController.reverse().
Here is the resulting button:

And the complete source code:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(),
home: Scaffold(
body: Center(child: LoadingButton()),
),
);
}
}
class LoadingButton extends StatefulWidget {
@override
LoadingButtonState createState() => LoadingButtonState();
}
class LoadingButtonState extends State<LoadingButton>
with SingleTickerProviderStateMixin {
AnimationController controller;
@override
void initState() {
super.initState();
controller =
AnimationController(vsync: this, duration: Duration(seconds: 1));
controller.addListener(() {
setState(() {});
});
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTapDown: (_) => controller.forward(),
onTapUp: (_) {
if (controller.status == AnimationStatus.forward) {
controller.reverse();
}
},
child: Stack(
alignment: Alignment.center,
children: <Widget>[
CircularProgressIndicator(
value: 1.0,
valueColor: AlwaysStoppedAnimation<Color>(Colors.grey),
),
CircularProgressIndicator(
value: controller.value,
valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
),
Icon(Icons.add)
],
),
);
}
}
might be a bit late, but how do i trigger it once the progress is finish during tap down? because right now i can trigger it only if the user tap up the button.
– ali
Jan 23 at 10:50
@ali you can also add a conditional to theonTapDownhandler. If I didn't got your question right, would you mind specifying what you exactly need? :)
– Niklas
Jan 24 at 10:44
add a comment |
As said by Arnold Parge, you can use the GestureDetector and listen to onTapDown and onTapUp. To create your desired LoadingButton, you can use the following Widget Structure:
- GetureDetector
- Stack
- CircularProgressIndicator // background circle
- CircularProgressIndicator // foreground circle
- Icon
To create the animation, you can add an AnimationController and bind the value of the foreground CircularProgressIndicator to AnimationController.value. Now you'll just have to the add the two listeners to to the GestureDetector:
onTapDown: When tapping on the button, the animation should start. Therefore we callAnimationController.forward()
onTapUp: When releasing the press, we want to check if the animation is already finished. We can use AnimationController.status to check the status. If it isAnimationStatus.forwardit is still running. Hence we want to reverse the animation with callingAnimationController.reverse().
Here is the resulting button:

And the complete source code:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(),
home: Scaffold(
body: Center(child: LoadingButton()),
),
);
}
}
class LoadingButton extends StatefulWidget {
@override
LoadingButtonState createState() => LoadingButtonState();
}
class LoadingButtonState extends State<LoadingButton>
with SingleTickerProviderStateMixin {
AnimationController controller;
@override
void initState() {
super.initState();
controller =
AnimationController(vsync: this, duration: Duration(seconds: 1));
controller.addListener(() {
setState(() {});
});
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTapDown: (_) => controller.forward(),
onTapUp: (_) {
if (controller.status == AnimationStatus.forward) {
controller.reverse();
}
},
child: Stack(
alignment: Alignment.center,
children: <Widget>[
CircularProgressIndicator(
value: 1.0,
valueColor: AlwaysStoppedAnimation<Color>(Colors.grey),
),
CircularProgressIndicator(
value: controller.value,
valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
),
Icon(Icons.add)
],
),
);
}
}
As said by Arnold Parge, you can use the GestureDetector and listen to onTapDown and onTapUp. To create your desired LoadingButton, you can use the following Widget Structure:
- GetureDetector
- Stack
- CircularProgressIndicator // background circle
- CircularProgressIndicator // foreground circle
- Icon
To create the animation, you can add an AnimationController and bind the value of the foreground CircularProgressIndicator to AnimationController.value. Now you'll just have to the add the two listeners to to the GestureDetector:
onTapDown: When tapping on the button, the animation should start. Therefore we callAnimationController.forward()
onTapUp: When releasing the press, we want to check if the animation is already finished. We can use AnimationController.status to check the status. If it isAnimationStatus.forwardit is still running. Hence we want to reverse the animation with callingAnimationController.reverse().
Here is the resulting button:

And the complete source code:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(),
home: Scaffold(
body: Center(child: LoadingButton()),
),
);
}
}
class LoadingButton extends StatefulWidget {
@override
LoadingButtonState createState() => LoadingButtonState();
}
class LoadingButtonState extends State<LoadingButton>
with SingleTickerProviderStateMixin {
AnimationController controller;
@override
void initState() {
super.initState();
controller =
AnimationController(vsync: this, duration: Duration(seconds: 1));
controller.addListener(() {
setState(() {});
});
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTapDown: (_) => controller.forward(),
onTapUp: (_) {
if (controller.status == AnimationStatus.forward) {
controller.reverse();
}
},
child: Stack(
alignment: Alignment.center,
children: <Widget>[
CircularProgressIndicator(
value: 1.0,
valueColor: AlwaysStoppedAnimation<Color>(Colors.grey),
),
CircularProgressIndicator(
value: controller.value,
valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
),
Icon(Icons.add)
],
),
);
}
}
answered Nov 22 '18 at 9:31
NiklasNiklas
1,119312
1,119312
might be a bit late, but how do i trigger it once the progress is finish during tap down? because right now i can trigger it only if the user tap up the button.
– ali
Jan 23 at 10:50
@ali you can also add a conditional to theonTapDownhandler. If I didn't got your question right, would you mind specifying what you exactly need? :)
– Niklas
Jan 24 at 10:44
add a comment |
might be a bit late, but how do i trigger it once the progress is finish during tap down? because right now i can trigger it only if the user tap up the button.
– ali
Jan 23 at 10:50
@ali you can also add a conditional to theonTapDownhandler. If I didn't got your question right, would you mind specifying what you exactly need? :)
– Niklas
Jan 24 at 10:44
might be a bit late, but how do i trigger it once the progress is finish during tap down? because right now i can trigger it only if the user tap up the button.
– ali
Jan 23 at 10:50
might be a bit late, but how do i trigger it once the progress is finish during tap down? because right now i can trigger it only if the user tap up the button.
– ali
Jan 23 at 10:50
@ali you can also add a conditional to the
onTapDown handler. If I didn't got your question right, would you mind specifying what you exactly need? :)– Niklas
Jan 24 at 10:44
@ali you can also add a conditional to the
onTapDown handler. If I didn't got your question right, would you mind specifying what you exactly need? :)– Niklas
Jan 24 at 10:44
add a comment |
Use GestureDetector.
Start the progress in onTapDown and reverse the progress in onTapUp if the progress is not complete or whatever your conditions are.
add a comment |
Use GestureDetector.
Start the progress in onTapDown and reverse the progress in onTapUp if the progress is not complete or whatever your conditions are.
add a comment |
Use GestureDetector.
Start the progress in onTapDown and reverse the progress in onTapUp if the progress is not complete or whatever your conditions are.
Use GestureDetector.
Start the progress in onTapDown and reverse the progress in onTapUp if the progress is not complete or whatever your conditions are.
answered Nov 22 '18 at 6:30
Arnold PargeArnold Parge
1,79611319
1,79611319
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53424764%2fcircular-progress-button-based-on-hold-flutter%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown