분류, 패키지 및 저장소 검색

GitHub 저장소abhisheksrocks/async_button

async_button

비동기 onPressed 함수용 사용자 지정 버튼입니다. [대기], [로딩], [성공], [실패] 상태 간에 원활한 애니메이션을 지원합니다.

async_button 프로젝트 이미지
스타
10
포크
1
최근 푸시(UTC)
2023. 2. 4.
프로젝트 상태
활성

원본 README

아래는 영문 원문 스냅샷입니다. 최신 내용은 GitHub에서 확인하세요.

Async Button

Buttons get boring when there is an asynchronous onTap function involved. Users don't get to see if or when the onTap function has finished execution, or if it has even finished sucessfully. To put it simply, this project aims to make them a little un-boring.

What is this?

This project provides you with the same buttons that you are used to, just with some modifications under the hood. You can manipulate the button state based on whether the onTap function is idle, loading or has finished loading(successfully or unsuccessfully).

How to use it?

This project provides you with 3 types of buttons. Let's list them below with an example.

AsyncElevatedBtn

Just like ElevatedButton, but for async onPressed

AsyncBtnStatesController btnStateController = AsyncBtnStatesController();

AsyncElevatedBtn(
  asyncBtnStatesController: btnStateController,
  onPressed: () async {
    btnStateController.update(AsyncBtnState.loading);
    try {
      // Await your api call here
      await Future.delayed(const Duration(seconds: 2));
      btnStateController.update(AsyncBtnState.success);
    } catch (e) {
      btnStateController.update(AsyncBtnState.failure);
    }
  },
  // * It is NOT mandatory to define [loadingStyle, successStyle, failureStyle]
  // * if you don't need it.

  // This should ideally be the button's loading state indicator.
  // If [style] or [widget] properties are not defined, we consider the button's
  // corresponding default [style] and [child] property
  loadingStyle: AsyncBtnStateStyle(
    style: ElevatedButton.styleFrom(
      backgroundColor: Colors.amber,
    ),
    widget: const SizedBox.square(
      dimension: 24,
      child: CircularProgressIndicator(
        color: Colors.white,
      ),
    ),
  ),

  // This should ideally be the button's success state indicator.
  // If [style] or [widget] properties are not defined, we consider the button's
  // corresponding default [style] and [child] property
  successStyle: AsyncBtnStateStyle(
    style: ElevatedButton.styleFrom(
      backgroundColor: Colors.green,
      foregroundColor: Colors.white,
    ),
    widget: Row(
      mainAxisSize: MainAxisSize.min,
      children: const [
        Icon(Icons.check),
        SizedBox(width: 4),
        Text('Success!')
      ],
    ),
  ),

  // This should ideally be the button's failure state indicator.
  // If [style] or [widget] properties are not defined, we consider the button's
  // corresponding default [style] and [child] property
  failureStyle: AsyncBtnStateStyle(
    style: ElevatedButton.styleFrom(
      backgroundColor: Colors.red,
      foregroundColor: Colors.white,
    ),
    widget: Row(
      mainAxisSize: MainAxisSize.min,
      children: const [
        Icon(Icons.error),
        SizedBox(width: 4),
        Text('Error!'),
      ],
    ),
  ),
  child: const Text('Execute'),
);

Too much? We have created a custom constructor that uses the exact values for loadingStyle, successStyle and failureStyle as above

AsyncBtnStatesController btnStateController = AsyncBtnStatesController();

AsyncElevatedBtn.withDefaultStyles(
  asyncBtnStatesController: btnStateController,
  onPressed: () async {
    btnStateController.update(AsyncBtnState.loading);
    try {
      // Await your api call here
      await Future.delayed(const Duration(seconds: 2));
      btnStateController.update(AsyncBtnState.success);
    } catch (e) {
      btnStateController.update(AsyncBtnState.failure);
    }
  },
  child: const Text('Execute'),
);

AsyncTextBtn

And this is our version of async TextButton

AsyncBtnStatesController btnStateController = AsyncBtnStatesController();

AsyncTextBtn(
  asyncBtnStatesController: btnStateController,
  onPressed: () async {
    btnStateController.update(AsyncBtnState.loading);
    try {
      // Await your api call here
      await Future.delayed(const Duration(seconds: 2));
      btnStateController.update(AsyncBtnState.success);
    } catch (e) {
      btnStateController.update(AsyncBtnState.failure);
    }
  },
  // * It is NOT mandatory to define [loadingStyle, successStyle, failureStyle]
  // * if you don't need it.

  // This should ideally be the button's loading state indicator.
  // If [style] or [widget] properties are not defined, we consider the button's
  // corresponding default [style] and [child] property
  loadingStyle: AsyncBtnStateStyle(
    style: TextButton.styleFrom(
      foregroundColor: Colors.amber,
    ),
    widget: const SizedBox.square(
      dimension: 24,
      child: CircularProgressIndicator(
        color: Colors.amber,
      ),
    ),
  ),


  // This should ideally be the button's success state indicator.
  // If [style] or [widget] properties are not defined, we consider the button's
  // corresponding default [style] and [child] property
  successStyle: AsyncBtnStateStyle(
    style: TextButton.styleFrom(
      foregroundColor: Colors.green,
    ),
    widget: Row(
      mainAxisSize: MainAxisSize.min,
      children: const [
        Icon(Icons.check),
        SizedBox(width: 4),
        Text('Success!')
      ],
    ),
  ),

  // This should ideally be the button's failure state indicator.
  // If [style] or [widget] properties are not defined, we consider the button's
  // corresponding default [style] and [child] property
  failureStyle: AsyncBtnStateStyle(
    style: TextButton.styleFrom(
      foregroundColor: Colors.red,
    ),
    widget: Row(
      mainAxisSize: MainAxisSize.min,
      children: const [
        Icon(Icons.error),
        SizedBox(width: 4),
        Text('Error!')
      ],
    ),
  ),
  child: const Text('Execute'),
);

Here again, you can use the following constructor instead

AsyncBtnStatesController btnStateController = AsyncBtnStatesController();

AsyncTextBtn.withDefaultStyles(
  asyncBtnStatesController: btnStateController,
  onPressed: () async {
    btnStateController.update(AsyncBtnState.loading);
    try {
      // Await your api call here
      await Future.delayed(const Duration(seconds: 2));
      btnStateController.update(AsyncBtnState.success);
    } catch (e) {
      btnStateController.update(AsyncBtnState.failure);
    }
  },
  child: const Text('Execute'),
);

AsyncOutlinedBtn

Similarly, here's one for async OutlinedButton

AsyncBtnStatesController btnStateController = AsyncBtnStatesController();

AsyncOutlinedBtn(
  asyncBtnStatesController: btnStateController,
  onPressed: () async {
    btnStateController.update(AsyncBtnState.loading);
    try {
      // Await your api call here
      await Future.delayed(const Duration(seconds: 2));
      btnStateController.update(AsyncBtnState.success);
    } catch (e) {
      btnStateController.update(AsyncBtnState.failure);
    }
  },
  // * It is NOT mandatory to define [loadingStyle, successStyle, failureStyle]
  // * if you don't need it.

  // This should ideally be the button's loading state indicator.
  // If [style] or [widget] properties are not defined, we consider the button's
  // corresponding default [style] and [child] property
  loadingStyle: AsyncBtnStateStyle(
    style: OutlinedButton.styleFrom(
      foregroundColor: Colors.amber,
    ),
    widget: const SizedBox.square(
      dimension: 24,
      child: CircularProgressIndicator(
        color: Colors.amber,
      ),
    ),
  ),

  // This should ideally be the button's success state indicator.
  // If [style] or [widget] properties are not defined, we consider the button's
  // corresponding default [style] and [child] property
  successStyle: AsyncBtnStateStyle(
    style: OutlinedButton.styleFrom(
      foregroundColor: Colors.green,
    ),
    widget: Row(
      mainAxisSize: MainAxisSize.min,
      children: const [
        Icon(Icons.check),
        SizedBox(width: 4),
        Text('Success!')
      ],
    ),
  ),

  // This should ideally be the button's failure state indicator.
  // If [style] or [widget] properties are not defined, we consider the button's
  // corresponding default [style] and [child] property
  failureStyle: AsyncBtnStateStyle(
    style: OutlinedButton.styleFrom(
      foregroundColor: Colors.red,
    ),
    widget: Row(
      mainAxisSize: MainAxisSize.min,
      children: const [
        Icon(Icons.error),
        SizedBox(width: 4),
        Text('Error!')
      ],
    ),
  ),
  child: const Text('Execute'),
);

Here as well, there is an alternative constructor

AsyncBtnStatesController btnStateController = AsyncBtnStatesController();

AsyncOutlinedBtn.withDefaultStyles(
  asyncBtnStatesController: btnStateController,
  onPressed: () async {
    btnStateController.update(AsyncBtnState.loading);
    try {
      // Await your api call here
      await Future.delayed(const Duration(seconds: 2));
      btnStateController.update(AsyncBtnState.success);
    } catch (e) {
      btnStateController.update(AsyncBtnState.failure);
    }
  },
  child: const Text('Execute'),
);

More Intuitive Examples

All buttons also supports these arguments - styleBuilder, loadingStyleBuilder, successStyleBuilder and failureStyleBuilder which creates the custom state styles at runtime. This essentially mean that one can create unlimited number of custom state widgets and styles based on different conditions.

There are also scopes for fallback styles and widgets if none of the necessary conditions are met.

Login Button

Click here for Code!

Download Button

Click here for Code!

Similar Projects

If this library doesn't cater to your requirements. Here are the some similar projects you can explore:

  • async_button_builder

  • easy_loading_button

  • animated_loading_button

Contribute

The creator always appreciates a helping hand, so don't hesitate before creating a pull request or reporting a bug/issue.

Connect with the Creator

The creator does aspire to help grow the flutter community. So if you have a question related to this project, your project, or anything flutter, connect with him over the following links. Don't worry, it's free!😉


Made with ❤️
Abhishek GitHub avatar
GitHub 작성자

Abhishek ↗

He likes coding. Oh sorry, did I say "likes"? I meant "is OBSESSED with coding"! Currently he's making mobile apps with Flutter & also some web development

언어Dart

분류

이 저장소가 배포한 패키지

사용 중인 의존성

의존성 목록 3 개

  • flutter{"sdk":"flutter"}
  • flutter_test개발 의존성{"sdk":"flutter"}
  • flutter_lints개발 의존성^2.0.0

프로젝트에 맞는 저장소를 선택하려면?

사용 목적에 따라 검색하고 개발 활동을 비교한 뒤 원본 저장소에서 요구 사항을 확인하세요.

  1. 이름, 작성자 또는 설명으로 검색하고 기술 주제로 범위를 좁힙니다.
  2. 스타, 포크, 최근 푸시를 함께 비교하세요. 스타는 관심의 지표이며 품질을 보장하지 않습니다.
  3. 사용하기 전에 GitHub에서 README, 라이선스, Issues를 확인하세요.

출처 및 관리

“A repository is the most basic element of GitHub.”

GitHub Docs — About repositories ↗