I already have initialise the bool variable then create a function and add it to my init state so as soon as the app loads it fetch the value. but instead of bring the value from the function it keeps bringing the initialise value
bool hasInternet = false;
void initialization() async {
hasInternet = await InternetConnectionChecker().hasConnection;
print('ready in 3...');
await Future.delayed(const Duration(seconds: 1));
print('ready in 2...');
await Future.delayed(const Duration(seconds: 1));
print('ready in 1...');
await Future.delayed(const Duration(seconds: 1));
print('go!');
FlutterNativeSplash.remove();
}
The hasInternet is the variable I want to use in my widget
CodePudding user response:
In a statefulwidget you need to update the state of your widget before the variable change is applied calling setState((){})
Problem with that is you need to wait for your widget to be build before you can call a new rebuild to apply the changes, to do this, we include a WidgetsBinding.instance.addPostFrameCallback in widget init to call your function after the widget is build, preventing the error.
If this is a check you do in everypage and you don't mind calling it or copying same code over and over again, then you can use the following example using a statefulwidget, else i would recomend you use a state mangement package like Provider that notifies every widget in your app of a variable change you define;
Hope it helps:
class YellowBird extends StatefulWidget {
const YellowBird({Key? key}) : super(key: key);
@override
State<YellowBird> createState() => _YellowBirdState();
}
class _YellowBirdState extends State<YellowBird> {
bool hasInternet = false;
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback((_) => initialization());
}
Future initialization() async {
hasInternet = await InternetConnectionChecker().hasConnection;
print('ready in 3...');
await Future.delayed(const Duration(seconds: 1));
print('ready in 2...');
await Future.delayed(const Duration(seconds: 1));
print('ready in 1...');
await Future.delayed(const Duration(seconds: 1));
print('go!');
FlutterNativeSplash.remove();
setState(() {});
}
@override
Widget build(BuildContext context) {
return Text("Has Internet: $hasInternet");
}
}
CodePudding user response:
bool hasInternet = false;
void initState() {
checkInternt();
print('ready in 3...');
await Future.delayed(const Duration(seconds: 1));
print('ready in 2...');
await Future.delayed(const Duration(seconds: 1));
print('ready in 1...');
await Future.delayed(const Duration(seconds: 1));
print('go!');
FlutterNativeSplash.remove();
}
checkInternet()async{
hasInternet = await InternetConnectionChecker().hasConnection;
}
Use in this way it will work .thanks
CodePudding user response:
It would be great to handle with state-management like provider/riverpod/bloc while we need to consider UI update. But for now, you can go for ValueNotifier
. Put it outside the class to be public,
final ValueNotifier<bool> hasInternet = ValueNotifier(false);
To change its value
hasInternet.value = true;
To rebuild the widget on value changes, use ValueListenableBuilder
.
ValueListenableBuilder<bool>(
valueListenable: hasInternet,
builder: (context, value, child) {
return Text("hasInternet $value");
},
),
You can listen the changes like hasInternet.value
.
More about ValueNotifier
and ValueListenableBuilder