I have a problem with a BottomNavigationBar. My app has two screens and one of them has a bottom sheet that doesn't hide on disposing of the first screen when I'm tapping on the icon of the second screen. BottomNavigationBar works normally and screens switch, but how to hide the bottom sheet of the first screen when shown the second screen I have no ideas. Could you help me solve that?
Calling:
void _showForm(int id) async {
showBottomSheet(
context: context,
elevation: 5,
builder: (context) => BottomSheetSwitch(_refreshJournals, id));
}
Closing (inside bottom sheet):
Navigator.of(context).pop();
P.S. I couldn't solve that problem, so I change showBottomSheet to showModalBottomSheet like that was in: how to set showModalBottomSheet to full height?
You can try to provide a key to the stateful widget of BottomSheet. And access that key's context just use the Navigator's pop method on tap or change of the screen. It might help you.
You can use it like
Navigator.of(key.currentContext).pop();
Else call the function of your BottomSheet using the key. Like as below
Declare GlobalKey with state in your currentWidget.
GloabalKey<BottomSheetWidgetState> closeKey = GloabalKey();
Declare one function closeBottomSheet in your bottomsheet widget state.
void closeBottomSheet(){ Navigator.of(conext).pop(); }
Call the function using the key.
closeKey.currentState.closeBottomSheet();
And done.
Related
just like the title says, when the showModalBottomSheet appear i want to press some button in the body/screen without closing the showModalBottomSheet i already set
isDismissible: false,
barrierColor: Colors.transparent,
but no button can be press
The short answer to your question is to wrap your bottom sheet with a GestureDetector and to do some processing in there yourself and avoid the touch event to get to the modal sheet. Here is a link to a similar answer on SO.
From what I understand, ModalBottomSheet internally uses BottomSheet and its code, where the actual presentation is done looks like this:
return AnimatedBuilder(
animation: widget.route!.animation!,
child: BottomSheet(
animationController: widget.route!._animationController,
onClosing: () {
if (widget.route!.isCurrent) {
Navigator.pop(context);
}
},
If you look at the onClosing() callback, it simply dismisses the object without checking with any external callbacks so I don't really think you can achieve that with a modal bottom sheet in Flutter without wrapping it inside a GestureDetector
I set two widgets in a Stack(), the one in the back is a sidebar and the one in the front is my main page.
When I click on the menu button from the main page, the main page gets shifted to the right and then the user can see the sidebar.
Now the problem is when the sidebar gets displyed i'm obliged to click exactly on the menu button to go back to the main page.
What i want to do is just to click anywhere in the main page to hide the sidebar.
I mean that i want to set the whole main page as a button when the sidebar is displayed.
You can use InkWell
InkWell(
onTap: (){
/// do something
},
child: Text('data') /// your widget,
),
You can also use GestureDetector
Generally if you want to make anything tappable you can just wrap the widget with GestureDetector
I fixed it by wrapping the main page with InkWell() and I added this to the onTap property"
InkWell(
onTap: isSidebarCollapsed ? () {
setState(() {
isSidebarCollapsed = false;
});
} : null,
child: Container(...)
)
Note that isSidebarCollapsed is the variable that determines if the menu is displayed or not.
Explaination of the code:
If the sidebar is collapsed (is displayed) then the onTap property returns a function where I set the variable isSidebarCollapsed to false (to say that the sidebar is gonna be hidden).
Else it returns null
When I press the device back button, it navigate to the homepage but not to the previous page.
I would like to know how to navigate to the previous page using the the device back button.
Thank you
You might have used Navigator.pushReplacement which destroys the previous page and creates the new page.However if you use Navigator.push pressing the back button will navigate you to the previous screen.
Example:
Container(
child: Center(
child: TextButton(child: Text("Next page"),onPressed: (){
Navigator.push(context, MaterialPageRoute(builder: (context) => Page2(),)); // back button will navigate to previous screen
//Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => Page2(),)); // back button will not navigate to previous page
},),),),
It was a Materialapp widget problem.
I solved the problem by deleting the Materialapp widget that was in one of the pages.
This occurs because the previous navigation was not saved in the route stack.
What you should do is this:
Widget A
Navigator.push(context, WidgetB());
Inside Widget B, press the device button and you will return to widget A.
It is important that in widget A you are not using replacement or another that removes widget A from the stack.
You can use:
Navigator.pop(context);
or
Navigator.pushNamed(context, '/routeName');
I tried passing the parent as this in the pram and then call parent.parentList.clear();
but after doing so the the Navigator is not popping and neither the list is changing.
nyIdeas?
I tried passing an instance of a function from parent to child but but still the same problem the navigator does not pop.
return WillPopScope(
onWillPop: () {
parent.parentList.clear();
Navigator.pop(context);
}, child : code.....
I think you could do this by passing a function down to the child and then calling it before popping. Have a look at my answer here: Flutter - How to change state from inside another widget
Hope it helps!
I am building a wallpaper app and want to implement a feature of switching views, like switching from GridView to ListView on the press of an IconButton in FLutter
would look something like this:
The only way I could think of implementing this feature is by changing the crossAxisCount value in the GridView.count() method by hooking up a counter to the crossAxisCount property and controlling it through a function on click of an IconButton, this works but I have to Hot Reload my application every time the counter is incremented or decremented,
Any Suggestions or fix to this problem is welcomed.
You can simply use ternary operators and setState() to achieve what you want.
First, declare a boolean above your widget build. Then you can use ternary operators to change it from gridview to listview.
bool isGridView=true;
#override
Widget build(BuildContext context) {
Scaffold(
body: isGridView ? GridView.builder():ListView.builder(),
);
}
In your onPressed(), you can call setState():
setState(() {
isGridView=false;
});