diegoveloper / flutter_keyboard_actions Goto Github PK
View Code? Open in Web Editor NEWLicense: MIT License
License: MIT License
Thanks for the plugin from a flutter newbie ;-))
Would it be possible to also add ExtraWidgets ?
Atmo there is only the 'closeWidget'...
For my purpose, I want to add a "Validate" and "Info" widgets in addition to Close...
ie
Prev/Next .. space ... Validate/Info/Close
Im using flutter_driver to test my application.
My test should scroll down and find an element and tap it. But the scroll dosnt work with FormKeyboardActions widget in the tree.
return Scaffold(
key: Key('pageKey'),
appBar: CustomAppBar(
title: "Profile",
showBorder: true,
action: _buildSubmitButton(),
),
body: FormKeyboardActions(
child: _buildContent();
),
);
Future<void> scrollDown(
SerializableFinder area, SerializableFinder element) async {
await driver.scrollUntilVisible(
area,
element,
dyScroll: -300.0,
);
}
Platform selection does not appear to be working, and I cannot see where you are checking which platform was selected.
I was able to fix it by adding _isAvailable to _focusChanged as below
_focusChanged(bool showBar) {
if (showBar && !_isShowing && _isAvailable) {
_insertOverlay();
} else if (!showBar && _isShowing && _isAvailable) {
_removeOverlay();
} else if (showBar && _isShowing && _isAvailable) {
_overlayEntry.markNeedsBuild();
}
WidgetsBinding.instance.addPostFrameCallback((_) {
_updateOffset();
});
}
documenting this request here based on #16 :: provide a way to custom build the action bar
Can't it be used in the showModalBottomSheet??Please help.
I'm hitting an error with version 2.1.1
(upgrading from 1.0.3
):
flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
flutter: The following assertion was thrown while finalizing the widget tree:
flutter: A FocusNode was used after being disposed.
flutter: Once you have called dispose() on a FocusNode, it can no longer be used.
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #0 ChangeNotifier._debugAssertNotDisposed.<anonymous closure> (package:flutter/src/foundation/change_notifier.dart:105:9)
flutter: #1 ChangeNotifier._debugAssertNotDisposed (package:flutter/src/foundation/change_notifier.dart:111:6)
flutter: #2 ChangeNotifier.removeListener (package:flutter/src/foundation/change_notifier.dart:166:12)
flutter: #3 FormKeyboardActionState._dismissListeningFocus.<anonymous closure> (package:keyboard_actions/keyboard_actions.dart:261:38)
flutter: #4 Iterable.forEach (dart:core/iterable.dart:277:30)
flutter: #5 FormKeyboardActionState._dismissListeningFocus (package:keyboard_actions/keyboard_actions.dart:260:17)
flutter: #6 FormKeyboardActionState.clearConfig (package:keyboard_actions/keyboard_actions.dart:166:5)
flutter: #7 FormKeyboardActionState.dispose (package:keyboard_actions/keyboard_actions.dart:342:5)
flutter: #8 StatefulElement.unmount (package:flutter/src/widgets/framework.dart:3916:12)
flutter: #9 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1697:13)
flutter: #10 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #11 ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3770:14)
flutter: #12 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #13 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #14 ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3770:14)
flutter: #15 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #16 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #17 MultiChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:4965:16)
flutter: #18 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #19 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #20 ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3770:14)
flutter: #21 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #22 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #23 ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3770:14)
flutter: #24 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #25 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #26 ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3770:14)
flutter: #27 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #28 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #29 SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:4864:14)
flutter: #30 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #31 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #32 ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3770:14)
flutter: #33 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #34 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #35 SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:4864:14)
flutter: #36 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #37 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #38 ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3770:14)
flutter: #39 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #40 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #41 ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3770:14)
flutter: #42 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #43 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #44 ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3770:14)
flutter: #45 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #46 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #47 ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3770:14)
flutter: #48 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #49 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #50 ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3770:14)
flutter: #51 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #52 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #53 ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3770:14)
flutter: #54 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #55 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #56 SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:4864:14)
flutter: #57 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #58 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #59 ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3770:14)
flutter: #60 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #61 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #62 SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:4864:14)
flutter: #63 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #64 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #65 SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:4864:14)
flutter: #66 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #67 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #68 MultiChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:4965:16)
flutter: #69 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #70 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #71 ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3770:14)
flutter: #72 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #73 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #74 SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:4864:14)
flutter: #75 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #76 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #77 ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3770:14)
flutter: #78 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #79 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #80 SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:4864:14)
flutter: #81 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #82 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #83 ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3770:14)
flutter: #84 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #85 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #86 SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:4864:14)
flutter: #87 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #88 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #89 ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3770:14)
flutter: #90 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #91 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #92 ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3770:14)
flutter: #93 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #94 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #95 ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3770:14)
flutter: #96 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #97 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #98 SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:4864:14)
flutter: #99 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #100 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #101 ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3770:14)
flutter: #102 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #103 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #104 SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:4864:14)
flutter: #105 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #106 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #107 ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3770:14)
flutter: #108 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #109 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #110 ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3770:14)
flutter: #111 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #112 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #113 SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:4864:14)
flutter: #114 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #115 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #116 ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3770:14)
flutter: #117 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #118 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #119 ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3770:14)
flutter: #120 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #121 _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1695:7)
flutter: #122 ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3770:14)
flutter: #123 _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1693:13)
flutter: #124 ListIterable.forEach (dart:_internal/iterable.dart:39:13)
flutter: #125 _InactiveElements._unmountAll (package:flutter/src/widgets/framework.dart:1706:25)
flutter: #126 BuildOwner.finalizeTree.<anonymous closure> (package:flutter/src/widgets/framework.dart:2364:27)
flutter: #127 BuildOwner.lockState (package:flutter/src/widgets/framework.dart:2196:15)
flutter: #128 BuildOwner.finalizeTree (package:flutter/src/widgets/framework.dart:2363:7)
flutter: #129 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:702:18)
flutter: #130 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:286:5)
flutter: #131 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1012:15)
flutter: #132 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:952:9)
flutter: #133 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:864:5)
flutter: #137 _invoke (dart:ui/hooks.dart:219:10)
flutter: #138 _drawFrame (dart:ui/hooks.dart:178:3)
flutter: (elided 3 frames from package dart:async)
My code follows the example pretty closely. I'm running into it when I navigate to a page with keyboard actions, pop navigation, and then again navigate to the keyboard actions route again.
This basic flutter app reproduces the issue (Github):
The problem is that line 259 is trying to remove listeners from focus nodes that were previously disposed of.
The first page looks like this:
import 'package:flutter/material.dart';
import 'form_page.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(primarySwatch: Colors.blue),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatelessWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) => FormPage(isEditing: false),
),
);
},
child: Icon(Icons.add),
),
);
}
}
and the form page is this:
import 'package:flutter/material.dart';
import 'package:keyboard_actions/keyboard_actions.dart';
class FormPage extends StatelessWidget {
final bool isEditing;
FormPage({
Key key,
@required this.isEditing,
}) : super(key: key ?? Key(isEditing ? 'editing' : 'creating'));
static final _scaffoldKey = GlobalKey<ScaffoldState>();
static final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.clear),
onPressed: () => Navigator.of(context).pop(),
),
title: Text(isEditing ? "Edit Herd Record" : "New Herd Record"),
),
body: FormKeyboardActions(
child: _FormContent(
isEditing: isEditing,
formKey: _formKey,
scaffoldKey: _scaffoldKey,
),
),
);
}
}
class _FormContent extends StatefulWidget {
final bool isEditing;
final GlobalKey<ScaffoldState> scaffoldKey;
final GlobalKey<FormState> formKey;
_FormContent({
Key key,
@required this.isEditing,
@required this.formKey,
@required this.scaffoldKey,
});
@override _FormContentState createState() => _FormContentState(
nameTextEditingController: TextEditingController(text: null),
);
}
class _FormContentState extends State<_FormContent> {
final FocusNode focusNodeName = FocusNode();
final TextEditingController nameTextEditingController;
_FormContentState({
@required this.nameTextEditingController,
});
GlobalKey<FormState> get _formKey => widget.formKey;
GlobalKey<ScaffoldState> get _scaffoldKey => widget.scaffoldKey;
String _name;
@override
void initState() {
_name = '';
// Configure keyboard actions
FormKeyboardActions.setKeyboardActions(context, _buildConfig(context));
super.initState();
}
KeyboardActionsConfig _buildConfig(BuildContext context) {
return KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.ALL,
actions: [
KeyboardAction(focusNode: focusNodeName),
]
);
}
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.only(left: 16, right: 16),
child: Form(
key: _formKey,
child: SingleChildScrollView(
child: Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center,
children: [
SafeArea(bottom: false,
child: Align(alignment: Alignment.center,
child: Container(constraints: BoxConstraints(maxWidth: 600),
child: Column(
children: <Widget>[
const SizedBox(height: 16),
_nameField(), const SizedBox(height: 24),
],
)
)
),
)
],
)
),
),
);
}
Widget _nameField() {
return TextFormField(
focusNode: focusNodeName,
initialValue: _name,
decoration: const InputDecoration(labelText: 'Name'),
);
}
@override
void dispose() {
focusNodeName.dispose();
nameTextEditingController.dispose();
super.dispose();
}
}
should I not be calling dispose
on the focusNode?
The iOS api allows to add multiple arbitrary keyboard actions (e.g. Save or Go and Cancel), but flutter_keyboard_actions is restricting it to only one action per field, so I don't see a way to have both cancel and save actions, especially for a numeric-only keyboard on the phone.
Please extend api to allow multiple actions, e.g. introduce another constructor in KeyboardAction
that would accept list of focusNodes
and have child
instead of closeWidget
.
I got this error.
My widget tree is
ModalProgressHUD
@override
void initState() {
FormKeyboardActions.setKeyboardActions(context, _buildConfig(context));
super.initState();
referenceController.addListener(() => onChange(referenceController));
}
$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, v1.5.4-hotfix.2, on Mac OS X 10.14.4 18E226)
[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
[✓] iOS toolchain - develop for iOS devices (Xcode 10.2.1)
[✓] Android Studio (version 3.3)
[✓] VS Code (version 1.33.1)
[✓] Connected device (1 available)
• No issues found!
flutter: Another exception was thrown: 'package:flutter/src/rendering/box.dart': Failed assertion: line 2193 pos 12: 'child.parent == this': is not true.
Flutter 1.7.8+hotfix.4 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 20e59316b8 (9 days ago) • 2019-07-18 20:04:33 -0700
Engine • revision fee001c93f
Tools • Dart 2.4.0
If I add a Column
with TextField
s into SingleChildScrollView
, TextField
s are not scrolled automatically into view. Using ListView
fixes the issue, but it cannot be used due to flutter/flutter#11500.
Another workaround is to replace SingleChildScrollView
directly with its child (Column
in my case), but this would require extra logic especially if you are planning to use this plugin only with iOS and not with Android.
So as an improvement, shouldn't the related logic starting from here
check if the child is already aSingleChildScrollView
? Now it will wrap an existing SingleChildScrollView
with another SingleChildScrollView
. I guess this causes the issue.Hey, so my most recent project has been to add a custom keyboard :) Thought I would open an issue to track if we wanted to support it here. I've been working on a change to allow a KeyboardAction to specify a custom overlay widget.
The widget would be shown below below the keyboard action bar. My use case is to implement a custom keyboard, for inputs that don't use the system keyboard, e.g. a color input:
It could also be used along with the system keyboard for things like providing some instructions, an error message, or input suggestions.
Sample form structure:
1. TextField
2. TextField
3. TextField
4. DropdownButtonFormField
5. DropdownButtonFormField
6. DropdownButtonFormField
7. TextField
8. TextField
9. TextField
In the TextField
3, I would like to disable Down-button (or preferably it should work like a Close-button) to prevent jumping directly to TextField
7 (user should go through the DropDownButtonFormField
s first).
All or any of the following new features would help:
KeyboardAction
KeyboardAction
KeyboardAction
so that it closes the keyboard instead of navigating Up/Downuse like this:
class KeyboardTest extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _KeyboardTestState();
}
}
class _KeyboardTestState extends State<KeyboardTest> {
final FocusNode _nodeText1 = FocusNode();
KeyboardActionsConfig _buildConfig(BuildContext context) {
return KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.ALL,
keyboardBarColor: Colors.grey[200],
nextFocus: true,
actions: [
KeyboardAction(
focusNode: _nodeText1,
),
],
);
}
@override
void initState() {
// Configure keyboard actions
FormKeyboardActions.setKeyboardActions(context, _buildConfig(context));
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
title: Text("Keyboard Actions Sample"),
),
body: IconTheme(
data: IconTheme.of(context).copyWith(color: Colors.black),
child: FormKeyboardActions(
child: Center(
child: Padding(
padding: EdgeInsets.all(15),
child: Column(
children: <Widget>[
TextField(
keyboardType: TextInputType.number,
focusNode: _nodeText1,
decoration: InputDecoration(
hintText: "Input Number",
),
),
],
),
),
),
),
),
);
}
}
open this page:
Navigator.of(context).push(
MaterialPageRoute(builder: (_) => KeyboardTest()),
);
error:
The following assertion was thrown building Builder:
Context does not contain a FormKeyboardActions ancestor: see Scaffold.of for reference.
why use like this?
because my project has many page like this,now i want add your lib to my code.
please help
Hi,
I try to use FormKeyboardActions
with a ListView
inside like in this example:
class StockInventoriesNewPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: SafeArea(
child: FormKeyboardActions(
child: Form(
child: _buildListView()
),
),
),
);
}
Widget _buildListView() {
return ListView(
children: [
Text("1"),
Text("2"),
Text("3"),
],
);
}
}
I have an error:
════════ Exception caught by rendering library ═════════════════════════════════
The following assertion was thrown during performResize():
Vertical viewport was given unbounded height.
Viewports expand in the scrolling direction to fill their container.In this case, a vertical viewport was given an unlimited amount of vertical space in which to expand. This situation typically happens when a scrollable widget is nested inside another scrollable widget.
If this widget is always nested in a scrollable widget there is no need to use a viewport because there will always be enough vertical space for the children. In this case, consider using a Column instead. Otherwise, consider using the "shrinkWrap" property (or a ShrinkWrappingViewport) to size the height of the viewport to the sum of the heights of its children.
User-created ancestor of the error-causing widget was
ListView
lib/…/new/new.dart:35
When the exception was thrown, this was the stack
#0 RenderViewport.performResize.<anonymous closure>
package:flutter/…/rendering/viewport.dart:1165
#1 RenderViewport.performResize
package:flutter/…/rendering/viewport.dart:1218
#2 RenderObject.layout
package:flutter/…/rendering/object.dart:1686
#3 RenderProxyBoxMixin.performLayout
package:flutter/…/rendering/proxy_box.dart:105
#4 RenderObject.layout
package:flutter/…/rendering/object.dart:1701
...
The following RenderObject was being processed when the exception was fired: RenderViewport#c7fe8 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
RenderObject: RenderViewport#c7fe8 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
needs compositing
parentData: <none> (can use size)
constraints: BoxConstraints(w=414.0, 762.0<=h<=Infinity)
size: MISSING
axisDirection: down
crossAxisDirection: right
offset: ScrollPositionWithSingleContext#6726f(offset: 0.0, range: null..null, viewport: null, ScrollableState, AlwaysScrollableScrollPhysics -> BouncingScrollPhysics, IdleScrollActivity#d7e2b, ScrollDirection.idle)
anchor: 0.0
center child: RenderSliverPadding#931d8 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
parentData: paintOffset=Offset(0.0, 0.0)
constraints: MISSING
geometry: null
padding: EdgeInsets.zero
textDirection: ltr
child: RenderSliverList#02f24 NEEDS-LAYOUT NEEDS-PAINT
parentData: paintOffset=Offset(0.0, 0.0)
constraints: MISSING
geometry: null
no children current live
It works without FormKeyboardActions
class StockInventoriesNewPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: SafeArea(
child: Form(child: _buildListView()),
),
);
}
Widget _buildListView() {
return ListView(
children: [
Text("1"),
Text("2"),
Text("3"),
],
);
}
}
If I used the ListView
directly as a child (which is not what I need in my project) I have another error maybe more explicit:
════════ Exception caught by widgets library ═══════════════════════════════════
'package:keyboard_actions/external/bottom_area_avoider.dart': Failed assertion: line 49 pos 16: 'child is ScrollView ? child.controller != null : true': is not true.
User-created ancestor of the error-causing widget was
SafeArea
lib/…/new/new.dart:26
════════════════════════════════════════════════════════════════════════════════
Hi,
When the input is in editing and keyboard is showing, if I click Back button and going back to the previous page, I got this exception. Could you help to check it?
flutter: When the exception was thrown, this was the stack:
flutter: #0 State.setState.<anonymous closure> (package:flutter/src/widgets/framework.dart:1090:9)
flutter: #1 State.setState (package:flutter/src/widgets/framework.dart:1116:6)
flutter: #2 FormKeyboardActionState._updateOffset (package:keyboard_actions/keyboard_actions.dart:304:7)
flutter: #3 FormKeyboardActionState._focusChanged.<anonymous closure> (package:keyboard_actions/keyboard_actions.dart:242:7)
flutter: #4 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1012:15)
flutter: #5 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:960:9)
flutter: #6 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:864:5)
flutter: #10 _invoke (dart:ui/hooks.dart:219:10)
flutter: #11 _drawFrame (dart:ui/hooks.dart:178:3)
flutter: (elided 3 frames from package dart:async)
I try to implement this: https://pub.dev/packages/keyboard_actions
But I get this error:
I/flutter (30378): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════ I/flutter (30378): The following assertion was thrown during performLayout(): I/flutter (30378): BoxConstraints forces an infinite height. I/flutter (30378): These invalid constraints were provided to RenderPadding's layout() function by the following I/flutter (30378): function, which probably computed the invalid constraints in question: I/flutter (30378): RenderConstrainedBox.performLayout (package:flutter/src/rendering/proxy_box.dart:259:13) I/flutter (30378): The offending constraints were: I/flutter (30378): BoxConstraints(w=360.0, h=Infinity) I/flutter (30378): I/flutter (30378): When the exception was thrown, this was the stack: I/flutter (30378): #0 BoxConstraints.debugAssertIsValid.<anonymous closure>.throwError (package:flutter/src/rendering/box.dart:507:9) I/flutter (30378): #1 BoxConstraints.debugAssertIsValid.<anonymous closure> (package:flutter/src/rendering/box.dart:550:21) I/flutter (30378): #2 BoxConstraints.debugAssertIsValid (package:flutter/src/rendering/box.dart:554:6)
It occurs when I give FormKeyboardActions() a child, the child is:
Padding -> Row[Expanded->Theme->TextFormField]
The FormKeyboardActions() is a child of Dismissible, Dismissible is a child of SizeTransition, which is a child of Column
Hey @diegoveloper
I have tweaked your sample.dart to illustrate the issue.
I'm getting BoxConstraints forces an infinite height
.
If you remove the Column
, everything works as expected.
If I wrap FormKeyboardActions
in Container
with the fixed height it also works.
My question is - is it possible to make it work without setting the fixed height?
Thanks!
import 'package:flutter/material.dart';
import 'package:keyboard_actions/keyboard_actions.dart';
//https://github.com/hackiftekhar/IQKeyboardManager
class Sample extends StatelessWidget {
final _focusNodeQuantity = FocusNode();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("KeyboardActions"),
),
body: Column(
children: <Widget>[
FormKeyboardActions(
config: KeyboardActionsConfig(actions: [
KeyboardAction(
focusNode: _focusNodeQuantity,
),
]),
child: TextField(
focusNode: _focusNodeQuantity,
keyboardType: TextInputType.multiline,
maxLines: null,
),
),
],
),
);
}
}
I got this error when I added the keyboard actions setup (based from Readme)
When I removed FormKeyboardActions everything worked no more error. Any ideas?
Scaffold(
child: FormKeyboardActions(
child: Form()
)
)
Flutter doctor
$ flutter doctor -v
[✓] Flutter (Channel stable, v1.5.4-hotfix.2, on Mac OS X 10.14.5 18F132, locale en-PH)
• Flutter version 1.5.4-hotfix.2 at /Users/jongbanaag/Documents/Files/flutter
• Framework revision 7a4c33425d (5 weeks ago), 2019-04-29 11:05:24 -0700
• Engine revision 52c7a1e849
• Dart version 2.3.0 (build 2.3.0-dev.0.5 a1668566e5)
[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
• Android SDK at /Users/jongbanaag/Library/Android/sdk
• Android NDK location not configured (optional; useful for native profiling support)
• Platform android-28, build-tools 28.0.3
• Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)
• All Android licenses accepted.
[✓] iOS toolchain - develop for iOS devices (Xcode 10.2.1)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Xcode 10.2.1, Build version 10E1001
• ios-deploy 1.9.4
• CocoaPods version 1.6.1
[✓] Android Studio (version 3.4)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin version 35.3.1
• Dart plugin version 183.6270
• Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)
[✓] VS Code (version 1.34.0)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.0.2
[✓] Connected device (1 available)
• iPhone Xs • 5E0528FE-478A-423E-AA2B-478469E20552 • ios • com.apple.CoreSimulator.SimRuntime.iOS-12-2 (simulator)
• No issues found!
First i click the textField then i tap the prefixIcon to call showModalBottomSheet
, the actions bar has not hide ..
See this video _(•̀ω•́
https://www.youtube.com/watch?v=Phcsx1eB30Q&feature=youtu.be
The up/down arrows could be disabled when there's no next or previous focusNode to go to.
@diegoveloper I'll send a PR if this sounds good! I'm planning on using this lib in production so will be getting lots of little improvements hopefully.
Hello, As the title says, I'm trying to open up the keyboard with custom actions that will ask the user to enter some info and then will be saved in the database,
The problem is that I want the keyboard to be shown when the user presses a Fab - or a button ,
In the example I found that keyboard will be shown if a user presses a TextField.
is there any way to open up the keyboard with custom actions using a button? any hint will be great so I can achieve it.
this is an example to the thing I'm trying to explain
Thank you for this amazing Lib.
I tried to upgrade to 3.1.2 from 2.1.2 but I need the equivalent of the old FormKeyboardActions.setKeyboardActions() as my logic for building the keyboard actions and my adding of the KeyboardActions widget are in different places. If there is a new way to achieve this with 3.1.2, can you please describe this in example code as I couldn't find a way to do this. Thanks.
I have a few issues using the keyboard actions. I have created a simple startup project that extends from your main sample - my app is much more complex and has a deep nesting of scrollable widgets but I have tried to abstract that functionality away by creating a small app that shows the issue. Hopefully I am missing something very basic.
Note
If autoscroll is turned off then for the simple use case below, keyboard actions functions - however - within our own live app which has many scrollable widgets nested deeply - we need to enable autoscroll on a per case basis.
Additionally - you will see that we have code such as :
showBody() {
List<Widget> list = [];
// Run with keyboard actions causes issues (Uncomment)
list.add(
FormKeyboardActions(
child: TextField2(),
),
);
Which adds one or more widgets encased within a FormKeyboardActions - in our app, the user can create as many TextField widgets as they desire - each textfield are multilined and can contain any number of lines. Scrolling between these textFields is important.
Here is the app running without using Keyboard Actions
From the gif above, we can see that the on screen keyboard allows newline entries and that we have a multiline textfield. Everything works perfectly except there is no close button (Hence the desire to use keyboard Action)
We are wrapping a TextField in a custom widget :
TextField2 (Which uses KeyboardAction)
TextField3 (which doesnt use KeyboardAction)
Build method showing how these widgets are used
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(title: Text('keyboardActions')),
body: showBody());
}
showBody() {
List<Widget> list = [];
// Run with keyboard actions causes issues (Uncomment)
// list.add(
// FormKeyboardActions(
// child: TextField2(
// ),
// ),
// );
// Run without keyboard actions shows the text field
list.add(
TextField3(),
);
return Column(
children: list,
);
}
Running the app with keyboard Actions causes exception
Source
Two small simple files :
Main.dart
import 'package:example/textfield2.dart';
import 'package:flutter/material.dart';
import 'package:keyboard_actions/keyboard_actions.dart';
// Application entry-point
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
_openWidget(BuildContext context, Widget widget) =>
Navigator.of(context).push(
MaterialPageRoute(builder: (_) => widget),
);
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('Test'),
),
backgroundColor: Colors.amber,
body: _myBody(context)),
);
}
_myBody(BuildContext context) {
return Builder(
builder: (context) => Center(
child: Padding(
padding: const EdgeInsets.all(18.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
RaisedButton(
child: Text("Full Screen form"),
onPressed: () => _openWidget(
context,
ScaffoldTest(),
),
),
SizedBox(
height: 25,
),
],
),
),
),
);
}
}
class ScaffoldTest extends StatefulWidget {
@override
_ScaffoldTestState createState() => _ScaffoldTestState();
}
class _ScaffoldTestState extends State<ScaffoldTest> {
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(title: Text('keyboardActions')),
body: showBody());
}
showBody() {
List<Widget> list = [];
// Run with keyboard actions causes issues (Uncomment)
// list.add(
// FormKeyboardActions(
// child: TextField2(),
// ),
// );
// Run without keyboard actions shows the text field
list.add(
TextField3(),
);
return Column(
children: list,
);
}
}
TextField2
import 'package:flutter/material.dart';
import 'package:keyboard_actions/keyboard_actions.dart';
class TextField2 extends StatefulWidget {
bool callInit;
TextField2();
@override
_TextField2State createState() => _TextField2State();
}
class _TextField2State extends State<TextField2> {
final FocusNode _nodeText1 = FocusNode();
KeyboardActionsConfig _buildConfig(BuildContext context) {
return KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.ALL,
keyboardBarColor: Colors.grey[200],
nextFocus: false,
actions: [
KeyboardAction(
focusNode: _nodeText1,
closeWidget: Padding(
padding: EdgeInsets.all(8.0),
child: Icon(Icons.close),
),
),
],
);
}
@override
void initState() {
FormKeyboardActions.setKeyboardActions(context, _buildConfig(context));
super.initState();
}
@override
Widget build(BuildContext context) {
return Center(
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Container(
color: Colors.lightGreen.withOpacity(.4),
child: Column(children: <Widget>[
TextField(
maxLines: null,
keyboardType: TextInputType.multiline,
textInputAction: TextInputAction.newline,
focusNode: _nodeText1,
decoration: InputDecoration(
hintText: "Text with custom close",
),
),
]))),
);
}
}
class TextField3 extends StatefulWidget {
TextField3();
@override
_TextField3State createState() => _TextField3State();
}
class _TextField3State extends State<TextField3> {
final FocusNode _nodeText2 = FocusNode();
@override
Widget build(BuildContext context) {
return Center(
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Container(
color: Colors.lightGreen.withOpacity(.4),
child: Column(children: <Widget>[
TextField(
maxLines: null,
keyboardType: TextInputType.multiline,
textInputAction: TextInputAction.newline,
focusNode: _nodeText2,
decoration: InputDecoration(
hintText: "Text with custom close",
),
),
]))),
);
}
}
When wanting to display just a footer, the top bar always renders, even if you've disabled both Next and CloseButton's.
Hi @diegoveloper,
Thanks for writing this great package!
The only problem I've experienced is when the keyboard is displayed and:
The problem occurs in the example app and the apps that I've used the package in.
It seems like the package is not able to detect the keyboard being hidden in this situation.
I'm hoping it's simple for you to reproduce.
I've tried it on a few different versions of Android. My set up is fairly standard:
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel beta, v1.0.0, on Mac OS X 10.14 18A391, locale en-AU)
[✓] Android toolchain - develop for Android devices (Android SDK 28.0.3)
[✓] iOS toolchain - develop for iOS devices (Xcode 10.1)
[✓] Android Studio (version 3.2)
[✓] Connected device (2 available)
Thanks
Looks like this can be a pure dart package with no native code needed.
These can be removed
https://github.com/diegoveloper/flutter_keyboard_actions/blob/master/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java
https://github.com/diegoveloper/flutter_keyboard_actions/blob/master/ios/Runner/GeneratedPluginRegistrant.h
https://github.com/diegoveloper/flutter_keyboard_actions/blob/master/ios/Runner/GeneratedPluginRegistrant.m
This is the way the API worked before adding FormKeyboardActions.setKeyboardActions
. It would be nice to pass an initial configuration in during widget construction for easier usage.
Would be nice to be able to disable the Done (Go, Next, etc) button as part of some form validation.
tried to use this inside a child widget where my input is at, the button is not showing up in the right position I guess it is because my child widget doesn't have a full-screen height.
Can you add a way to use this inside a child widget instead of the scaffold body?
Does not support CupertinoPageScaffold?
I have a situation where one of my TextFields can be disabled some times.
The problem I have is that the focus keep being put in that field when the user navigates with keyboard actions.
The image below shows that behavior.
Focus was in the Nome
field and CPF
field was disabled. When I navigate through the arrows, the focus is put inside CPF
.
App Structure:
Home
| -> Register Page
| -> Login Page
Replicate the Error:
To replicate this error, you will need to create a home page and the home screen will link to register screen and setup the FormKeyboardActions just like the example, when clicking back button from the Register Screen to navigate back to Home Screen, the following error occur.
Code that cause the error:
void dispose() {
_nodeText1.dispose();
_nodeText2.dispose();
_nodeText3.dispose();
_nodeText4.dispose();
super.dispose();
}
Error:
flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
flutter: The following assertion was thrown while finalizing the widget tree:
flutter: A FocusNode was used after being disposed.
flutter: Once you have called dispose() on a FocusNode, it can no longer be used.
Note: From what i understand, we should be disposing the FocusNode at dispose(), and this cause the error to show up, please correct me if i am wrong.
Assuming you have code that displays the same Widget (say 'x' times and can be triggered by a user tapping a + icon) - running this code below will add the three text fields but only the last one will have a close button and not three which is the intended action :
This code will add 3 textfields and clicking the + will add further text fields :
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(actions: <Widget>[
IconButton(
icon: Icon(Icons.add),
onPressed: () => _add(),
)
], title: Text('keyboardActions')),
body: FormKeyboardActions(child: showBody()));
}
showBody() {
// Initially 3 textfields that call _buildConfig(...)
list.add(
TextField2(),
);
list.add(
TextField2(),
);
list.add(
TextField2(),
);
return ValueListenableBuilder(
valueListenable: _addNotifier,
builder: (BuildContext context, int value, Widget child) {
return Column(
children: list,
);
},
);
}
_add() {
list.add(
TextField2(),
);
_addNotifier.value += 1;
}
Only the last TextField has the close button
Please add support for web and macos platforms
════════ Exception caught by services library ══════════════════════════════════════════════════════
The following NoSuchMethodError was thrown during a platform message callback:
The getter 'footerBuilder' was called on null.
Receiver: null
Tried calling: footerBuilder
When the exception was thrown, this was the stack:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
#1 KeyboardActionstate._focusChanged (package:keyboard_actions/keyboard_actions.dart:219:26)
#2 KeyboardActionstate.didChangeAppLifecycleState (package:keyboard_actions/keyboard_actions.dart:373:9)
#3 WidgetsBinding.handleAppLifecycleStateChanged (package:flutter/src/widgets/binding.dart:536:16)
#4 SchedulerBinding._handleLifecycleMessage (package:flutter/src/scheduler/binding.dart:285:5)
...
════════════════════════════════════════════════════════════════════════════════════════════════════
error when Navigator.pop(context)
════════ Exception Caught By scheduler library ═════════════════════════════════
The following assertion was thrown during a scheduler callback:
Looking up a deactivated widget's ancestor is unsafe.
At this point the state of the widget's element tree is no longer stable.
To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling inheritFromWidgetOfExactType() in the widget's didChangeDependencies() method.
It'd be great if the toolbar can just slide up with the keyboard just like a standard iOS UIToolbar does.
I want to change button color and change size or colors options
Hi,
I'm getting the below exception every time the keyboard changes from number only to text. I'm using the text fields in a list view which is a child of KeyboardActions and KeyboardActionsConfig.
Please help.
════════ Exception caught by scheduler library
The following NoSuchMethodError was thrown during a scheduler callback:
The getter 'position' was called on null.
Receiver: null
Tried calling: position
When the exception was thrown, this was the stack:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
#1 scrollToObject (package:keyboard_actions/external/bottom_area_avoider.dart:189:33)
#2 BottomAreaAvoiderState._paddingAnimationStatusChanged. (package:keyboard_actions/external/bottom_area_avoider.dart:153:7)
#3 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1102:15)
#4 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1049:9)
...
Hello, I faced with the following problem after adding your keyboard: when I open the keyboard text in TextField scrolls up and isn't shown until I close the keyboard. Here are the screenshots:
Before opening of the keyboard:
After opening:
Text in textfield didn't disappear but it only scrolled up that it's not visible now, unfortunately I can't show it. So, here's the way how I implemented keyboard to my widget:
class InputGoalWidget extends StatefulWidget {
final bool isValid = true;
final String title;
final String hint;
final TextInputType tit;
final String emoji;
final TextEditingController controller;
InputGoalWidget({this.title, this.hint, this.emoji, this.controller, this.tit});
@override
_InputGoalWidgetState createState() => _InputGoalWidgetState();
}
class _InputGoalWidgetState extends State<InputGoalWidget> with SingleTickerProviderStateMixin {
AnimationController animationController;
Animation<double> animation;
FocusNode _node = FocusNode();
KeyboardActionsConfig _buildConfig(BuildContext context) {
return KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.ALL,
keyboardBarColor: Colors.white,
nextFocus: false,
actions: [
KeyboardAction(
focusNode: _node,
displayCloseWidget: true,
),
],
);
}
@override
void initState() {
super.initState();
animationController = AnimationController(
vsync: this,
duration: Duration(milliseconds: 600),
)..addListener(() => setState(() {}));
animation = Tween<double>(
begin: 50.0,
end: 120.0,
).animate(CurvedAnimation(
parent: animationController,
curve: Interval(0.8, 1.0, curve: Curves.fastOutSlowIn),
));
animationController.forward();
}
@override
Widget build(BuildContext context) {
return buildContainer(context);
}
Container buildContainer(BuildContext context) {
return Container(
margin: EdgeInsets.only(top: 3),
color: Color(AppColors.white),
child: Padding(
padding: const EdgeInsets.only(top: 15, bottom: 10),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 20.0, right: 16),
child: Text(
widget.emoji,
textAlign: TextAlign.justify,
style: TextStyle(fontSize: 32),
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(widget.title, style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
Container(
height: MediaQuery.of(context).size.height * 0.06,
width: MediaQuery.of(context).size.width * 0.7,
child: Center(
child: Padding(
padding: const EdgeInsets.only(bottom: 0),
child: FormKeyboardActions(
config: _buildConfig(context),
child: TextField(
textCapitalization: TextCapitalization.sentences,
focusNode: _node,
style: TextStyle(
fontSize: 18,
color: Color(AppColors.brandViolet),
fontWeight: FontWeight.w500,
),
keyboardType: widget.tit,
inputFormatters: widget.tit == TextInputType.number ? [WhitelistingTextInputFormatter.digitsOnly] : null,
decoration: InputDecoration(
hintText: widget.hint,
border: InputBorder.none,
),
controller: widget.controller,
),
),
),
),
)
],
)
],
),
),
);
}
}
And here's the way how this widgets are used in the screen:
Flexible(
flex: 1,
child: ListView(
children: <Widget>[
_nameWidget,
_calorieWidget,
_stepsWidget,
_waterWidget,
],
),
),
So. _nameWidget
, _calorieWidget
, _stepsWidget
and _waterWidget
are InputGoalWidgets. Why such issue can happen? Thanks in advance for any help!
Hello,
First of all, thanks for this Widget 👍
I'd like to align the close widget on the left as it is getting collapsed by the floating button. (is it possible to have a closeWidgetAlignment ? If the closeWidget is in a Container, you can bind the closeWidgetAlignment to the Row mainAxisAlignment, isn't it ?
Also, the panel shouldn't inherit of any margin or padding in my humble opinion. It would make it more easy because right now, if your root widget has a margin, it will be applied to the panel. (see screenshot below).
Ask me if you need further information.
I was obliged to remove the margin/padding and move them to the content of the FormKeyboardActions widget.
Final result (I faced an issue where tapping on the close, then focus again the TextField, which open the keyboard again : then tapping the close widget only close the KeyboardAction panel but not the keyboard : second screenshot)
In your example:
https://github.com/diegoveloper/flutter_keyboard_actions/tree/master/example
all textfields pushed up when keyboard opened. How to prevent this?
I want keyboard show over fields.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.