Is there any possible way to control the state of the Widgets outside of them? I've tried using global keys, but is there anything easier to use? I've read that using of the global keys is not the best way from the optimization side. I don't want to use Flutter navigation utils, but, if I will if I have no choice, since I have too many problems with global keys now.
I tried to implement the following ScreenSwitcher with screens.dart file, but there are too many stupid moments, in my opinion.
This file contains all of my screens, with globalKeys and end actions for anims, that deletes my widget from the stack
screens.dart:
GlobalKey<ScreenSwitcherState> stackSwitcherStateKey = GlobalKey();
enum ScreenUniqueID {
uiLauncherLogo,
uiLauncherMain,
uiLauncherModal,
uiLauncherSettings,
uiLauncherServers,
uiLauncherSocial,
uiLauncherAccount,
}
GlobalKey<LauncherMainScreenState> screenKeyLauncherMain =
GlobalKey<LauncherMainScreenState>();
GlobalKey<LauncherModalScreenState> screenKeyLauncherModal =
GlobalKey<LauncherModalScreenState>();
GlobalKey<LauncherSettingsScreenState> screenKeyLauncherSettings =
GlobalKey<LauncherSettingsScreenState>();
GlobalKey<LauncherLogoScreenState> screenKeyLauncherLogo =
GlobalKey<LauncherLogoScreenState>();
GlobalKey<LauncherServersScreenState> screenKeyLauncherServers =
GlobalKey<LauncherServersScreenState>();
GlobalKey<LauncherSocialBonusScreenState> screenKeyLauncherSocial =
GlobalKey<LauncherSocialBonusScreenState>();
GlobalKey<LauncherAccountScreenState> screenKeyLauncherAccount =
GlobalKey<LauncherAccountScreenState>();
var screensDb = <ScreenObject>[
ScreenObject(
key: screenKeyLauncherLogo,
widget: LauncherLogoScreen(
key: screenKeyLauncherLogo,
onAnimationEndAction: () {
stackSwitcherStateKey.currentState
?.removeScreen(screenKeyLauncherLogo);
},
)),
ScreenObject(
key: screenKeyLauncherMain,
widget: LauncherMainScreen(
key: screenKeyLauncherMain,
onAnimationEndAction: () {
stackSwitcherStateKey.currentState
?.removeScreen(screenKeyLauncherMain);
},
).animate(effects: [const FadeEffect()])),
ScreenObject(
key: screenKeyLauncherModal,
widget: LauncherModalScreen(
modalKey: screenKeyLauncherModal,
onAnimationEndAction: () {
stackSwitcherStateKey.currentState
?.removeScreen(screenKeyLauncherModal);
}, positiveText: '', negativeText: '', dialogText: '', svgAssetName: '', onPositiveButtonAction: (){}, onNegativeButtonAction: (){}, negativeVisible: true,
).animate(effects: [const FadeEffect()])),
ScreenObject(
key: screenKeyLauncherSettings,
widget: LauncherSettingsScreen(
key: screenKeyLauncherSettings,
onAnimationEndAction: () {
stackSwitcherStateKey.currentState
?.removeScreen(screenKeyLauncherSettings);
},
)),
ScreenObject(
key: screenKeyLauncherServers,
widget: LauncherServersScreen(
key: screenKeyLauncherServers,
onAnimationEndAction: () {
stackSwitcherStateKey.currentState
?.removeScreen(screenKeyLauncherServers);
},
)),
ScreenObject(
key: screenKeyLauncherSocial,
widget: LauncherSocialBonusScreen(
key: screenKeyLauncherSocial,
onAnimationEndAction: () {
stackSwitcherStateKey.currentState
?.removeScreen(screenKeyLauncherSocial);
},
)),
ScreenObject(
key: screenKeyLauncherAccount,
widget: LauncherAccountScreen(
key: screenKeyLauncherAccount,
onAnimationEndAction: () {
stackSwitcherStateKey.currentState
?.removeScreen(screenKeyLauncherAccount);
},
)),
];
screen_switcher.dart:
class ScreenSwitcher extends StatefulWidget {
Function onWidgetLoaded;
final GlobalKey<ScreenSwitcherState> stackSwitcherStateKey;
ScreenSwitcher(this.onWidgetLoaded, this.stackSwitcherStateKey)
: super(key: stackSwitcherStateKey);
@override
ScreenSwitcherState createState() => ScreenSwitcherState();
}
class ScreenSwitcherState extends State<ScreenSwitcher> {
var activeScreens = <ScreenObject>[];
@override
void initState() {
// TODO: implement initState
super.initState();
widget.onWidgetLoaded();
print("onWidgetLoaded");
}
@override
Widget build(BuildContext context) {
return Stack(
children: [Stack(children: activeScreens.map((e) => e.widget).toList())],
);
}
Future<void> removeScreen(Key key) async {
setState(() {
var listToRemove = [];
for (var element in activeScreens) {
if (element.key == key) {
listToRemove.add(element);
}
}
activeScreens.removeWhere((element) => listToRemove.contains(element));
});
}
void showScreen(int ui) async {
setState(() {
ScreenObject screen = screensDb.elementAt(ui);
if(ui == ScreenUniqueID.uiLauncherMain.index){
GlobalKey<LauncherMainScreenState> screenKeyLauncherMain1 = GlobalKey<LauncherMainScreenState>();
screen = ScreenObject(
key: screenKeyLauncherMain1,
widget: LauncherMainScreen(
key: screenKeyLauncherMain1,
onAnimationEndAction: () {
stackSwitcherStateKey.currentState
?.removeScreen(screenKeyLauncherMain1);
},
).animate(effects: [const FadeEffect()]));
screensDb[ScreenUniqueID.uiLauncherMain.index] = screen;
}
if(ui == ScreenUniqueID.uiLauncherAccount.index){
GlobalKey<LauncherAccountScreenState> screenKeyLauncherAcc = GlobalKey<LauncherAccountScreenState>();
screen = ScreenObject(
key: screenKeyLauncherAcc,
widget: LauncherAccountScreen(
key: screenKeyLauncherAcc,
onAnimationEndAction: () {
stackSwitcherStateKey.currentState
?.removeScreen(screenKeyLauncherAcc);
},
).animate(effects: [const FadeEffect()]));
screensDb[ScreenUniqueID.uiLauncherAccount.index] = screen;
}
if (activeScreens.any((element) => screen.key == element.key)) {
return;
}
activeScreens.add(screen);
});
}
void showModal(
String positiveText,
String negativeText,
String dialogText,
String svgAssetName,
Function onPositiveButtonAction,
Function onNegativeButtonAction,
bool negativeVisible) async {
GlobalKey<LauncherModalScreenState> globalKey = GlobalKey();
screensDb[ScreenUniqueID.uiLauncherModal.index] = ScreenObject(
key: globalKey,
widget: LauncherModalScreen(
onAnimationEndAction: () {
stackSwitcherStateKey.currentState?.removeScreen(globalKey);
},
modalKey: globalKey,
positiveText: positiveText,
negativeText: negativeText,
dialogText: dialogText,
svgAssetName: svgAssetName,
onPositiveButtonAction: onPositiveButtonAction,
onNegativeButtonAction: onNegativeButtonAction,
negativeVisible: negativeVisible,
));
ScreenObject screen =
screensDb.elementAt(ScreenUniqueID.uiLauncherModal.index);
setState(() {
activeScreens.add(screen);
});
}
void hideScreen(int ui) {
print("hideScreen " + ui.toString());
ScreenObject screen = screensDb.elementAt(ui);
setState(() {
(screen.key.currentState as WidgetUI).removeView();
});
}
}