Snapshot do README original do repositório-fonte vinculado. Consulte o repositório para o conteúdo mais recente.



One Context to rule them all
OneContext provides a simple way to deal with Dialogs, Overlays, Navigations, Theme* and MediaQuery* with no need of BuildContext.
If you are Flutter developer, you don’t have to learn something new. This package use the same identificators and names from framework. It’s not a specialized* implementation, so you have the power to create and do not get blocked because of that.
If you are Flutter package developer, OneContext can be very useful too! You can create a custom dialogs package with no need BuildContext, and release a version, that do not depends of the context, to the comunity.

BuildContext always is needed (in some cases we need to choose carefully the specific one to make things work as expected), but, to global things, like dialogs, it can be reached by OneContext package. 🎯
🎮 Let's start
⚠ Important: Configure MaterialApp. e.g.
return MaterialApp(
builder: OneContext().builder,
navigatorKey: OneContext().key,
...
);
There are 2 ways to get OneContext singleton instance, OneContext() or OnceContext.intance. e.g.
OneContext().pushNamed('/detail_page');
OneContext.instance.pushNamed('/detail_page');
There are controllers to use navigation, overlays and dialogs. e.g.
OneContext().navigator.pushNamed(...);
OneContext().dialog.showDialog(...);
OneContext().overlay.addOverlay(...);
Or, you can use the shortcuts ;)
OneContext().pushNamed(...);
OneContext().showDialog(...);
OneContext().addOverlay(...);
OneContext is:
- Fast (O(1))
- Easy to learn/use
- It use same native function names from Flutter, to keep it simple and intuitive ;)
💬 How to show Dialogs with no need of the BuildContext?
OneContext().showSnackBar(
builder: (_) => SnackBar(content: Text('My awesome snackBar!'))
);
OneContext().showDialog(
builder: (_) => AlertDialog(
title: new Text("The Title"),
content: new Text("The Body"),
)
);
OneContext().showBottomSheet(
builder: (context) => Container(
alignment: Alignment.topCenter,
height: 200,
child: IconButton(
icon: Icon(Icons.arrow_drop_down),
iconSize: 50,
color: Colors.white,
onPressed: () => Navigator.of(context).pop('sucess')),
),
);
OneContext().showModalBottomSheet<String>(
builder: (context) => Container(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
leading: Icon(Icons.music_note),
title: Text('Music'),
onTap: () => OneContext().popDialog('Music');
ListTile(
leading: Icon(Icons.videocam),
title: Text('Video'),
onTap: () => Navigator.of(context).pop('Video'),
),
SizedBox(height: 45)
],
),
)
);
⛵ How to navigate? (All methods from Navigator Class are available)
OneContext().pushNamed('/second');
OneContext().push(MaterialPageRoute(builder: (_) => SecondPage()));
OneContext().pop();
OneContext().popDialog();
String result = await OneContext().push<String>(MaterialPageRoute(builder: (_) => SecondPage()));
print(result);
🍰 How to show Overlays?
OneContext().showProgressIndicator();
OneContext().hideProgressIndicator();
OneContext().showProgressIndicator(
backgroundColor: Colors.blue.withOpacity(.3),
circularProgressIndicatorColor: Colors.white
);
OneContext().hideProgressIndicator();
OneContext().showProgressIndicator(
builder: (_) => MyAwesomeProgressIndicator();
);
OneContext().hideProgressIndicator();
String myCustomAndAwesomeOverlayId = UniqueKey().toString();
OneContext().addOverlay(
overlayId: myCustomAndAwesomeOverlayId,
builder: (_) => MyCustomAndAwesomeOverlay()
);
OneContext().removeOverlay(myCustomAndAwesomeOverlayId);
🎨 Changing Dark and Light theme mode
Breaking change: OneHotReload becomes OneNotification
⚠ Please check consideration on Theme and MediaQuery topic
OneNotification<OneThemeChangerEvent>(
stopBubbling: true,
builder: (_, __) {
return MaterialApp(
builder: OneContext().builder,
themeMode: OneThemeController.initThemeMode(ThemeMode.light),
theme: OneThemeController.initThemeData(ThemeData(brightness: Brightness.light)),
darkTheme: OneThemeController.initDarkThemeData(ThemeData(brightness: Brightness.dark)),
...
);
);
OneContext().oneTheme.toggleMode();
OneContext().oneTheme.changeDarkThemeData(
ThemeData(
primarySwatch: Colors.amber,
brightness: Brightness.dark
)
);
🚧 Reload, Restart and Reboot the app (Need bubbling events or data?)
First define the data type in type generics, after that, you can rebuild multiple ancestors widgets that listen the same data type. This is used for the package in this example, to change ThemeMode and Locale and even Restart the app entirely.
OneNotification<List<Locale>>(
onVisited: (context, localeList) {
print('widget visited!');
},
stopBubbling: true,
initialData: _localeEnglish,
rebuildOnNull: true,
builder: (context, localeList) {
return MaterialApp(
supportedLocales: localeList,
);
},
);
Need to dispatch more specialized data/event?
class MySpecializedEvent {
final String text;
MySpecializedEvent(this.text);
}
OneNotification<MySpecializedEvent>(
builder: (context, event) {
return Text(event.text);
},
)
OneNotifier.notify(
context,
NotificationPayload(
data: MySpecializedEvent('Nice!');
)
);
Reload and Restart the app
OneNotification(
builder: (_, __) => child
);
OneNotification.softReloadRoot(context);
OneNotification.hardReloadRoot(context);
Reboot and load different apps
void main() => OnePlatform.app = () => MyApp();
OnePlatform.reboot();
OnePlatform.reboot(
builder: () => MyApp()
);
OnePlatform.reboot(
builder: () => MyApp2()
);
⚙ Theme and MediaQuery
print('Platform: ' + OneContext().theme.platform);
print('Orientation: ' + OneContext().mediaQuery.orientation);
[IMPORTANT] If you need get widget rebuild on theme data changes using OneContext().oneTheme.toggleMode();, please consider to use the traditional way Theme.of(context) when getting theme data inside widget.
@override
Widget build(BuildContext context) {
return Container(
color: Theme.of(context).primaryColor,
height: 100,
width: 100,
);
}
Or you can call Theme.of(context); in the begining of build method instead;
e.g.
@override
Widget build(BuildContext context) {
Theme.of(context);
return Container(
color: OneContext().theme.primaryColor,
height: 100,
width: 100,
);
}
In initState or inside class constructor (now it's possible)
@override
void initState() {
super.initState();
OneContext().showDialog(
builder: (_) => AlertDialog(
title: new Text("On Page Load"),
content: new Text("Hello World!"),
),
);
🚦 Warnings
* OneContext().theme and OneContext().mediaQuery are global instances of the root of the widget tree. Use it with care! It can reproduce unexpected behavior if you don't understand it.
* OneContext().context is like a root context, so, it should not be used directly, as it can reproduce unexpected behaviors, unless you have a understanding how it works. It shouldn't work well with InheritedWidget for example.
* This package only uses specialized implementation in Overlays, to make things easy and ensure a quick start.
👨💻👨💻 Contributing
Contributions of any kind are welcome! I'll be glad to analyse and accept them! 👾
Sponsor
