Flutter keyboard hide not working on tab clicks - flutter

I have one application of tabbars. one tab have textfield. It shows keyboard. I want to hide keyboard after press ob any other tab. I used below code but its still not working on other tabs.
return new Scaffold(
key: _scaffoldKey,
resizeToAvoidBottomInset: false,
backgroundColor: blackColor,
body: GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
FocusScope.of(context).requestFocus(new FocusNode());
},
child: Stack(children: <Widget>[
_showForm(),
],)
),
);

you can use onTap under TabBar() like this:
TabBar(
onTap: (_) => FocusManager.instance.primaryFocus?.unfocus(),
tabs: [
tab1(),
tab2(),
)
this will make every tab unfocus the keyboard and move to other tab as well

Use FocusScope.of(context).unfocus() when tab change.

when you click to change tab write below line :
FocusScope.of(context).requestFocus(new FocusNode());

Related

Floating action button to be ontop of drawer after opening

I have a floating action button which opens the drawer. I want it to stay in its place when it opens the drawer and just change the icon to close icon with animation. I couldn't find a good solution to do this.
I tried wrapping inside my drawer with scaffold and adding a floating action button there and using hero widgets so make it look like it stays in its place but didn't help at all.
Is there anyway to achieve this?
U can use foldable Sidebar package to achieve this functionalities that's package is available on :
https://pub.dev/packages/foldable_sidebar
And check this piece of code how to use this :
child: Scaffold(
body: FoldableSidebarBuilder(
drawerBackgroundColor: Colors.deepOrange,
drawer: CustomDrawer(closeDrawer: (){
setState(() {
drawerStatus = FDBStatus.FDB_CLOSE; // For Closing the Sidebar
});
},),
screenContents: FirstScreen(), // Your Screen Widget
status: drawerStatus,
),
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.deepOrange,
child: Icon(Icons.menu,color: Colors.white,),
onPressed: () {
// To Open/Close Sidebar
setState(() {
drawerStatus = drawerStatus == FDBStatus.FDB_OPEN ? FDBStatus.FDB_CLOSE : FDBStatus.FDB_OPEN;
});
}),
),
),

How to get Flutter AlertDialog actions to watch for keyboard event (enter key)?

Is there a way to get the "enter" key keyboard event in flutter to default to one of the action buttons on my AlertDialog? Note I'm referring to use of flutter for web where there is a physical keyboard. For example I have this dialog:
Future<void> _confirmDelete(int index) async {
var fp = SessionInfo.of(context).myFloorplans.entries.toList()[index].value;
return showDialog<void>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Confirm Delete?'),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(8.0))),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text("Please confirm deleting ${fp.name}"),
],
),
),
actions: <Widget>[
FlatButton(
child: Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
FlatButton(
child: Text('Delete'),
onPressed: () {
_deleteFloorplan(index);
Navigator.of(context).pop();
},
),
],
);
},
);
}
Is there a way to default the "enter" key on the keyboard to act like they hit delete? Maybe not the safest UI experience yet, but mostly just asking to understand the foundation here.
Thanks,
Justin
The only thing you need to do is wrap your AlertDialog in a RawKeyboardListener.
check this example :
RawKeyboardListener(
// its better to initialize and dispose of the focus node only for this alert dialog
focusNode: FocusNode(),
autofocus: true,
onKey: (v) {
if (v.logicalKey == LogicalKeyboardKey.enter) {
_deleteFloorplan(index);
Navigator.pop(context);
}
},
child: your alert dialog ...
I don't see anything that will cause the keyboard to show in this dialog.
Anyway if you have a TextFormField that will show the keyboard you can do something like this
onFieldSubmitted: (value) {
_deleteFloorplan(index);
Navigator.of(context).pop();
}
onFieldSubmitted gets called whenever the user hits the text Input action button (the "enter" key you mentioned)

Removing keyboard focus on multiple buttons pressed

I'm trying to hide keyboard when tapped everywhere outside of textField. So I wrapped Scaffold with GestureDetector and set onTap with unfocused(). That works well however when a button is pressed then the keyboard is still active
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Scaffold(
appBar: AppBar(
actions: <Widget>[FlatButton(child: Text('Done'), onPressed: () {})],
),
body: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
FlatButton(
child: Text('something'),
onPressed: () {},
),
TextField(),
],
),
),
);
}
Is there any way to remove the focus without adding that unfocused in onTap of all buttons.. Reason is I've got many buttons there and some has even onLogTap set so there would be a lot of duplicate codes
You need to also add code for hide keyboard inside onPressed() method of FlatButton
FlatButton(
child: Text('something'),
onPressed: () {
FocusScope.of(context).unfocus();
},
),
was hoping for some solution where I wouldn't need so many duplicate codes to do one thing.
AFAIK that is not possible because the click event of GestureDetector widget and click event of FlatButton both are different,
You are registering different/separate click event of FlatButton that's why your keyboard is not hiding when you click on FlatButton
Now the reason why your keyboard not hiding when pressed on buttons
Because the click event of your GestureDetector widget if overridden by the click event of your FlatButton
SOLUTION
You can do one thing, create a common method to hide the keyboard, and call that method to from button click
By thinking a little outside of the box I have managed to hide keyboard on all taps by modifying GestureDetector..
Widget build(BuildContext context) {
return GestureDetector(
onPanDown: (pd) {FocusScope.of(context).unfocus();}, //<- replaced
child: Scaffold(
appBar: AppBar(
actions: <Widget>[FlatButton(child: Text('Done'), onPressed: () {})],
),
body: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
FlatButton(
child: Text('something'),
onPressed: () {},
),
TextField(),
],
),
),
);
}
Now the keyboard will hide on taping everywhere outside of the TextField even on Buttons click.. No need to hide it in each button click. Please if you know about better solution then let me know
UPDATE:
This solution will create exception when tap on already focused TextField

Floating Action Button centerDocked, overlapping any screen or dialogue?

I am using animated icons in my FloatingActionButton (FAB) at bottom navigation bar. But FAB overlapping any page or dialogue open from the BottomAppBar, how can I resolve this?
When I open a new page with Navigator.push, Navigator.pushNamed, modalBottomSheet or a dialogue, the fab overlapping them.
Only works when I use pushReplacementNamed to open a new page.
How can I show the modalSheet without the fab on it and a page using just pushNamed?
I use this reference.
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: _buildFab(context, model),
bottomNavigationBar: BottomAppBar(
color: CustomTheme.getThemeData(context).getAccentColor(),
shape: CircularNotchedRectangle(),
notchMargin: 4.0,
child: new Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
icon: Icon(Icons.menu),
onPressed: () => _showModal(),
),
IconButton(
icon: Icon(Icons.home),
onPressed: () => {},
),
],
),
),
This is my FAB
And this happen when a show the modal or any page
Please I need your help..
I don't know what else to do. :-(
If this is happening with the Modal bottom sheet then try to increase the elevation of the bottom sheet. Like this
showModalBottomSheet(context: context, builder: (context) {
return AddressChangeBottomSheet(
title: "Change Area",
showAddress: false,
cityAreaList: list, onAddressChangeSubmit: () {
mainBloc.fetchUpdatedUser();
});
}, elevation: 10.0)

Flutter - popup menu isn't closed after selecting an item

I am experimenting with Flutter and having a problem with PopupMenuButton. After selecting an item in the menu I show a new screen without the menu, and after I navigate back the popup menu is still open - as shown in the following screenshots:
After navigating back from the edit profile screen (2nd screenshot) to the account screen (1st screenshot) the pop up menu is still open. I would like it to be closed. The relevant code where I create the popup menu inside an appbar:
actions: <Widget>[
new PopupMenuButton(
itemBuilder: (BuildContext context) {
return <PopupMenuEntry>[
new AppBarMenuItem("Edit profile", () => Navigator.pushNamed(context, Routes.editProfile)).build(context),
new AppBarMenuItem("Option 1", () => {}).build(context),
new AppBarMenuItem("Option 2", () => {}).build(context),
new AppBarMenuItem("Option 3", () => {}).build(context),
new AppBarMenuItem("Option 4", () => {}).build(context),
];
},
),
],
And the AppBarMenuItem:
new PopupMenuItem(
child: new InkWell(
child: new Text(_label),
onTap: _onTap,
)
How can I make sure that the popup menu gets closed after selecting an item? It looks like if I just use PopupMenuItem in my PopupMenuButton and navigate to the new screen in the onSelected function the menu closes properly. But when I use the onTap function of InkWell it doesn't close anymore.
Just use pop inside your onTap function Navigator.pop(context, "$popupValue");
PopupMenuItem<String>(
value: "Replay Game",
child: ListTile(
leading: Icon(Icons.replay,
color: theme.actionButtonColor),
title: Text("Replay Game"),
onTap: () {
Navigator.pop(context, "Replay Game");
showDialog(
context: context,
builder: (context) {
return AlertDialog(
content: Text("Clear input and replay game?"),
actions: <Widget>[
FlatButton(
onPressed: () => Navigator.pop(context),
child: Text("No"),
textColor: theme.alterDialogActionColor,
),
FlatButton(
onPressed: () {
store.dispatch(ReplayAction(timerBloc, varBloc.fireAnalytics));
Navigator.pop(context);
},
child: Text("Yes"),
textColor: theme.alterDialogActionColor,
),
],
);
});
},
),
)
as stated in the documentation the popup menu should automatically close when user selects an option from the popup menu item.
Using InkWell onTap wont automatically close the popup menu rather directly use the popup menu item to automatically close the popup menu when an item is selected from the popupMenuList
Make sure that the value property of the PopupMenuItem is not null otherwise the onSelected function will not be called when the PopupMenuItem is selected
I had this same issue and here is my solution. Your PopUpMenuButton() is not utilizing the onSelected property. The onSelected property will properly close your PopUpMenuButton. It currently is not because the onTap property of your AppBarMenuItem is taking over that job.
Also, I created a list of PopUpMenuItem, instead of PopUpMenuEntry, not sure if that makes a difference. But for each of my PopUpMenuItem, I also assigned the value property to each, so that the onSelected would communicate to the PopUpMenuButton() which item was tapped.
Something like this:
PopupMenuButton(
onSelected: (selection) {
switch (selection) {
case 1:
... do stuff...
break;
case 2:
... break stuff...
);
break;
}
},
Where case 1, case 2, etc refer to the value property I assigned to the PopUpMenuItem().