Autoclose dialog in Flutter - 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();
}

Related

How to make a timer when screen is inactice show dialogbox?

i try to make a timer which detect if the screen is not using then it will pop up a dialogbox. The popup working fine after 5sec but how can i make it only popup one times instead of every 5sec will popup a new dialog box?
timer = Timer.periodic(Duration(seconds: 5), (time) {
Navigator.of(context, rootNavigator: true).pop();
print('Something');
showDialog(
context: context,
builder: (BuildContext context) {
Future.delayed(Duration(seconds: 5), () {
Navigator.of(context).pop(true);
});
return Dialog(
child: _imageslideshowProductDetails(),
);
}).then((value){
timer?.cancel();
});});
use
Timer.run(); // it will only run once and will pop after 5 secs

Pass value when dialog closed

I'm trying to create an app in Flutter.
When a particular button is pressed a Dialog shows up. In the dialog, the user can write to TextField. I want to use this text in the previous screen when the dialog is closed with pop().
Is there any way to do it?
try this:
showDialog(
context: context,
builder: (context) => Dialog(),
).then((result){
// use the result here
});
and in dialog pop like this:
Navigator.pop(context, result);
You can await to get data from button. also You can pass data .pop(YourValue)
onPressed: () async {
final data = await showDialog(
context: context,
builder: (context) {
final TextEditingController controller =
TextEditingController(); // this can be outside to get direct text from it
return AlertDialog(
content: TextField(
controller: controller,
),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop(controller.text);
},
child: Text("Close"))
],
);
},
);
if (data != null) {
//your operation
}
print(data);
},

How to stop the loader after 5 seconds

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

How to set the duration of onLongPress

I know onLongPress would trigger after a certain period of time (like 500 ms or so). But what I want to do is to trigger some action when user presses the button for like 3 seconds. Actually I want to set the duration for onLongPress.
ElevatedButton(
onPressed: () => print('ok I\'m just fine'),
onLongPress: () => print('Trigger me when user presses me for like 3 seconds'),
style: ElevatedButton.styleFrom(
primary: Colors.red,
elevation: 4,
),
How I did it:
onLongPress: () {
Timer(Duration(milliseconds: (longPressIncrementDuration > 500) ? longPressIncrementDuration - 500 : 0), //enter function here//);
// I subtract 500 ms from required time limit as longpress on flutter activates after 500ms
},
You can solve your problem this way, use onPanCancel and onPanDown of GestureDetector with timer.
class _MyHomePageState extends State<MyHomePage> {
Timer _timer;
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: GestureDetector(
onPanCancel: () => _timer?.cancel(),
onPanDown: (_) => {
_timer = Timer(Duration(seconds: 3), () { // time duration
// your function here
})
},
),
);
}
}
let me know if it work for you.
I made a package today where you can set the duration on GestureDetector. if you wan you can try it out https://pub.dev/packages/custom_long_tap
GestureDetector(
onTapDown: (_) { //Detect when you click the element
_timer = Timer(
const Duration(seconds: 5),
() {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const ListOrder(),
),
);
},
);
print('tapping');
},
onTapUp: (_) { // Detect and cancel when you lift the click
_timer!.cancel();
print('cancel');
},
child: const Icon(Icons.person_search),
),

How to dismiss AlertDialog after Navigator.push?

I am call Navigator.push() after user press button on AlertDialog. But when user press button AlertDialog remain open and on top of new page.
How to dismiss AlertDialog after user press button?
Future<void> _showMyDialog() async {
return showDialog<void>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: Text('AlertDialog Title'),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text('This is a demo alert dialog.'),
Text('Would you like to approve of this message?'),
],
),
),
actions: <Widget>[
FlatButton(
child: Text('Approve'),
onPressed: () async {
await Navigator.push(
context,
MaterialPageRoute(builder: (context) => Page()),
);
Navigator.of(context).pop();
},
),
],
);
},
);
}
await _showMyDialog();
The comment saying to call pop is probably the easiest way to do this.
Another thing to consider next is if you want them to be able to stay on the same page. Here is a way to do both of these if you get beyond the => NewPage() style of navigation on your app. It's more commonly used for Drawers, of course.
Happy coding!
onTap: () {
newRouteName = "/form_check";
// if the current route is the exact location we're at (first on the stack), mark that
Navigator.popUntil(context, (route) {
if (route.settings.name == newRouteName) {
isNewRouteSameAsCurrent = true;
} else {
isNewRouteSameAsCurrent = false;
}
return true;
});
// if it isn't, go to the new route
if (!isNewRouteSameAsCurrent) {
Navigator.pushNamed(context, newRouteName);
}
// again if it is, just pop the drawer/dialog away
else {
Navigator.pop(context);
}
}