After clicking the button it should show the web view. I did this. But when press the back button it is closing the app. It does not go back to previous state. If I press back button it should go back to previous page or state. I am getting web view from a function.
Here is my code:
_contentSearch(BuildContext context){
url = "https://www.google.com";
return WebviewScaffold(
url: url,
appBar: AppBar(
title: Text("Google"),
),
withJavascript: true,
withLocalStorage: true,
withZoom: false,
enableAppScheme: true,
)
},
);
}
And I am calling this method like this:
FlatButton(
padding: EdgeInsets.all(0.0),
onPressed: (){
Navigator.pushReplacement(
context,
new MaterialPageRoute(builder: (BuildContext context) => _contentSearch(context)
));
},
child: new Text("Button"),
),
It's not going back. It's always closing the app.
Its because you are using pushReplacement(Replace the current route of the navigator) instead of push
Navigator.push(
context,
MaterialPageRoute(builder: (context) => _contentSearch(context),
);
Related
I'm having a little error I can't seem to figure out, and I believe it's due to my Alert Dialog implementation. I'm using the flutter Provider package, and opening my Dialog like this:
_openSearchHistory(
BuildContext context, TextEditingController searchController) {
final searchModel = Provider.of<SearchModel>(context, listen: false);
showDialog(
context: context,
builder: (_) => ChangeNotifierProvider<SearchModel>.value(
value: searchModel,
child: DialogSearchHistory(
searchHistory: searchModel.searchHistory,
searchController: searchController,
),
));
}
The problem is when on android and the user presses the back button, the Dialog does not close, but the page behind the Dialog pops back a page. I have a close button on the Dialog that successfully closes the dialog, but I want users to be able to use the back button for a better experience. The Dialog does close if the user clicks outside of it as well. I've tried wrapping the Dialog with WillPopScope, but it does not get called on a back button press.
Could anyone shed some light on what I'm doing wrong here?
I have tried wrapping the Widget in the calling method with WillPopScope
showDialog(
context: context,
builder: (_) => ChangeNotifierProvider<SearchModel>.value(
value: searchModel,
child: WillPopScope(
onWillPop: () {
Navigator.of(context).pop();
return Future.value(false);
},
child: DialogSearchHistory(
searchHistory: searchModel.searchHistory,
searchController: searchController,
),
),
));
As well as wrapping the Alert Dialog itself in the build function
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () {
Navigator.of(context).pop();
return Future.value(false);
},
child: AlertDialog(
backgroundColor: kCardColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(20.0)),
),...
Neither have worked. The page behind the Dialog pops back, but the Dialog stays put. onWillPop is never hit by the debugger
Late to the party but setting useRootNavigator to false inside showDialog worked for me.
showDialog(
context: context,
useRootNavigator: false,
builder: (context) {
return AlertDialog();
},
);
If the application has multiple Navigator objects, it may be necessary to call Navigator.of(context, rootNavigator: true).pop(result) to close the dialog rather than just Navigator.pop(context, result).
I hope this will close the alert dialog If you have multiple navigator objects. Give it a try
onWillPop: (){
Navigator.of(context, rootNavigator: true).pop();
return Future.value(false);
},
OR
Try Navigator.pop(context);, this will call internally Navigator.of(context).pop() method.
Official Implementation of Navigator.pop() method.
static void pop<T extends Object>(BuildContext context, [ T result ]) {
Navigator.of(context).pop<T>(result);
}
Doc - https://api.flutter.dev/flutter/widgets/Navigator/pop.html
Hi there i face similar issue and the below method worked for me as Vinoth vino tell wrap your page in WillPopScope widget and try to add pop function there like
body: WillPopScope(
onWillPop: (){
Navigator.of(context).pop();
return Future.value(false);
},
child:...your code
I'm using the flutter package: https://pub.dev/packages/intro_slider and once the intro has already been viewed the first time the user has logged, I don't want the intro to show on subsequent app opens. There is a visual error where the intro briefly appears before switching to the main app on the subsequent opens, so I tried to use FutureBuilder, but I'm quite inexperienced.
Here is where the widget is being built:
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: restore(),
builder: (BuildContext context, snapshot){
return new IntroSlider(
// List slides
slides: this.slides,
// Skip button
renderSkipBtn: this.renderSkipBtn(),
onSkipPress: this.onSkipPress,
highlightColorSkipBtn: Color(0xff000000),
// Next, Done button
onDonePress: this.onDonePress,
renderNextBtn: this.renderNextBtn(),
renderDoneBtn: this.renderDoneBtn(),
highlightColorDoneBtn: Color(0xff000000),
// Dot indicator
colorDot: Colors.white10,
colorActiveDot: Colors.greenAccent,
sizeDot: 8.0,
);
}
);
}
}
Here is my restore function:
Future<String> restore() async {
final SharedPreferences sharedPrefs = await SharedPreferences.getInstance();
setState(() {
yn = (sharedPrefs.getBool('yn') ?? false);
});
if (yn){
Navigator.pushReplacement(context, new MaterialPageRoute(
builder: (context) => SplashScreen()
));
}else{
await sharedPrefs.setBool('yn', true);
}
}
And here's my initState if it matters:
void initState() {
super.initState();
restore();
slides.add(
new Slide(
title: "Hail",
styleTitle:
TextStyle(color: Colors.white, fontSize: 30.0, fontFamily: 'Courier'),
description: "Allow miles wound place the leave had. To sitting subject no improve studied limited",
styleDescription:
TextStyle(color: Colors.white, fontSize: 20.0, fontFamily: 'Mono'),
pathImage: "assets/totoro.png",
backgroundColor: Colors.black,
),
);
}
The yn variable is just to check if it is the user's first time opening the app. Thanks in advance!!
I am trying to run the WebView Sample of Flutter in android emulator which is provided by Android studio itself. Now the problem I am facing is while I am running the sample I am not able to view the web page in WebView itself.
When the app runs for the first time it asks me to open the initialUrl into either into the chrome or web browser see below screenshots.
However, when I run the same sample in my mobile device it works fine and I can see the web page insdie WebView
Code
class _WikipediaExplorerState extends State<WikipediaExplorer> {
Completer<WebViewController> _controller = Completer<WebViewController>();
final Set<String> _favorites = Set<String>();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Wikipedia Explorer'),
// This drop down menu demonstrates that Flutter widgets can be shown over the web view.
actions: <Widget>[
NavigationControls(_controller.future),
Menu(_controller.future, () => _favorites),
],
),
body: WebView(
initialUrl: 'https://en.wikipedia.org/wiki/Kraken',
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
),
floatingActionButton: _bookmarkButton(),
);
}
_bookmarkButton() {
return FutureBuilder<WebViewController>(
future: _controller.future,
builder:
(BuildContext context, AsyncSnapshot<WebViewController> controller) {
if (controller.hasData) {
return FloatingActionButton(
onPressed: () async {
var url = await controller.data.currentUrl();
_favorites.add(url);
Scaffold.of(context).showSnackBar(
SnackBar(content: Text('Saved $url for later reading.')),
);
},
child: Icon(Icons.favorite),
);
}
return Container();
},
);
}
}
I want to pass values from 2nd page to 1st page with navigator.pop and refresh or reload my 1st page with new values in initstate or any other work around?
I am able to get these values in 1st page but not able to refresh or reload the page with new values in initstate where i want to pass new data in API n get response...
any help?
I am redirecting to list page from this...
getBrand(BuildContext context) async {
tempBrand = await Navigator.push(context,
MaterialPageRoute(builder: (context) => BrandList(widget.subCatID)));
selectedBrand = tempBrand.name;
selectedBrandID = tempBrand.id;
}
now here i am passing those values in navigator.pop
Getting value here and passing back to 1st page.
Container(
padding: EdgeInsets.all(10),
child: ListView.separated(
separatorBuilder: (context, index) =>
Divider(color: Color(0xffcccccc)),
itemCount: prodBrands.length,
itemBuilder: (BuildContext context, int index) {
return GestureDetector(
child: InkWell(
onTap: () {
tempProdBrand = ProdBrandListModel.Message(
id: prodBrands[index].id,
name: prodBrands[index].name,
);
Navigator.pop(context, tempProdBrand);
},
child: Container(
child: Text(prodBrands[index].name),
padding: EdgeInsets.all(10.0),
),
),
);
}),
)
Want to use new values here...
submitProduct() {
api
.newbiz(
selectedBrandID,
)
.then((response) {
setState(() {
productID = response.message;
});
});
setState(() {});
}
Simply want to refresh my page from initstate or any other way when i pop back to 1st page with my new values passed in pop function.
to navigate from Page1 to Page2
usually you use Navigator.push()
for example:
// Page1
Navigator.push(context, MaterialPageRoute(builder: (context) => Page2()));
and when you are in Page2 you do some work for example saving some data in shared preference and go back to Page1 and refresh Page1 to get the new data from shared preferences, what you can do is to pop to Page1 using
//Page2
Navigator.pop(context);
this is not gonna be enough to refresh your Page1
so you need to attach a .then in the Page1 Navigator as a callback it will be called when you pop from page2 and that .then should have a set state to trigger a rebuild just call a something inside the set state to cause a rebuild
like this:
//Page1
Navigator.push(context, MaterialPageRoute(builder: (context) => Page2())).then((value) {
setState(() {
// refresh state of Page1
});
});
I would like to be able to use the back button to navigate back to the main page instead of closing the app, I have seen the WillPopScope widget option but that needs to show a dialog, is there a way to pop back using the android back button without a dialog?
You can Use Navigator.canPop() Method to avoid app from Exiting.
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
return Navigator.canPop(context);
},
child: Scaffold(
appBar: AppBar(title: const Text('HomePage')),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.add),
backgroundColor: Colors.red,
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => SecondPage()));
},
),
),
);
}
}
The onWillPop callback needs a Future of bool returned. You just can do
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () {
return Future.value(true); // or return Future.value(false);
},
child: Container()
);
}