Open sgon00 opened 5 years ago
Is there any solution? It has been over a year, but it is still open...
@sgon00 I have the same problem. Have you made any progress?
I come up with a way to do this. The core idea is Scaffold(resizeToAvoidBottomInset: !showEmojiKeyboard)
and below is a working example:
import 'package:flutter/material.dart';
void main() {
runApp(const App());
}
class App extends StatelessWidget {
const App({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.orange,
),
home: TextInputDemo(),
);
}
}
const kTextFieldPadding = 16.0;
const kIconSize = 28.0;
class TextInputDemo extends StatefulWidget {
@override
State<TextInputDemo> createState() => _TextInputDemoState();
}
class _TextInputDemoState extends State<TextInputDemo> {
final focusNode = FocusNode();
var showEmojiKeyboard = false;
@override
void initState() {
focusNode.addListener(_handleFocusChange);
super.initState();
}
@override
void dispose() {
focusNode.dispose();
super.dispose();
}
void _handleFocusChange() {
print("focus changed ${focusNode.hasFocus}");
if (focusNode.hasFocus) {
setState(() {
showEmojiKeyboard = false;
});
}
}
@override
Widget build(BuildContext context) {
final keyboardHeight = MediaQuery.of(context).viewInsets.bottom;
final bottomPadding = MediaQuery.of(context).padding.bottom;
print("keyboardHeight $keyboardHeight");
print("bottomPadding $bottomPadding");
return GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: Scaffold(
resizeToAvoidBottomInset: !showEmojiKeyboard,
appBar: AppBar(title: const Text('Home')),
backgroundColor: Colors.orange,
body: SafeArea(
child: Column(
children: [
Expanded(
child: Container(
color: Colors.indigo,
child: ListView(
children: List.generate(
30,
(i) => ListTile(
title: Text("#$i"),
),
).toList(),
),
)),
Stack(
children: [
TextField(
// autofocus: true,
focusNode: focusNode,
showCursor: true,
minLines: 1,
maxLines: 6,
keyboardType: TextInputType.multiline,
textAlignVertical: TextAlignVertical.top,
style: const TextStyle(fontSize: 18.0),
decoration: const InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(
vertical: kTextFieldPadding,
horizontal: kIconSize + 2 * kTextFieldPadding),
hintText: 'Enter your text here',
fillColor: Colors.white,
filled: true,
),
),
Positioned(
left: 0,
bottom: 0,
child: Container(
// decoration: BoxDecoration(border: Border.all()),
child: IconButton(
onPressed: () {
print("face pressed!");
setState(() {
showEmojiKeyboard = !showEmojiKeyboard;
});
focusNode.unfocus();
},
// splashRadius: 1.0,
padding: const EdgeInsets.fromLTRB(
kTextFieldPadding, 8, 8, kTextFieldPadding),
// constraints: const BoxConstraints(),
icon: const Icon(
Icons.face_outlined,
size: kIconSize,
),
),
),
),
Positioned(
right: 0,
bottom: 0,
child: Container(
// decoration: BoxDecoration(border: Border.all()),
child: IconButton(
onPressed: () {
print("pressed!");
},
// splashRadius: 1.0,
padding: const EdgeInsets.fromLTRB(
8, 8, kTextFieldPadding, kTextFieldPadding),
// constraints: const BoxConstraints(),
icon: const Icon(
Icons.note_add_outlined,
size: kIconSize,
),
),
),
),
],
),
if (showEmojiKeyboard)
SizedBox(
height: 336 - bottomPadding,
child: Container(
color: Colors.black,
),
)
],
),
)),
);
}
}
+1
This issue is missing a priority label. Please set a priority label when adding the triaged-design
label.
Anyone has solved this issue?
Maybe you can try this package.
Flutter version
Hi, I will try my best to describe the problem. Basically, I want to achieve what many messenger apps do when clicking Emoji icon when keyboard is present. All messenger apps including Facebook messenger, WeChat etc.. are doing the same thing. But I have spent two days to try to do the same in Flutter, but failed.
First, hiding and showing keyboard are easy by the code
SystemChannels.textInput.invokeMethod('TextInput.hide');
andSystemChannels.textInput.invokeMethod('TextInput.show');
When clicking the Emoji button, I want the textfield row position remains unchanged, then hide the keyboard and the keyboard original position should be replaced by the emoji panel. But the current behavior is the keyboard showing and hiding actions will change the UI layout during the animation. This does not happen to all the native apps that I use. Something like the following:
Showing Emoji Panel When Keyboard OnScreen
Original Screen:
After clicking Emoji Icon:
Phase 1 Screen:
ListView and Emoji Panel positions changed because Both Emoji Panel and Keyboard are present at the same time. and NOTE THAT their positions will keep changing during keyboard moving down.
Phase 2 Screen:
ListView and Emoji Panel positions changed because Keyboard is finally gone.
Hiding Emoji Panel and Bring Keyboard Back
Original Screen:
Clicking Emoji Icon (or Keyboard Icon)
Phase 1 Screen:
ListView and TextFieldRow positions changed because emoji panel is gone.
Phase 2 Screen:
ListView and Emoji Panel's positions keeps changing while keyboard is moving up.
What I expect
I expect the ListView and TextFieldRow will not change their positions while the keyboard is moving up or down and emoji shows or hides. And this is what all native apps I used so far do. I tried many codes including playing around Stack, resizeToAvoidBottomPadding property etc.. But nothing works so far.
(Btw, I can get keyboard height with
MediaQuery.of(context).viewInsets.bottom
, so setting the same height to emoji panel as the keyboard is not a problem. and even if the emoji panel has a a little bit different height, the positions change should be around some pixels instead of the current behaviors)Thank you very much for your help.