how to make showModalBottomSheet background become pressable - flutter

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

Related

Flutter - How to detect if popupmenu has been closed or user tapped out of the menu to close it?

I am showing a popupmenu by calling the showMenu() method inside my custom appbar widget.
I need to be able to detect if user closed the popupmenu in anyway.
I tried using GestureDetector but it only detects taps when the popupmenu is already closed which is not what I need.
body: GestureDetector(
onTap: () => print('Tapped'),
child: MyWidget(),
),
Any ideas on how to solve this problem?
you can look at the PopupMenuButton documentation you will find it has a property called onCancelled you can read about it here
showMenu method returns a value, you should wait for. It returns either null (if menu has been closed in ANYWAY) or any value(if user selected menu button)
final result = await showMenu(...)
// you can detect close event even if user just dismissed menu like this:
if(result==null){...do something}
else{...use result}

Flutter dont close bottomSheet on BottomNavigationBar tap

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.

Flutter: showing one dialog at a time

I am fairly new to state management in Flutter, and I have an application where the user will be interacting with dialogs, and a dialog may have a button to open another dialog which can result in the following:
https://i.stack.imgur.com/VBSzr.png
As shown, multiple issues arise when more than one is opened at once -- most notably the previous dialog is still visible in the background. So when a user opens a new dialog, is there any method where I can hide the dialog behind it, and when the frontmost dialog closes, show the previous one which is hidden? Thanks in advance.
Use Navigator.pop(context); method to close the dialog on your button's onPressed before opening the second dialog.
And then while closing your second dialog you can reopen your previous dialog.
Example:
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text("Hello World"),
content: Text("This is content"),
actions: [
TextButton(
onPressed: () {
Navigator.pop(context); //Close your current dialog
//TODO:open your second dialog
},
child: Text("Open"))
],
);
});
I would first try to re-think the logic for opening multiple dialogs at the same time.
Maybe there is a quick workaround for that, but if you keep adding more and more dialogs, then it would become a mess.
Since showDialog<T> function returns Future<T?>, you could potentially use await and wait until the first dialog is closed and then open the second one and so on:
bool canContinue = await showDialog<bool>(
context: context,
builder: (context) => YourWidget(),
);
Alternatively, you could pop by using Navigator but as said, this will be visible to the user that something weird is going on (pushing and popping dialogs programatically).

How to set a widget as a button in Flutter

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

Long Press on BottomNavigationBarItem

Is there any way to handle long press on the items of BottomNavigationBar in Flutter?
I see "onTap" event handler, but nothing else and I also cannot wrap the Items into GestureDetector.
I can wrap the whole BottomNavigationBar section into the GestureDetector but in this case it's not possible to realize which Item was pressed :-/
Thanks in advance!
After couple of days I finally understood how to realize it: you just need (as almost always) wrap Icon and Text of you bottom navigation bar items into GestureDetector widget and it works :)
The snippet would be:
new BottomNavigationBarItem(
icon: GestureDetector(
onLongPress: (){print("long tap icon");
setState(() {
_resetSct(context, i);
});
},
child: new Image.memory([skiped])), //Icon(Icons.looks_one),//photos[0].icon,
title: GestureDetector(
onLongPress: (){print("long tap title");
setState(() {
//do stuff
});
},
child: Text([skipped]))
With Flutter I recommend you to create your custom Bottom Navigation Bar as it is very easy to do.
Note: There is no way to do what you want using the default BottomNaivgationBarItem.
You need also to add enableFeedback as true and wrap your icon with GestureDetector
BottomNavigationBar(
enableFeedback: true,
This is works for me.