How to stop the loader after 5 seconds - flutter

I'm trying to display the loader on whole screen on button click and after 5 seconds displaying a dialogue box an want to stop the loader. here is my code
setState(() {
_isLoading = true;
});
_isLoading
? showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return WillPopScope(
onWillPop: () async {
return false;
},
child: Center(
child: CircularProgressIndicator(
color: Apptheme.primaryColor,
),
),
);
})
: null;
await Future.delayed(const Duration(seconds: 5), () {
AppDialogs()
.showInfoDialogue(context, "Sorry all drivers are busy!", () {
Navigator.pop(context);
});
});
setState(() {
_isLoading = false;
});
calling this code on button click, it shows the dialogue box after 5 seconds but not stop the loader. kindly help where i'm doing wrong.

Once you call showDialog the loader is mounted on the screen and it will not disappear, if you have a simple setup calling .pop() on the navigator will remove your loader before you show the dialog. Modification required:
await Future.delayed(const Duration(seconds: 5), () {
Navigator.of(context).pop();
AppDialogs().showInfoDialogue(context, "Sorry all drivers are busy!", () {
Navigator.pop(context);
});
});

You can define thai cde in instate event
Future.delqyed(duration:Duration(seconds:5),(){showdialog((BuildContext context,Widget child)=>Dialog());
});
You can try this

Related

How to check Alert Dialog is open only one times instead of multiple new dialog box after onTap in flutter

I am working on my flutter application and I want to check whether the alert dialog is open or not on the screen . Can anyone tell me how to do that, now everytime i press ontap and it will appear a new dialog box. how can i only appear one dialog box instead of multiple of new dialog box ?
I have try bool, ontap cancel all not working.
Future? _dialog;
Future<void> _checkTimer() async {
if (_dialog == null) {
_dialog = await Future.delayed(Duration(seconds: 5));
showTimer(context);
await _dialog;
_dialog = null;
} else {
//do nothing
}
}
showTimer(BuildContext context) {
// set up the buttons
// ignore: deprecated_member_use
if (didUserTouchedScreen = true){
Container alert = Container(child: _imageslideshowProductDetailstimer());
// show the dialog
showDialog(
barrierDismissible: true,
context: context,
builder: (BuildContext context) {
return WillPopScope(
onWillPop: () async {
didUserTouchedScreen = false;
// _checkTimer();
return true;
},
child: alert);
},
).then((_) => didUserTouchedScreen = false);
}}
behavior: HitTestBehavior.translucent,
onTapDown: (tapdown) {
print("down");
_checkTimer();
},
onTapCancel: (){print('up');_checkTimer();}
You can achieve this with a boolean state, let's call it isButtonActive. The button is enabled/disabled depending on the value of this state. When the button is pressed, set the state to false, and when the dialog box is closed, set the state to true.
Below is an example code:
class _HomePageState extends State<HomePage> {
bool isButtonActive = true;
showTimer(BuildContext context) async {
setState(() {
isButtonActive = false;
});
await Future.delayed(Duration(seconds: 2));
showDialog(
context: context,
builder: (BuildContext context) {
return Column(
children: const [
Text('qwerty'),
],
);
},
).then((value) {
setState(() {
isButtonActive = true;
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('총톤수'),
),
body: Center(
child: ElevatedButton(
onPressed: isButtonActive ? () => showTimer(context) : null,
child: const Text('총톤수'),
),
),
);
}
}

How to auto dismiss an AlertDialog box after getting GPS point?

I am trying to make a dialog box that displays "text" after getting the location and then doing... Navigator.of(context).pop(); to auto close the dialog
Help! I am starting at Flutter... here's the code
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
......
showProgressDialogGPS(BuildContext context,
{String message = 'Loading...'}) {
showDialog(
context: context,
barrierDismissible: false,
builder: (context) {
Future.delayed(Duration(milliseconds: 50), () {
_getPosition();
Navigator.of(context).pop();
});
return AlertDialog(
actions: [],
content: Row(
children: <Widget>[
CircularProgressIndicator(),
SizedBox(width: 20),
Expanded(child: Text(message)),
],
),
);
},
);
}
Future _getPosition() async {
await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.low)
.then((value) {
print(value);
});
}
.......
Thanks guys!!!
You can modify your code like this :
Future.delayed(Duration(milliseconds: 50), () async{
await _getPosition();
Navigator.of(context).pop();
});
here you are waiting for _getPosition to be executed then the statement Navigator.of(context).pop(); will be executed.

Flutter how to ensure that a dirty widget has been re-built before continuing with execution

I am trying to take a screenshot after hiding a few parts of the UI. I can not figure out how to assure that the UI parts are hidden before I take the screenshot except using Future.delayed(). SetState only marks the widget to be re-built. How can I know when it has been?
floatingActionButton: FloatingActionButton(
child: Icon(Icons.camera, color: Colors.white, size: 45.0),
onPressed: () {
takeScreenCapture();
},
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
void takeScreenCapture() async {
if(mounted) {
setState(() {
hideUi = true;
});
}
// need a way to wait until the above change is reflected in the UI
// before exceuteing the command below
String path = await NativeScreenshot.takeScreenshot();
if(mounted) {
setState(() {
_hideUi = false;
});
}
Navigator.push(context, MaterialPageRoute(builder: (context) => ImageDisplay(path)));
}
If I delay the screenshot just a little bit the UI has time to repaint and it works but this is not something I would want in production code:
void takeScreenCapture() async {
Future.delayed(Duration(milliseconds: 100), () async {
String path = await NativeScreenshot.takeScreenshot();
setState(() {
_hideUi = false;
});
Navigator.push(context, MaterialPageRoute(builder: (context) => ImageDisplay(path)));
});
}
not sure if I understood correctly but try something like this
void takeScreenCapture() async {
setState(() {
_hideUi = false;
WidgetsBinding.instance.addPostFrameCallback((_) async {
String path = await NativeScreenshot.takeScreenshot();
Navigator.push(context, MaterialPageRoute(builder: (context) => ImageDisplay(path)));
});
});
}
#Dude had the right idea with WidgetsBinding.instance.addPostFrameCallback, just posting below what would work for my example:
void takeScreenCapture() async {
WidgetsBinding.instance.addPostFrameCallback((_) async {
String path = await NativeScreenshot.takeScreenshot();
Navigator.push(context, MaterialPageRoute(builder: (context) => ImageDisplay(path)));
setState(() {
_hideUi = false;
});
});
}

Flutter Modular Mobx - Observable doesn't update inside of onpress

I am new with Flutter and I am having a problem. I'm using mobx. In my view I have a button and inside of this button, I am waiting for the showDialog property to change in order to show the dialog view . However, within onpress the showdialog does not work. Is there any other way to do this?
My controller
#observable
bool showDialog = false;
#action
Future callLoginService() async {
await Future.delayed(Duration(seconds: 6));
showDialog = true;
}
view
Observer(
builder: (_) {
return Center(
child: RaisedButton(
child: Text("TESTE"),
onPressed: () async {
controller.callLoginService();
if (controller.showDialog) {
final action = await InfoDialogView.showAlertDialog(
context, "Try again", 'Invalid user');
if (action == DialogAction.abort) {
controller.showDialog = false;
}
}
},
),
);
},
),
This is because your onPressed method is asynchronous but you haven't used 'await' keyword ahead of controller.callLoginService().
Observer(
builder: (_) {
return Center(
child: RaisedButton(
child: Text("TESTE"),
onPressed: () async {
await controller.callLoginService(); //put await for calling asynchronous methods
if (controller.showDialog) {
final action = await InfoDialogView.showAlertDialog(
context, "Try again", 'Invalid user');
if (action == DialogAction.abort) {
controller.showDialog = false;
}
}
},
),
);
},
),

Autoclose dialog in Flutter

I want to autoclose dialog a few seconds after opening. The solution that I found is to call Navigator.of(context).pop(); delayed and it works. But the problem occurs if I closed it manually (by clicking outside) before the execution of the Navigator.pop command. Then Navigator.pop just closes the app and I see just a black screen.
I need a way to destroy this delay on closing the dialog or to find another workaround.
showDialog(
context: context,
builder: (BuildContext builderContext) {
Future.delayed(Duration(seconds: 5), () {
Navigator.of(context).pop();
});
return AlertDialog(
backgroundColor: Colors.red,
title: Text('Title'),
content: SingleChildScrollView(
child: Text('Content'),
),
);
}
);
You can use a Timer to achieve this. You can cancel the timer whenever you want.
Declare a timer property in your class:
Timer _timer;
And change your showDialog code like:
showDialog(
context: context,
builder: (BuildContext builderContext) {
_timer = Timer(Duration(seconds: 5), () {
Navigator.of(context).pop();
});
return AlertDialog(
backgroundColor: Colors.red,
title: Text('Title'),
content: SingleChildScrollView(
child: Text('Content'),
),
);
}
).then((val){
if (_timer.isActive) {
_timer.cancel();
}
});
In this case, you are using the wrong context.
Try to change the context you are using in the "pop"
You have this BuildContext builderContext, use that builderContext like:
Navigator.of(builderContext).pop();
You can use different way of executing pop() request using Timer
_timer = Timer(Duration(seconds: _timerTimeoutInterval), () {
Navigator.of(context).pop();
});
And in case you want to cancel the timer you can call this:
if (_timer != null && _timer.isActive) {
_timer.cancel();
}