Flutter webview app closes when back button pressed - flutter

I have a simple webview application, when i go some pages and press back button it closes the app. I want to go previous page when back button pressed. But my code give error on
Try correcting the name to the name of an existing method, or defining a method named '_onWillPop'.
onWillPop: () => _onWillPop(context),
return Scaffold(
body: SafeArea(
child: Stack(
children: <Widget>[
WillPopScope(
onWillPop: () => onWillPop(context),
child: WebView(
javascriptMode: JavascriptMode.unrestricted,
initialUrl: 'https://google.com',
navigationDelegate: (NavigationRequest request) {
setState(() {
isLoading = true;
});
return NavigationDecision.navigate;
},
onPageFinished: (String url) {
setState(() {
isLoading = false;
});
},
// onPageFinished: (finish) {
// setState(() {
// var isLoading = false;
// });
// },
),
),
isLoading
? const Center(
child: CircularProgressIndicator(),
)
: Stack(),
],
),
),
);

you Need to create method for onWillPopScope
this is example
Future<bool> initBackButton() async {
Logger().d('back button pressed');
return await showDialog(
context: context,
builder: (context) => ElasticIn(
child: AlertDialog(
title: const Text('Exit App'),
content: const Text('Do you really want to exit ?'),
actions: [
ElevatedButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text('No'),
),
ElevatedButton(
onPressed: () => Navigator.of(context).pop(true),
child: const Text('Yes'),
),
],
),
),
) ??
false;
}
after that call like this
onWillPop: () => initBackButton,

Related

How use alert dialog flutter

I try building alert function, but this error follow return:
Undefined name 'context'.
Try correcting the name to one that is defined, or defining the name.
Future<void> _showAlertDialog() async {
return showDialog<void>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
// <-- SEE HERE
title: const Text('Cancel booking'),
content: SingleChildScrollView(
child: ListBody(
children: const <Widget>[
Text('Are you sure want to cancel booking?'),
],
),
),
actions: <Widget>[
TextButton(
child: const Text('No'),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: const Text('Yes'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
I would like to click on a certain elevatedbutton to open the alert dialog
Try to pass the current BuildContext to your function
Future<void> _showAlertDialog(BuildContext context) async {

How to close severals showDialogs in flutter

How can I to close all the showDialogs in my aplication? in this case _mostrarDialogConfirmacion is the dialog where i request to the user a confirmation to make a query, cargandoDialog is another dialog where i show a loading message while the query is executing, when the query finish, i want to close the two dialogs and only see the _mostrarDialogMensaje dialog
_mostrarDialogConfirmacion(
mensaje,
BuildContext context,
codLink,
motivo,
) {
return showDialog(
context: context,
builder: (context){
return AlertDialog(
title: const Text(
'Informacion',
textAlign: TextAlign.center,
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget> [
Text(mensaje, textAlign: TextAlign.center),
],
),
actions: <Widget> [
TextButton(
onPressed: () async {
Navigator.of(context).pop();
cargandoDialog(context);
List<dynamic> ingresarReclamo1 = await ingresarReclamo
.ingresarReclamo(codLink, titular, motivo);
// ignore: use_build_context_synchronously
Navigator.of(context).pop();
// ignore: use_build_context_synchronously
_mostrarDialogMensaje(
ingresarReclamo1[0].observaciones,
ingresarReclamo1[0].validado,
context,
);
},
child: const Text('Si')
),
TextButton(
onPressed: ()=> Navigator.of(context).pop(),
child: const Text('No')
),
],
);
}
);
}
you will dismiss first dialog and then you can use whenComplete to dismiss the second dialog
showDialog(
.....
).whenComplete(() => Navigator.of(context).pop())
You can return bool while .pop(boolValue) to check the tap button. Also, the showDialog is a future method, you can use await until it finished and then processed to next dialog. Navigator.of(context).pop() will be used to close recent dialog on this case. As for my understanding about the question, try this example code.
_mostrarDialogConfirmacion(mensaje, BuildContext context, codLink, motivo) {
return showDialog(
context: context,
barrierDismissible: false,
builder: (context) {
return AlertDialog(
title: const Text('Informacion', textAlign: TextAlign.center),
content: Column(
mainAxisSize: MainAxisSize.min,
),
actions: <Widget>[
TextButton(
onPressed: () async {
// Navigator.of(context)
// .pop(); //if you like to close previous one before showing the next dialog
final bool isSi = await showDialog(
barrierDismissible: false,
builder: (context) => AlertDialog(
content: Text("Second Dialog"),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop(true);
},
child: const Text('Si')),
TextButton(
onPressed: () =>
Navigator.of(context).pop(false),
child: const Text('No')),
],
),
context: context);
if (mounted && isSi) {
Navigator.of(context).pop();
await showDialog(
builder: (context) => AlertDialog(
content: Text("_mostrarDialogMensaje")),
context: context);
}
},
child: const Text('Si')),
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text('No')),
],
);
});
}

How to add Pull to refresh feature to Flutter Webview without any problem?

How to add Pull to refresh feature to Flutter Webview without any problem?
I've been struggling for 2 days.
Here is the whole code but it doesn't work correctly. Could you please help?
What is the best practice to give refresh feature to webview?
This code I wrote gives an error, the application closes
.....
#override
Widget build(BuildContext context) {
WebViewController? _webviewController;
return SafeArea(
child: Scaffold(
appBar: AppBar(
actions: [],
),
body: RefreshIndicator(
onRefresh: () {
return Future.delayed(Duration(seconds: 1), () {
_webviewController!.reload();
});
},
child: Expanded(
child: SingleChildScrollView(
physics: AlwaysScrollableScrollPhysics(),
scrollDirection: Axis.vertical,
child: Column(
children: [
SizedBox(
height: heights,
child: WebView(
javascriptMode: JavascriptMode.unrestricted,
initialUrl: "https://flutter.dev/",
// WebviewControlleri burada tanimliyoruz
onWebViewCreated: (WebViewController webViewController) {
_webviewController = webViewController;
},
onPageFinished: (content) async {
var _heights = double.parse(await _webviewController!
.evaluateJavascript(
"document.documentElement.scrollHeight"));
heights = _heights;
setState(() {});
},
),
),
],
),
),
),
),
bottomNavigationBar: BottomAppBar(
color: Colors.amber,
child: Row(
children: [
IconButton(
onPressed: () async {
// Geri donecek bir sey varmi kontrol ediyoruz
if (await _webviewController!.canGoBack()) {
// Varsa geri donuyoruz
_webviewController!.goBack();
} else {
// Yoksa ekrana mesaj gosteriyoruz
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("Geri donecek bir sey yok")));
}
},
icon: Icon(
Icons.arrow_left,
size: 50,
),
),
IconButton(
onPressed: () async {
// Ileriye gidecek bir sey varmi kontrol ediyoruz
if (await _webviewController!.canGoForward()) {
// Varsa ileri gidiyoruz
_webviewController!.goForward();
} else {
// Yoksa ekrana mesaj gosteriyoruz
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("Ileri gidecek bir sey yok")));
}
},
icon: Icon(
Icons.arrow_right,
size: 50,
),
)
],
),
),
),
);
}
}

Flutter Webview Back Button Controller

I have a Flutter project with Bottom Navigation Bar. There are 2 tabs in the Bottom Navigation Bar. One page is webview and the other is flutter page. I add these two pages to my home page with include. I want to manage the navigation in the webview when the back button is pressed while the inside webview is on the page.
Home Page Code:
Future<bool> _onBackPressed() {
return (showDialog(
context: context,
builder: (context) => new AlertDialog(
title: new Text('Sure?'),
content:
new Text('???'),
actions: <Widget>[
TextButton(
onPressed: () => Navigator.of(context).pop(false),
child: new Text('No'),
),
TextButton(
onPressed: () => Navigator.of(context).pop(true),
child: new Text('Yes'),
),
],
),
)) ??
false;
}
#override
Widget build(BuildContext context) {
List<Widget> pageList = [
MainHomePage(
text: widget.text,
),
WatchPage()
];
return WillPopScope(
onWillPop: _onBackPressed,
child: Scaffold(
//backgroundColor: Colors.transparent,
body: Container(
child: pageList[_activePage],
),
bottomNavigationBar: CurvedNavigationBar(
animationCurve: Curves.easeInOut,
animationDuration: Duration(milliseconds: 600),
color: Color(0xff1f5269),
backgroundColor: Colors.transparent,
onTap: (index) {
setState(() {
_activePage = index;
});
},
items: <Widget>[
Icon(
Icons.home,
color: Colors.white,
),
Icon(
Icons.tv,
color: Colors.white,
),
],
),
),
);
}
WebView Page:
WebViewController controller;
final Completer<WebViewController> _controller =
Completer<WebViewController>();
Future<void> _onWillPop(BuildContext context) async {
print("onwillpop");
if (await controller.canGoBack()) {
controller.goBack();
return Future.value(true);
} else {
//exit(0);
return Future.value(false);
}
}
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () => _onWillPop(context),
child: Scaffold(
appBar: AppBar(
toolbarHeight: 10,
flexibleSpace: Container(
color: Color(0xff1f5269),
),
),
body: Builder(builder: (BuildContext context) {
return WebView(
initialUrl: widget.text,
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController c) {
_controller.future.then((value) => controller = value);
_controller.complete(c);
},
onProgress: (int progress) {
//print("Webview is loading(progress: $progress&)");
},
onPageStarted: (String url) {
if (url == "https://app.testt.com/Login/Cikis") {
Navigator.of(context, rootNavigator: true).push(
MaterialPageRoute(builder: (context) => new LoginPage()));
}
},
onPageFinished: (String url) {
if (url == "https://app.testt.com/Login" ) {
Navigator.of(context, rootNavigator: true).push(
MaterialPageRoute(builder: (context) => new LoginPage()));
}
},
gestureNavigationEnabled: true,
);
}),
),
);
}

Flutter dialog is not displaying when button is pressed

child: RaisedButton(
color: const Color(0xFF5867DD),
onPressed: (){
updateProfilePic();
},
Widget updateProfilePic(){
return SimpleDialog(
title: const Text('Select any option'),
children: <Widget>[
SimpleDialogOption(
onPressed: () { profileImg = ImagePicker.pickImage(source: ImageSource.gallery)
.whenComplete(() {
setState(() {});
}); },
child: const Text('open gallery'),
),
SimpleDialogOption(
onPressed: () { profileImg = ImagePicker.pickImage(source: ImageSource.camera)
.whenComplete(() {
setState(() {});
}); },
child: const Text('open camera'),
),
],
);
}
I am trying to implement Dialog when the button is pressed.I want to select image from gallery and camera so that i created a dialog to select any option to upload the picture.The issue is when i click the button dialog is not visible.
You need to call showDialog
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text(title),
content: Text(message),
);
});
As mentioned by Figen Güngör You need to call showDialog.
Just want to clarify that it is a Future (function) not a Widget, therefore your code would be like this:
Future updateProfilePic(BuildContext context){
return showDialog(
context: context,
builder : (BuildContext context){
return SimpleDialog(
title: const Text('Select any option'),
children: <Widget>[
SimpleDialogOption(
onPressed: () { profileImg = ImagePicker.pickImage(source: ImageSource.gallery)
.whenComplete(() {
setState(() {});
}); },
child: const Text('open gallery'),
),
SimpleDialogOption(
onPressed: () { profileImg = ImagePicker.pickImage(source: ImageSource.camera)
.whenComplete(() {
setState(() {});
}); },
child: const Text('open camera'),
),
],
);
},
);
}