/flutter_smart_dialog

An elegant Flutter Dialog solution | 一种更优雅的 Flutter Dialog 解决方案

Primary LanguageDartMIT LicenseMIT

pub stars issues commit

Language: English | 中文

Migrate doc:3.x migrate 4.0 | 3.x 迁移 4.0

Flutter 2:Please use flutter_smart_dialog: 4.0.9+5

Flutter 3:Please use the latest version

Introduction

An elegant Flutter Dialog solution.

Some Effect

attachLocationAndPoint

attachHighlight

dialogStack

loadingCustom

toastCustom

Advantage

  • Do not need BuildContext

  • Can penetrate dark background, click on the page behind dialog

  • Support dialog stack,close the specified dialog

  • Support positioning widget, display the specified location dialog

  • Support highlight feature,dissolve the specified location mask

  • Easily implement toast,loading,attach dialog,custome dialog

Quick start

Install

Initialization

initialization

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomePage,
      // here
      navigatorObservers: [FlutterSmartDialog.observer],
      // here
      builder: FlutterSmartDialog.init(),
    );
  }
}

Advanced initialization: configure global custom Loading and Toast

SmartDialog's showLoading and showToast provide a default style. Of course, custom param are definitely supported.

  • SmartDialog custom Loading or Toast is very simple: However, when using it, it may make you feel a little troublesome
  • for example
    • Use custom Loading: SmartDialog.showLoading(builder: (_) => CustomLoadingWidget);
    • The effect we want must be like this: SmartDialog.showLoading();
  • In view of the above considerations, I added the function of setting custom default Loading and Toast styles at the entrance

Let me show you the following

  • The entry needs to be configured: implement toastBuilder and loadingBuilder, and pass in custom Toast and Loading
void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomePage,
      // here
      navigatorObservers: [FlutterSmartDialog.observer],
      // here
      builder: FlutterSmartDialog.init(
        //default toast widget
        toastBuilder: (String msg) => CustomToastWidget(msg: msg),
        //default loading widget
        loadingBuilder: (String msg) => CustomLoadingWidget(msg: msg),
      ),
    );
  }
}

Easy usage

  • toast usage💬
SmartDialog.showToast('test toast');

toastDefault

  • loading usage
SmartDialog.showLoading();
await Future.delayed(Duration(seconds: 2));
SmartDialog.dismiss(); 

loadingDefault

  • dialog usage🎨
SmartDialog.show(builder: (context) {
  return Container(
    height: 80,
    width: 180,
    decoration: BoxDecoration(
      color: Colors.black,
      borderRadius: BorderRadius.circular(10),
    ),
    alignment: Alignment.center,
    child:
    Text('easy custom dialog', style: TextStyle(color: Colors.white)),
  );
});

dialogEasy

You may have questions

For details, please check: Some Consideration Details

initBack

hardClose

Attach Chapter

For details, please check: Attach Chapter Details

This is a very important function. I wanted to add it a long time ago, but it was busy and has been shelved; New Year's Day (2022.1.1) started, and it took some time to complete this function and related demos.

attachLocation

attachImitate

attachGuide

Dialog Chapter

For details, please check: Dialog Chapter Details

dialogLocation

dialogPenetrate

dialogStack

Loading Chapter

For details, please check: Loading Chapter Details

loadingOne

loadingSmile

loadingNormal

Toast Chapter

For details, please check: Toast Chapter Details

toastOne

toastSmart

toastCustom

Little tricks of anger

There is a scene that compares the egg cone

  • We encapsulated a small component using StatefulWidget
  • In a special situation, we need to trigger a method inside this component outside the component
  • There are many implementation methods for this kind of scene, but it may be a little troublesome to make it

Here is a simple idea, which can be triggered very easily, a method inside the component

  • Create a widget
class OtherTrick extends StatefulWidget {
  const OtherTrick({Key? key, this.onUpdate}): super(key: key);

  final Function(VoidCallback onInvoke)? onUpdate;

  @override
  _OtherTrickState createState() => _OtherTrickState();
}

class _OtherTrickState extends State<OtherTrick> {
  int _count = 0;

  @override
  void initState() {
    // here
    widget.onUpdate?.call(() {
      _count++;
      setState(() {});
    });

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        padding: EdgeInsets.symmetric(horizontal: 50, vertical: 20),
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(10),
        ),
        child: Text('Counter: $_count', style: TextStyle(fontSize: 30.0)),
      ),
    );
  }
}
  • Show this component and then trigger it externally
void _otherTrick() async {
  VoidCallback? callback;

  // display
  SmartDialog.show(
    alignment: Alignment.center,
    builder: (_) =>
    OtherTrick(onUpdate: (VoidCallback onInvoke) => callback = onInvoke),
  );

  await Future.delayed(const Duration(milliseconds: 500));

  // handler
  SmartDialog.show(
    alignment: Alignment.centerRight,
    maskColor: Colors.transparent,
    builder: (_) {
      return Container(
        height: double.infinity,
        width: 150,
        color: Colors.white,
        alignment: Alignment.center,
        child: ElevatedButton(
          child: const Text('add'),
          onPressed: () => callback?.call(),
        ),
      );
    },
  );
}
  • Let's see the effect

trick