Giter Site home page Giter Site logo

flutter_rounded_loading_button's Introduction

rounded_loading_button

pub package build codecov style: effective dart License: MIT Awesome Flutter

RoundedLoadingButton is a Flutter package with a simple implementation of an animated loading button, complete with success and error animations.

Installation

Add this to your pubspec.yaml:

dependencies:
    rounded_loading_button: ^2.0.8

Usage

Import

import 'package:rounded_loading_button/rounded_loading_button.dart';

Simple Implementation

final RoundedLoadingButtonController _btnController = RoundedLoadingButtonController();

void _doSomething() async {
    Timer(Duration(seconds: 3), () {
        _btnController.success();
    });
}

RoundedLoadingButton(
    child: Text('Tap me!', style: TextStyle(color: Colors.white)),
    controller: _btnController,
    onPressed: _doSomething,
)

The Rounded Loading Button has many configurable properties, including:

  • duration - The duration of the button animation
  • loaderSize - The size of the CircularProgressIndicator
  • animateOnTap - Whether to trigger the loading animation on the tap event
  • resetAfterDuration - Reset the animation after specified duration, defaults to 15 seconds
  • errorColor - The color of the button when it is in the error state
  • successColor - The color of the button when it is in the success state
  • successIcon - The icon for the success state
  • failedIcon - The icon for the failed state

Contributions

All contributions are welcome!

flutter_rounded_loading_button's People

Contributors

alexobviously avatar chrisedg87 avatar federicodesia avatar joaovvrodrigues avatar lucasdanbatista avatar megatunger avatar mufaddal1125 avatar rexios80 avatar shamilpp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

flutter_rounded_loading_button's Issues

Rounded button using Outlined button style

I am using this package for my buttons. I have situation when I need to have rounded button which looks like an outlined button. I have wrapped it with a container with border colour. This works except that when circular progress indicator shows it does not shrink the border of wrapped container.

I am wondering if there is a better way to deal with this. Basically I want an outlined button style.

Thank you

disable button from controller

is there a way to disable programmatically?
the scenario is that I have multiple buttons on the same page and I want to prevent the user to click on all of them, during the first click I would like to disable all remaining controllers

thanks

Initialize RoundedLoadingButtonController listeners in build() not in initState()

This will solve the problem in issue #14.

The problem happens every time the widget that holds the controller changes (so the controller itself changes). The problem occurs because some fields in the controller gets initialized only one time in the initState of the RoundedLoadingButton, so when the controller changes but the state doesn't change, the fields don't get initialized.

Question

**- Does the control close automatically when I go to another page because I did not find "Function Disposed"!?

  • Is there a risk of occurrence Memory Leak ?**

Programmatically stop and start fails

I would like to start the button animation and stop it after a ModalBottom has been shown.

When the modal is shown, if I press outside the modal (basically it pops it from the stack) the button would continue to run. That is why I added controller.reset().

This works fine the first time. However if I do this same thing twice I get

I/flutter (25672): LateInitializationError: Field '_stopListener@67160650' has not been initialized.
I/flutter (25672): 
I/flutter (25672): #0      RoundedLoadingButtonController._stopListener (package:rounded_loading_button/rounded_loading_button.dart)
I/flutter (25672): #1      RoundedLoadingButtonController.stop (package:rounded_loading_button/rounded_loading_button.dart:313:5)
I/flutter (25672): #2      JoinGameButton.onPressed (package:nutmeg/screens/MatchDetailsModals.dart:575:16)
I/flutter (25672): <asynchronous suspension>

This is the onTap function for the button

Future<void> onTap(
      BuildContext context, RoundedLoadingButtonController controller) async {
      var paymentRecap = await PaymentController.generatePaymentRecap(
        matchesState, match.documentId, userState);
    await showModalBottomSheet(
         context: context,
         builder: (context) => PrepaymentBottomBar(
               match: match,
               recap: paymentRecap,
             ));

    controller.stop();

I have tried controller.stop() as well as controller.reset() but same outcome

Flutter 3.18.0-11.0 Error onSurface

Could not build the precompiled application for the device.
Error (Xcode): ../../../.pub-cache/hosted/pub.dev/rounded_loading_button-2.1.0/lib/rounded_loading_button.dart:197:11: Error: No named parameter with the name 'onSurface'.

Example Code:
RoundedLoadingButton(
color: Colors.red,
successColor: Colors.green,
controller: _btnController,
onPressed: () {
if (_formKey.currentState!.validate()) {
userinfoset();
} else {
_btnController.error();
_reset();
}
},
child: Text(sonuc.toString(),
style: const TextStyle(color: Colors.white)),
),

Change CircleProgressIndicator size

Hi! very good package!

Could you add an option to resize CircleProgressIndicator?

I think with SizedBox and Center it is possible to modify the size:
SizedBox( height: progressHeight, width: progressWidth, child: Center( child: CircularProgressIndicator() ), )

create new RoundedLoadingButtonController() dynamically

Hi ,

i'm ask how to create new RoundedLoadingButtonController() dynamically , so i have list from api
and i want each item has it's uniq RoundedLoadingButtonController for controller and pass it's reference to other method to control stop or error and so on

my code:

RoundedLoadingButton(

                                controller:
                                    new RoundedLoadingButtonController(),
                                color: Theme.of(context).accentColor,
                                onPressed: () {
                                  _con.addFoodReview(
                                      _con.foodsReviews[index],
                                      _con.foodsOfOrder[index],
                                      new RoundedLoadingButtonController()); // i have to pass it here to method to controll stop and error 
                                },
                              ),

Change the color of circular progress

Hi
Do you know how I can change the color of circular progress? Because one of the buttons in my app is white and I want the color of the circular progress to be blue.

Incompatible versions...

Max version that woks is the 1.0.4, but the recents do not.

sdk: ">=2.7.0 <3.0.0"
.....
 rxdart:
    dependency: transitive
    description:
      name: rxdart
      url: "https://pub.dartlang.org"
    source: hosted
    version: "0.23.1"

The error Message :

Because no versions of select_dialog match >1.1.0 <2.0.0 and select_dialog 1.1.0 depends on rxdart ^0.23.1, select_dialog ^1.1.0 requires rxdart ^0.23.1.
And because rounded_loading_button >=1.0.5 depends on rxdart ^0.24.0, select_dialog ^1.1.0 is incompatible with rounded_loading_button >=1.0.5.
So, because my_civi_flutter_app depends on both select_dialog ^1.1.0 and rounded_loading_button ^1.0.5, version solving failed.
pub get failed (1; So, because my_civi_flutter_app depends on both select_dialog ^1.1.0 and rounded_loading_button ^1.0.5, version solving failed.)

Unhandled Exception: Bad state: Cannot add new events after calling close

My code:
_btnController.start();
var logoutData = await HttpService().logOut(api, body);
if (logoutData != null) {
_btnController.stop();
Navigator.of(context)
.pushNamedAndRemoveUntil(LoginScreen.routeName, (route) => false);
}

errors:
[VERBOSE-2:ui_dart_state.cc(199)] Unhandled Exception: Bad state: Cannot add new events after calling close
#0 _BroadcastStreamController.add (dart:async/broadcast_stream_controller.dart:243:24)
#1 Subject._add (package:rxdart/src/subjects/subject.dart:141:17)
#2 Subject.add (package:rxdart/src/subjects/subject.dart:135:5)
#3 _StreamSinkWrapper.add (package:rxdart/src/subjects/subject.dart:167:13)
#4 RoundedLoadingButtonState._reset (package:rounded_loading_button/rounded_loading_button.dart:305:17)

Flutter Widget Test doesn't seem to work.

I have two options when executing a tap:

/* by type: */ await tester.tap(find.byType(RoundedLoadingButton), warnIfMissed: true);
/* by key: */ await tester.tap(find.byKey(const Key("signInButton")), warnIfMissed: true);

But neither of them works at all. I get errors when trying to verify a certain function from a mock instance which is expected to be executed when the button is tapped.

This works with a regular TextButton by the way.

Is there a way to apply borders for the button?

Noticed that the closing animation has elevation even if the button doesn't, resulting in a weird effect.
If the elevation is set to zero, would be great to set up a border for the button. I tried to use box decoration but wasn't bright enough to accomplish the goal.

Button size with infinite width

When setting the button size to double.infinity, the animation errors at the beginning. Any thoughts on how to solve this?

Calling a refactored RoundedLoadingButton exceptions with the parent code

Hi

I have wanted buttons of a uniform appearance which shall feature animation on presses. So I refactored (made a child from) the RoundedLoadingButton widget.

It is when the child widget is featured within an app and all of the relevant imports are made, that Flutter begins to flag exceptions with the parent code.

Could you advise me on how to achieve the desired result without the exceptions please? The refactored code is attached for your consideration.

With thanks

Mathems

RoundAnimeButton.txt

Problem with button size

There seems to be a problem displaying the buttons child if the width of the button is quite small.

Issue with Flutter 3.19

when i use the below code

RoundedLoadingButton(
controller: loginBtn,
onPressed: () {
if (formKey.currentState!.validate()) {
loginBtn.success();
} else {
loginBtn.error();
}
Future.delayed(const Duration(seconds: 1), () {
loginBtn.reset();
});
},
successColor: Colors.green,
child: Text('Login'.hardcoded))

the code works fine in flutter 3.16 without any issue and when i upgraded to 3.19 it shows the following error with build failed result.

../../.pub-cache/hosted/pub.dev/rounded_loading_button-2.1.0/lib/rounded_loading_button.dart:197:11: Error: No named parameter with the name 'onSurface'.
onSurface: widget.disabledColor,
^^^^^^^^^
../../Flutter_SDK/packages/flutter/lib/src/material/elevated_button.dart:151:22: Context: Found this candidate, but the arguments don't match.
static ButtonStyle styleFrom({
^^^^^^^^^
Target kernel_snapshot failed: Exception

Animation lags when reset

Timer(Duration(seconds: 3), () async {
_btnController.success();
await Future.delayed(Duration(seconds: 1));
_btnController.reset();
}

When the animation resets, it lags. It will stop for a moment and then continue. When I play it in slow motion it seems that the button will take the size of the text inside it and then continue to grow. That is why you see the lag

borderRadius in different States

Should have a way to set the borderRadius for differents button states. For example, before onTap, when loading and after loading. I needed set different borderRadius for the button but I can't.

The behavior that I expect was possible before Null Safety, but now is not anymore.

This first image shows the button state before loading.
image

I would like be rounded when loading, like this second image
image

But this was no possible, so the button on the second image was made this from scratch. So what I got with the plugin is this showed in the third image bellow.
image

more than 1 button

I want to create more than one button with listview builder but I can't control it. how can i handle it?

Getting an error while trying to show the success state

Getting the below error in the sample code for 3 seconds timer. Button showing in the in-progress state all the time. Any idea how to fix it?

/flutter (14084): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: NoSuchMethodError: The method 'call' was called on null.
E/flutter (14084): Receiver: null
E/flutter (14084): Tried calling: call()
E/flutter (14084): 0 Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
E/flutter (14084): 1 RoundedLoadingButtonController.success
package:rounded_loading_button/rounded_loading_button.dart:261
E/flutter (14084): 2 _LoginPageState.build._sendOTP.
package:flutterloginui/main.dart:158
E/flutter (14084): 3 _rootRun (dart:async/zone.dart:1180:38)
E/flutter (14084): 4 _CustomZone.run (dart:async/zone.dart:1077:19)
E/flutter (14084): 5 _CustomZone.runGuarded (dart:async/zone.dart:979:7)
E/flutter (14084): 6 _CustomZone.bindCallbackGuarded. (dart:async/zone.dart:1019:23)
E/flutter (14084): 7 _rootRun (dart:async/zone.dart:1184:13)
E/flutter (14084): 8 _CustomZone.run (dart:async/zone.dart:1077:19)
E/flutter (14084): 9 _CustomZone.bindCallback. (dart:async/zone.dart:1003:23)
E/flutter (14084): 10 Timer._createTimer. (dart:async-patch/timer_patch.dart:23:15)
E/flutter (14084): 11 _Timer._runTimers (dart:isolate-patch/timer_impl.dart:398:19)
E/flutter (14084): 12 _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:429:5)
E/flutter (14084): 13 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)

NoSuchMethodError

when field validation fails the reset function raises an error

my code:

  Future<void> submit() async {
    final allValid = await checkInput();
    if (allValid) {
      Logger.log(tag, message: 'going to submit');
...
      checkImageController.success();
    } else {
      checkImageController.reset();
    }
  }

the error

E/flutter (22565): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: NoSuchMethodError: The method 'call' was called on null.
E/flutter (22565): Receiver: null
E/flutter (22565): Tried calling: call()
E/flutter (22565): #0      Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
E/flutter (22565): #1      RoundedLoadingButtonController.reset (package:rounded_loading_button/rounded_loading_button.dart:286:19)
E/flutter (22565): #2      OrganizationSignedModel.submit (package:customer/ui/auth/organization_signed_model.dart:118:28)
E/flutter (22565): <asynchronous suspension>

this is how I init the controller

  final RoundedLoadingButtonController checkImageController = RoundedLoadingButtonController();

thanks

android only controller.success or reset not working with flutter 3.16

RoundedLoadingButton starts animation automatically but when i call reset of success on same controller nothing happen , tested the same code on I phone and it works as expected .

flutter doctor

[✓] Flutter (Channel stable, 3.16.2, on macOS 14.1.2 23B92 darwin-x64, locale en-EG)
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 15.0.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2022.3)
[✓] VS Code (version 1.84.2)
[✓] Connected device (4 available)
[✓] Network resources

android targetSdkVersion 34

Disabled

How do I disabled the button now? In previous versions there was a parameter for this

RoundedLoadingButtonState was disposed with an active Ticker.

════════ Exception caught by widgets library ═══════════════════════════════════════════════════════ The following assertion was thrown while finalizing the widget tree: RoundedLoadingButtonState#37ffe(tickers: tracking 2 tickers) was disposed with an active Ticker.

plesase add dispose function for stop animation controller thanks

Function called twice when animateOnTap is set to false

When animateOnTap is set to false and I call _btnController.start(); onPressed is called again.

RoundedLoadingButton(
  animateOnTap: false,
  controller: _btnController,
  elevation: 0,
  onPressed: () => startAnimation(),
  borderRadius: 30,
  child: Text('Loading Button'),
)



void startAnimation() {
  print('I WAS CALLED');

  _btnController.start();
  Timer(Duration(seconds: 5), () {
      _btnController.success();
   });
 }

How to separate animation of these buttons in any page widget.

I have the current_widget variable to switch pages A and B by setState, and I used the rounded_loading_button on these pages. When I press the rounded_button in the A page and I switch to the B page, the rounded_button on the B page is animating like page A. How to separate animation of these buttons.


You can duplicate this issue by:

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:rounded_loading_button/rounded_loading_button.dart';

class test extends StatefulWidget {
const test({Key? key}) : super(key: key);

@OverRide
_testState createState() => _testState();
}

class _testState extends State {
Widget currentSection = SizedBox();

bool current = true;

@OverRide
void initState() {
setState(() {
currentSection = pageA();
});
super.initState();
}

void doSomething(RoundedLoadingButtonController btnController) async {
Timer(
Duration(milliseconds: 500),
() {
btnController.success();
},
);
Timer(
Duration(seconds: 2),
() {
btnController.reset();
},
);
}

@OverRide
Widget build(BuildContext context) {
return Column(
children: [
IconButton(
onPressed: () {
setState(() {
if (current) {
currentSection = pageB();
current = !current;
} else {
currentSection = pageA();
current = !current;
}
});
},
icon: Icon(Icons.swipe),
),
currentSection,
],
);
}

Widget pageA() {
final RoundedLoadingButtonController btnControllerA =
new RoundedLoadingButtonController();

return Column(
  children: [
    Text("Page A"),
    RoundedLoadingButton(
      controller: btnControllerA,
      onPressed: () => doSomething(btnControllerA),
      child: Text('BTN A'),
    ),
  ],
);

}

Widget pageB() {
final RoundedLoadingButtonController btnControllerB =
new RoundedLoadingButtonController();

return Column(
  children: [
    Text("Page B"),
    RoundedLoadingButton(
      controller: btnControllerB,
      onPressed: () => doSomething(btnControllerB),
      child: Text('BTN B'),
    ),
  ],
);

}
}


Or simple code like

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:rounded_loading_button/rounded_loading_button.dart';

class Test extends StatefulWidget {
const Test({Key? key}) : super(key: key);

@OverRide
_testState createState() => _testState();
}

class _testState extends State {
bool current = true;

void doSomething(RoundedLoadingButtonController btnController) async {
Timer(
Duration(milliseconds: 500),
() {
btnController.success();
},
);
Timer(
Duration(seconds: 2),
() {
btnController.reset();
},
);
}

@OverRide
Widget build(BuildContext context) {
return Column(
children: [
IconButton(
onPressed: () {
setState(() {
if (current) {
current = !current;
} else {
current = !current;
}
});
},
icon: Icon(Icons.swipe),
),
current ? pageA() : pageB(),
],
);
}

Widget pageA() {
final RoundedLoadingButtonController btnControllerA =
new RoundedLoadingButtonController();

return Column(
  children: [
    Text("Page A"),
    RoundedLoadingButton(
      controller: btnControllerA,
      onPressed: () => doSomething(btnControllerA),
      child: Text('BTN A'),
    ),
  ],
);

}

Widget pageB() {
final RoundedLoadingButtonController btnControllerB =
new RoundedLoadingButtonController();

return Column(
  children: [
    Text("Page B"),
    RoundedLoadingButton(
      controller: btnControllerB,
      onPressed: () => doSomething(btnControllerB),
      child: Text('BTN B'),
    ),
  ],
);

}
}

Null safety

Thanks for this package! Do you plan to add null safety?

Disable Button

Hi
I want to disable button if my form is invalid.
normally I set (OnPressed : null) and it works for all buttons but it does not work with this button.
is there any trick to do that ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.