I want to display a "Close keyboard" button above the keyboard when it is visible.
I know that the resizeToAvoidBottomInset can impact how the keyboard interact with the rest of the application, however it doesn't do exactly what I want.
I have a background image and others widgets (not shown in the sample below) which should not be resized and not moved when the keyboards is shown. This is an ok behavior when the resizeToAvoidBottomInset
attribute is set to false.
However, I would like to add a button which should appear above the keyboard.
How can I do that? I only want one widget floating above the keyboard, not all the app.
Here is a sample code :
import 'dart:async';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
var home = MyHomePage(title: 'Flutter Demo Home Page');
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: home,
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
title: Text(widget.title),
),
body: _getBody(),
floatingActionButton: FloatingActionButton(
onPressed: () {},
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
Widget _getBody() {
return Stack(children: <Widget>[
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/sample.jpg"), fit: BoxFit.fitWidth)),
// color: Color.fromARGB(50, 200, 50, 20),
child: Column(
children: <Widget>[TextField()],
),
),
Positioned(
bottom: 0,
left: 0,
right: 0,
child: Container(
height: 50,
child: Text("Aboveeeeee"),
decoration: BoxDecoration(color: Colors.pink),
),
),
]);
}
}
Your Positioned
widget has a bottom
of 0, replacing with an appropriate value should do the job.
MediaQuery.of(context).viewInsets.bottom
will give you the value of the height covered by the system UI(in this case the keyboard).
import 'dart:async';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
var home = MyHomePage(title: 'Flutter Demo Home Page');
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: home,
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
title: Text(widget.title),
),
body: _getBody(),
floatingActionButton: FloatingActionButton(
onPressed: () {},
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
Widget _getBody() {
return Stack(children: <Widget>[
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/sample.jpg"), fit: BoxFit.fitWidth)),
// color: Color.fromARGB(50, 200, 50, 20),
child: Column(
children: <Widget>[TextField()],
),
),
Positioned(
bottom: MediaQuery.of(context).viewInsets.bottom,
left: 0,
right: 0,
child: Container(
height: 50,
child: Text("Aboveeeeee"),
decoration: BoxDecoration(color: Colors.pink),
),
),
]);
}
}
A PR was merged that provides platform-synchronized animations for closing/opening the keyboard. See the PR in effect here.
To achieve keyboard-visibility-based animated padding, here are a few modifications over @10101010's great answer:
If you want the bottom
change when keyboard changes visibility to be animated AND you want extra padding under your floating child then:
To listen when keyboard is appearing/disappearing, like so:
bool isKeyboardVisible = false;
@override
void initState() {
super.initState();
KeyboardVisibilityNotification().addNewListener(
onChange: (bool visible) {
isKeyboardVisible = visible;
},
);
}
Optionally you can write your own native plugins, but it's already there you can check the pub's git repo.
AnimatedPostioned
:For fine-tuned animated padding, like so:
Widget _getBody() {
double bottomPadding = 0;
if (isKeyboardVisible) {
// when keyboard is shown, our floating widget is above the keyboard and its accessories by `16`
bottomPadding = MediaQuery.of(context).viewInsets.bottom + 16;
} else {
// when keyboard is hidden, we should have default spacing
bottomPadding = 48; // MediaQuery.of(context).size.height * 0.15;
}
return Stack(children: <Widget>[
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/sample.jpg"), fit: BoxFit.fitWidth)),
// color: Color.fromARGB(50, 200, 50, 20),
child: Column(
children: <Widget>[TextField()],
),
),
AnimatedPositioned(
duration: Duration(milliseconds: 500),
bottom: bottomPadding,
left: 0,
right: 0,
child: Container(
height: 50,
child: Text("Aboveeeeee"),
decoration: BoxDecoration(color: Colors.pink),
),
),
]);
}
For now this is still an known ongoing issue
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With