Dismissing a Cupertino dialogue action Flutter - ios

While dismissing a presented Cupertino alert dialogue action using the explained method my entire screen gets popped of and the alert dialogue stays on the screen. This is my code.
if (deviceList.isEmpty){
var alert = new CupertinoAlertDialog(
title: new Text("Alert"),
content: new Text("There was an error signing in. Please try again."),
actions: <Widget>[
new CupertinoDialogAction(
child: const Text('Discard'),
isDestructiveAction: true,
onPressed: () { Navigator.pop(context, 'Discard'); }
),
new CupertinoDialogAction(
child: const Text('Cancel'),
isDefaultAction: true,
onPressed: () { Navigator.pop(context, 'Cancel'); }
),
],
);
showDialog(context: context, child: alert);
}
Is there anything wrong in what I am doing? I cant find any other solution to dismiss the alert dialogue. Please help.

In this case, you need to specify the rootNavigator to of() :
Navigator.of(context, rootNavigator: true).pop("Discard");
Check the implementation proposed in the documentation

Related

How to update webview's url on setState flutter?

I need to update webview's url with my setState. How to do that?
The initial url I haved set on constructor have been loaded successfully. But it's not working when I try load the new one through my drawer menu by onTap method.
...
class _MyWebState extends State<MyWeb> {
Completer<WebViewController> _controller = Completer<WebViewController>();
final Set<String> _favorites = Set<String>();
String url;
Widget web;
_MyWebState() {
web = WebView(
initialUrl: 'https://my.flazhost.com',
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('MyWeb'),
actions: <Widget>[
NavigationControls(_controller.future),
Menu(_controller.future, () => _favorites),
],
),
body: web,
drawer: Drawer(
child: ListView(
children: <Widget>[
ListTile(
leading: FlutterLogo(
size: 20,
),
title: Text('Web AlQudwah'),
onTap: () {
setState(() {
web = WebView(
initialUrl: 'https://flazhost.com',
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
);
Navigator.pop(context);
});
},
),
],
),
),
floatingActionButton: _bookmarkButton(),
);
}
}
...
How to update webview's url onTap method? Please help?
I struggled with the flutter webview for a long time, and I'm still not very happy with it...
But the key is the WebController instance that you get from the onWebViewCreated method of the webview. The instance of the initialized WebViewController has a method called loadUrl('your_new_url')
So you can just call following in your onTap handler:
onTap: () {
_controller.loadUrl('your_new_url');
}
When working with WebViews in flutter I experienced problems when using setState, because it will trigger a rebuild of whole page including the webview which gets reinitialized and of course reloads the page...
But that is mostly not the desired result, so if you want to controll the webview (wheater it will be changes to url, going back in browser history or executing javascript) you should handle it over the WebController initialized from the onWebViewCreated method
Here are the most used methods of the WebViewController class:
_controller.currentUrl() // Gets current url from WebView
_controller.loadUrl('your_new_url'); // Loads new url
_controller.evaluateJavascript('your js code as a string') // Execute JS over WebView console
_controller.goBack() // Goes one step back in browser history
_controller.goForward() // Goes one step forwards in browser history
_controller.clearCache() // Clears cache of WebView
It's really confusing and badly documented (espacially for beginners like me), so I hope the flutter team will provide us with more detailed information and tutorials

How to create progress dialog while executing task and after complete task dialog should be dismiss?

How do I add Progressbar?
After click button, I need to display a progress bar while executing the task and after complete task, the dialog should be dismissed and move to next page if successful login.
in Raised Button:
onPressed: () async {
(isOffline)
? showSnackBar(context)
: checkingValidation(usernameController, context, _url);
}
checkingValidation(TextEditingController usernameController, BuildContext context, String _url) async {
if(....){
...
}else{
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HomePage()))
}
You should use Stack and inside that use alert dialog as you want.
Add a flag like bool showProgress, whenever you need a progress alert dialog to be shown or hide just set showProgress=true or showProgress=false respectively in setState to show or hide the alert dialog widget.
or simply use this template I created.
static showProgressDialog(BuildContext context, String title) {
try {
showDialog(
context: context,
barrierDismissible: false,
builder: (context) {
return AlertDialog(
content: Flex(
direction: Axis.horizontal,
children: <Widget>[
CircularProgressIndicator(),
Padding(padding: EdgeInsets.only(left: 15),),
Flexible(
flex: 8,
child: Text(
title,
style: TextStyle(
fontSize: 16, fontWeight: FontWeight.bold),
)),
],
),
);
});
} catch (e) {
print(e.toString());
}
}
when you want to show this just call
AppUtils.showProgressDialog(context, "Please wait");
when you have done task, just call Navigator.pop(context);
You can create a class as AppUtils and place this template in class, so you can reuse this anywhere in your app.

How to exit the app on back button press? [duplicate]

This question already has an answer here:
How To Override the “Back” button in Flutter? [duplicate]
(1 answer)
Closed 4 years ago.
I have an app that needs move from screen 1 to screen two ....now when the user presses the back button..it should show a dialog box...if the user presses yes it has to exit...any help?the upper solutions don't work
It seems like you can use WillPopScope. You also need to pass a callback function which will indicate what will happen on pressing the back button.
In your case, you can add the code to show an AlertDialog which will ask for exit confirmation from the user.
You can simply wrap your Scaffold inside a WillPopScope.
Example:
Widget build(BuildContext context) {
return WillPopScope(
child: /*Your scaffold widget*/
onWillPop: () {
return showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
title: Text("Confirm Exit"),
content: Text("Are you sure you want to exit?"),
actions: <Widget>[
FlatButton(
child: Text("YES"),
onPressed: () {
SystemNavigator.pop();
},
),
FlatButton(
child: Text("NO"),
onPressed: () {
Navigator.of(context).pop();
},
)
],
);
}
);
return Future.value(true);
},

Flutter "showDialog" with Navigator.pop()

I have problem with showDialog, when i press nothing happens but if i use Navigator.pushNamed(context, "/screen1") it works. I can not run Navigator.pop(context), it does not return any errors.
_showDialog(BuildContext context) {
return showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: new Text("Alert Dialog title"),
actions: <Widget>[
new FlatButton(
child: new Text("Back"),
onPressed: () {
//Navigator.pushNamed(context, "/screen1");
Navigator.pop(context);
},
),
],
);
});}
In my build() :
IconButton(
iconSize: 30.0,
onPressed: () => _showDialog(context),
icon: Icon(
Icons.clear,
color: Colors.white,
),
)
had the same issue .having useRootNavigator: false, in showDialog params solved my issue .
Use pop() two times:-
Navigator.of(context).pop();
Navigator.of(context).pop();
Reason: first pop function dismiss the dialog and Second pop function close the screen
The above answer should be accepted for this question, just elaborating the above answer
return showDialog(
context: context,
useRootNavigator: false, //this property needs to be added
builder: (BuildContext context) {....});
Try calling Navigator.of(context).pop(); instead of Navigator.pop(context);
For closing dialogs, you can also use:
Navigator.pop(context, true);
Source: https://docs.flutter.io/flutter/widgets/Navigator/pop.html
For those who have nested/multiple Navigators, you can also use the pop method as shown below (notice the named parameter rootNavigator set to true):
Navigator.of(context, rootNavigator: true).pop();
As suggested by others, I tried setting the useRootNavigator in the showDialog as false but this way the barrierColor wasn't covering the whole screen (it was only covering the screen displayed by Navigator object the dialog was in).
In summary, you can use the way showed above if you have nested navigators and want to achieve having the barrierColor covering the whole screen.

Navigate back and show snack

I am thinking of this pattern for my application, and cannot find a proper way of doing it.
User is in list page, she clicks on an item and goes to edit page. She edits, and hits the save. Now I want the application to
- show spinning wheel, while saving the item
- after save pop the route to go back to list page, AND show a snackbar on the list page.
I don't seem to find a way to pass a parameter to the previous route to tell it about the state, which is to show the snackbar.
For showing progress on click of save button you can use something like this.
Firstly initialize a variable static bool isSaving = false; then in your scaffold use it like this.
child:Stack(
children: <Widget>[
isSaving
? new Container(
child: new CircularProgressIndicator(
value: null,
strokeWidth: 2.0,
),
alignment: Alignment.center,
)
: new Container(
child: new RaisedButton(
onPressed: () {
setState(() {
isSaving = true;
//Other Implementations here
});
},
child: new Text("Save"),
),
),
],
),
When the operation is complete again set state and make variable false.
Now when you get notified that operation has been done use Navigator to go back.
Navigator.pop(context);
For showing snackbar in your previous screen use a Global Key.
GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
Assign this key to your scaffold.
new Scaffold(
key: scaffoldKey,
...
)
As answered here show snackbar just after pop operation like this.
scaffoldKey.currentState
.showSnackBar(new SnackBar(content: new Text("Saved Successfully")));
Or can try a different approach as explained in this sample.
Hope it helps.
You can send data back through pop method. You can do something like that.
In your edit page:
bool saved = item.save();
Navigator.pop(context, saved);
In your list page:
var saved = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => EditRoute(item)),
);
if (saved) {
// Show success snackbar
} else {
// Show error snackbar
}

Resources