I wrote the code like data: (data){Navigator.of(context).pop();},//here
to pop showDialog
but actually other Navigator.of(context)
was popped and figured out that I should distinguish inner context
in builder: (context) { //here2
from outer context
but could not reach how to do that. Would somebody please give me some advise to solve this ?
final authC = ref.watch(authFutureProvider);
authC.when(
data: (data){Navigator.of(context).pop();},//here
error: (error, stackTrace) {},
loading: () {
final loading =
WidgetsBinding.instance.addPostFrameCallback((_) {
showDialog(
barrierDismissible: false,
context: context,
builder: (context) { //here2
return const Center(
child: CircularProgressIndicator(),
);
}
);
});
},
);
CodePudding user response:
I strongly not recommend WidgetsBinding.instance.addPostFrameCallback to show loading because it takes time to render, so your app will load a loading function. It will make End-user can do multiple clicks on the button because the loading has not rendered yet.
this package is verylight and easy to use, the dismiss and show even different from regular widget, so you will not accidentally close your screen because wrong logic or back-end handler failure.
class LoadingExample {
showLoadingExample(){
EasyLoading.instance
..displayDuration = const Duration(milliseconds: 2000)
..indicatorType = EasyLoadingIndicatorType.fadingCircle
..loadingStyle = EasyLoadingStyle.dark
..indicatorSize = 45.0
..radius = 10.0
..progressColor = Colors.yellow
..backgroundColor = Colors.green
..indicatorColor = Colors.yellow
..textColor = Colors.yellow
..maskColor = Colors.blue.withOpacity(0.5)
..userInteractions = true
..dismissOnTap = false
..customAnimation = CustomAnimation();
}
dismissExampleLoading(){
EasyLoading.dismiss();
}
}
to call it simply do: *I recommend OOP so you can modify it in 1 place when you need.
LoadingExample().showLoadingExample();
or
LoadingExample().dismissExampleLoading();
even you accidentally call show or dissmiss multiple time, the loading will not stack, and it will just recall or reset the animation. So your app will not crash
CodePudding user response:
Well, you can easily define different BuildContexts by giving them different names, like this:
@override
Widget build(BuildContext parentContext) {
final authC = ref.watch(authFutureProvider);
authC.when(
data: (data){Navigator.of(parentContext).pop();},//here
error: (error, stackTrace) {},
loading: () {
final loading =
WidgetsBinding.instance.addPostFrameCallback((_) {
showDialog(
barrierDismissible: false,
context: parentContext,
builder: (context) { //here2
return const Center(
child: CircularProgressIndicator(),
);
}
);
});
},
);
return Widget();
}
However, that won't change the fact that the context I've named "parentContext" is the parent context! This is the context sent TO the Dialog, not the context of the Dialog itself.
If you want to pop whichever context is on top at the moment, you can define a GlobalKey variable like this:
//global.dart
import 'package:flutter/material.dart';
class GlobalVariable {
static final GlobalKey<NavigatorState> navState = GlobalKey<NavigatorState>();
}
Then, you can pop the current context like this, from anywhere:
import 'global.dart';
void func(){
Navigator.pop(GlobalVariable.navState.currentContext!);
}
That should pop the Dialog IF the Dialog is currently on top...
But of course, if some other BuildContext is on top, then that will be popped, instead.