foreword
flutter_smart_dialog related addresses: pub , github , web effect
An open source library, with continuous iterative optimization, will inevitably encounter a very painful problem
- The original design was not very reasonable: many new features wanted to be added were hindered by this
To make the library more powerful and robust, a refactoring must be done
- Because the refactoring involves the exposed API, everyone will encounter a more irritating problem: after updating the version, a large area of errors will be reported
- I have been thinking about it for a long time. How can I help you to migrate quickly? Finally came up with a reasonable solution
For the changes of flutter_smart_dialog version 4.0, many of them are to solve the historical legacy that I have not considered before. The original intention of this library was mainly to solve the problem of loading and dialog penetration; now it is extended to: custom dialog, attach dialog, loading, toast , the initial design is really inadequate, the API in config is difficult to subdivide the functions of these four modules, and the design of some parameters is not reasonable based on the current functions and scenarios, etc.
I hope everyone can understand why I want to refactor 🥺, I am definitely not doing things 🥺
Quick Migration Guide
Compatible API (required) ⭐️
illustrate
- The show method is fast compatible
SmartDialog.compatible.show();
SmartDialog.compatible.showAttach();
SmartDialog.compatible.showLoading();
SmartDialog.compatible.showToast();
- config fast compatible
SmartDialog.compatible.config;
Added compatible
intermediate variable, which can be quickly compatible with the changed parameters
Quick action
Quick migration using global replace function:
SmartDialog.show
--->SmartDialog.compatible.show
- Mac: command + shift + r
- Windows: ctrl+shift+r
Config:
SmartDialog.config
--->SmartDialog.compatible.config
- Mac: command + shift + r
- Windows: ctrl+shift+r
Parameter removal (required) ⭐️
- Version 4.0 removed a small number of parameters
method | illustrate |
---|---|
showLoading(...) | Delete the background parameter (compatible is not compatible with this parameter) |
showToast(...) | Remove the alignment parameter (compatible with this parameter) |
showAttach(...) | Delete the highlight parameter (compatible with this parameter) |
- These parameters are deleted. When initializing custom loading and toast, you need to make a little adjustment
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),
),
);
}
}
illustrate
background
and alignment
these two parameters are really useless, the frequency used is too low
Generally, the toast and loading styles are customized, and you can draw as you want; if you simply use toast and loading, these two parameters cannot achieve a strong custom effect, which is too cumbersome and simply deleted.
Parameter name change (optional)
Through the above 兼容API
and 参数移除
you can complete the migration
Here I will write down the changed parameter names completely, you can compare them
original parameter name | change parameter name |
---|---|
widget | builder: Align with the routing dialog parameter (see the description of the builder parameter below for details) |
isLoading / isLoadingTemp | animationType: It is convenient to expand various animation types later |
isPenetrate / isPenetrateTemp | usePenetrate: true (click events will penetrate the background), false (do not penetrate) |
isUseAnimation / isUseAnimationTemp | useAnimation: true (use animation), false (do not use) |
clickBgDismiss / clickBgDismissTemp | clickMaskDismiss: true (close the dialog after clicking on the mask), false (do not close) |
animationDuration / animationDurationTemp | animationTime: animation duration |
alignmentTemp | alignment: controls the position of the pop-up window |
maskColorTemp | maskColor: mask color |
maskWidgetTemp | maskWidget: Highly customizable mask |
debounceTemp | debounce: Anti-shake function |
time(showToast) | displayTime: toast display time |
type(showToast) | displayType: Multiple types of toast display logic |
Builder parameter description (important)
Version 4.0 has made a lot of changes to custom control parameters
- old version
SmartDialog.show(
widget: 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),
),
),
);
- Version 4.0
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),
),
);
});
Although this change will make it a little more troublesome to use, it is very important.
- The first is to align with the api of the routing dialog, and the custom control parameters of the routing dialog are also builder
- Then solve the problem of dynamic refresh of the custom dialog itself: the custom layout has TextField, when the keyboard pops up, the custom dialog layout can dynamically adjust the distance (need to use the corresponding widget)
What's New in Version 4.0
Powerful Config
- You can use config to get whether the dialog exists
// 自定义dialog,attach或loading,是否存在在界面上
SmartDialog.config.isExist;
// 自定义dialog或attach是否存在在界面上
SmartDialog.config.isExistDialog;
// loading是否存在界面上
SmartDialog.config.isExistLoading;
// toast是否存在在界面上
SmartDialog.config.isExistToast;
config can control show, showAttach, showLoading, showToast and other pop-up windows in more detail
- The default parameters of SmartConfigXxx() are all set by me after deep thinking, and no additional settings are required if there are no special requirements.
- If you do not need to customize the config value, the initialization code below does not need to be written
SmartDialog.config
..custom = SmartConfigCustom()
..attach = SmartConfigAttach()
..loading = SmartConfigLoading()
..toast = SmartConfigToast();
You can customize the values in any config to meet the corresponding needs
- The code below is to demonstrate custom parameters
- You can set as needed
SmartDialog.config
..custom = SmartConfigCustom(
maskColor: Colors.black.withOpacity(0.35),
useAnimation: true,
)
..attach = SmartConfigAttach(
animationType: SmartAnimationType.scale,
usePenetrate: false,
)
..loading = SmartConfigLoading(
clickMaskDismiss: false,
leastLoadingTime: const Duration(milliseconds: 0),
)
..toast = SmartConfigToast(
intervalTime: const Duration(milliseconds: 100),
displayTime: const Duration(milliseconds: 2000),
);
bindPage
illustrate
The meaning of this parameter is to bind the SmartDialog to the page: if the page is jumped on the SmartDialog
- Binding SmartDialog to the current page will automatically hide
- When back to the binding page, the SmartDialog will show
Regarding the problem of jumping pages on the Dialog, the version before 4.0 can be solved by using the useSystem
parameter
- When using the
useSystem
parameter, the essence is to use the built-in dialog as the carrier, so that you can interact with the page reasonably - 但是因为自带dialog的各种局限,使用
useSystem
时:usePenetrate
,tag
,KeepSingle
,permanent
all banned
The logic of bindPage introduced in version 4.0 can avoid various restrictions when using useSystem
bindPage is enabled by default (can be configured in config), and can also be manually disabled or enabled when using show and showAttach; in special business scenarios, use bindPage
and useSystem
Just
Effect
- Write a demo, this is the normal operation of jumping pages on the pop-up window
void _dialogBindPage() async {
var index = 0;
Function()? showDialog;
toNewPage(bool useSystem) async {
Get.to(
() {
return Scaffold(
appBar: AppBar(title: Text('New Page ${++index}')),
body: Container(
color: randomColor(),
alignment: Alignment.center,
child: ElevatedButton(
onPressed: () => showDialog?.call(),
child: Text('test bindPage $index'),
),
),
);
},
preventDuplicates: false,
);
}
showDialog = () {
SmartDialog.show(builder: (_) {
return Container(
width: 300,
height: 170,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
),
child: ElevatedButton(
onPressed: () => toNewPage(false),
child: Text('test bindPage $index'),
),
);
});
};
showDialog();
}
to see the effect
- To be honest, the effect is silky without the useSystem function
- But bindPage also solves the problem of jumping pages on the pop-up window, while retaining functions such as usePenetrate, tag, KeepSingle, permanent, etc.
- Everyone needs to use
Carry data when closing popup
This function is closed with flutter routing, and the function of carrying return data is aligned
- Take a look at the demo: Click the
show result
button to close the pop-up window and return the data in the input box
void _dialogCarryResult() async {
var result = await SmartDialog.show(builder: (_) {
var message = '';
return Container(
width: 300,
height: 170,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
),
child: Column(mainAxisSize: MainAxisSize.min, children: [
Container(
width: 100,
margin: EdgeInsets.only(bottom: 30),
child: TextField(onChanged: (msg) => message = msg),
),
ElevatedButton(
onPressed: () => SmartDialog.dismiss(result: message),
child: Text('show result'),
)
]),
);
});
SmartDialog.showToast("$result");
}
- Effect
Persistent Dialog
Set the permanent
parameter to true, the opened dialog will become a permanent dialog, and all the closing operations (returning events, routing pop, clicking on the mask, etc.) inside the framework will be invalid, and only manual closure
Please use this function in combination with actual business scenarios and do not abuse it
- Open a persistent dialog
SmartDialog.show(
permanent: true,
usePenetrate: true,
builder: (_) => Container(width: 150, height: 150, color: Colors.black),
);
- Close the permanent dialog
SmartDialog.dismiss(force: true);
- Take a look at the demo
void _dialogPermanent() async {
openPermanentDialog() {
SmartDialog.show(
permanent: true,
alignment: Alignment.centerRight,
usePenetrate: true,
clickMaskDismiss: false,
builder: (_) {
return Container(
width: 150,
height: double.infinity,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
bottomLeft: Radius.circular(20),
),
boxShadow: [
BoxShadow(color: Colors.grey, blurRadius: 8, spreadRadius: 0.2)
],
),
child: Text('permanent dialog'),
);
},
);
}
SmartDialog.show(builder: (_) {
return Container(
width: 300,
height: 170,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
),
child: Wrap(spacing: 20, children: [
ElevatedButton(
onPressed: () => openPermanentDialog(),
child: Text('open'),
),
ElevatedButton(
onPressed: () => SmartDialog.dismiss(force: true),
child: Text('close'),
)
]),
);
});
}
- Effect: You can see the pop route, click on the mask and return events, can not be closed
permanent dialog
Minimum load time
There is a leastLoadingTime
parameter in loading in config, which can control the minimum loading time
This function is to solve the problem that the interface request is too fast, causing the loading pop-up window to flash by.
Use: Please set appropriate data for this parameter in combination with the actual business scenario. The default value of leastLoadingTime is 0 seconds.
- It is only for demonstration here, and config.loading is reassigned here. Generally, it is recommended to set the parameters in the initialization position of the app.
- Call dismiss immediately after showLoading(), and loading will flash by
- If the leastLoadingTime is set to 2 seconds, the loading will be forced to wait for two seconds before the dismiss will take effect.
void _loadingLeastTime() async {
SmartDialog.config.loading = SmartConfigLoading(
leastLoadingTime: const Duration(seconds: 2),
);
SmartDialog.showLoading();
SmartDialog.dismiss();
SmartDialog.config.loading = SmartConfigLoading();
}
- Effect
Continuous toast display interval time
When multiple toasts are displayed continuously, the previous toast and the next toast display no interval time, which looks a bit awkward
Here, a SmartConfigToast
intervalTime
parameter is added to ---742f2f2221158cbcbb1c47da0ffe53dd--- to control the interval time
The default intervalTime
is already a reasonable parameter, if it is unnecessary, it is best not to change it
- Take a look at the effect, just for demonstration,
intervalTime
value is set slightly larger
void _toastIntervalTime() async {
SmartDialog.config.toast = SmartConfigToast(
intervalTime: const Duration(milliseconds: 800),
);
for (var i = 0; i < 3; i++) {
SmartDialog.showToast("toast $i").then((value) {
if (!SmartDialog.config.isExistToast) {
SmartDialog.config.toast = SmartConfigToast();
}
});
}
}
- renderings
Summarize
SmartDialog 4.0 version is a very important version, marking SmartDialog bid farewell to the green and mature
After this reconstruction, I also have the confidence to face more complex business scenarios and carry out various expansions.
I have done a lot of thinking about this reconstruction, and I am very grateful to everyone for giving me a variety of issues
, you have inspired me!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。