1、创建键盘单例工具类
2、监听底部viewInsets.bottom,并给工具类赋值
3、使用底部弹出框样式,先调出键盘,在展示弹出框。
import 'dart:math';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:my_pets_app/components/input_kayboard.dart';
import 'package:my_pets_app/utils/keyboard_utils.dart';
class TestKeyboardPage extends StatefulWidget {
const TestKeyboardPage({Key? key}) : super(key: key);
@override
_TestKeyboardPageState createState() => _TestKeyboardPageState();
}
class _TestKeyboardPageState extends State
with WidgetsBindingObserver {
var fn = new FocusNode();
bool isCloseForUp = false;
double keyboardHeight = 0.0;
bool isKeyboardShow = false;
@override
void initState() {
// TODO: implement initState
super.initState();
fn.addListener(() {});
WidgetsBinding.instance.addObserver(this);
}
@override
void didChangeMetrics() {
// TODO: implement didChangeMetrics
super.didChangeMetrics();
final bottom = MediaQueryData.fromWindow(window).viewInsets.bottom;
print("===> ${bottom}");
// 键盘存在中间态,回调是键盘冒出来的高度
keyboardHeight = max(keyboardHeight, bottom);
if (bottom == 0) {
isKeyboardShow = false;
print("==> 键盘关闭");
KeyboardUtils.getInstance().setKeyboardHeight(0);
} else if (bottom == keyboardHeight || keyboardHeight == 0) {
isKeyboardShow = true;
print("==> 键盘打开");
} else {
isKeyboardShow = false;
print("==> 键盘关闭");
KeyboardUtils.getInstance().setKeyboardHeight(0);
}
print(keyboardHeight);
KeyboardUtils.getInstance().setKeyboardHeight(keyboardHeight);
Future.delayed(Duration(microseconds: 1000),
() => KeyboardUtils.getInstance().setIsOpen(isKeyboardShow));
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
WidgetsBinding.instance.removeObserver(this);
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: Container(
padding: EdgeInsets.all(10),
height: double.infinity,
width: double.infinity,
child: Stack(
children: [
Positioned.fill(child: Container(color: Colors.red)),
Positioned(
bottom: 0,
child: Container(
height: 40,
width: MediaQuery.of(context).size.width,
//color: Colors.green,
child: GestureDetector(
child: TextField(
enabled: false,
focusNode: fn,
decoration:
InputDecoration(filled: true, fillColor: Colors.pink),
),
onTap: () {
showDi(context);
},
),
),
)
],
),
),
);
}
}
import 'dart:ui';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:my_pets_app/model/emoji_model.dart';
import 'package:my_pets_app/utils/keyboard_utils.dart';
import 'package:my_pets_app/utils/rpx.dart';
import 'package:my_pets_app/utils/view_utils.dart';
showDi(BuildContext context) {
SystemChannels.textInput.invokeMethod('TextInput.show');
Future.delayed(Duration(microseconds: 1000), () {
final TextEditingController tc = TextEditingController();
final FocusNode fn = FocusNode();
tc.addListener(() {});
fn.addListener(() {
});
tc.selection = TextSelection.fromPosition(TextPosition(
affinity: TextAffinity.downstream, offset: tc.text.length));
var p = EdgeInsets.only(top: 10, bottom: 10, left: 15, right: 15);
return showModalBottomSheet(
context: context,
builder: (context) {
return MediaQuery.removePadding(
context: context,
child: Stack(
children: [
Container(
height: KeyboardUtils.getInstance().getKeyboardHeight() +100,
color: Colors.white,
// alignment: Alignment.,
child: Container(
child: Column(
children: [
Container(
height: 40,
padding:
EdgeInsets.only(top: 10, left: 10, right: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
getEmojiList(tc)[85],
getEmojiList(tc)[86],
getEmojiList(tc)[87],
getEmojiList(tc)[88],
getEmojiList(tc)[89],
getEmojiList(tc)[90],
getEmojiList(tc)[91],
],
),
),
Row(
children: [
Expanded(
child: Container(
height: 60,
padding: EdgeInsets.all(10),
child: TextField(
enabled: true,
focusNode: fn,
autofocus: true,
//cursorWidth: 0,
//cursorHeight: 0,
controller: tc,
cursorColor: primaryColor,
keyboardType: TextInputType.multiline,
onChanged: (str) {
},
style: TextStyle(fontSize: rpx(13)),
decoration: InputDecoration(
contentPadding:
const EdgeInsets.symmetric(
vertical: 4.0, horizontal: 10),
hintText: '说点什么',
hintStyle: TextStyle(
color:
Color.fromARGB(104, 63, 63, 63),
fontSize: rpx(13)),
border: OutlineInputBorder(
borderRadius:
BorderRadius.circular(15),
borderSide: BorderSide.none),
filled: true,
fillColor: Colors.grey[200],
suffixIcon: GestureDetector(
child: KeyboardUtils.getInstance()
.getIsOpen()
? Icon(
Icons.emoji_emotions_outlined,
color: Color.fromARGB(
104, 63, 63, 63),
)
: Icon(
CupertinoIcons.equal_circle,
color: Color.fromARGB(
104, 63, 63, 63),
),
onTap: () {
var isShowEmojiPanel =
KeyboardUtils.getInstance()
.getIsShowEmojiPanel();
KeyboardUtils.getInstance()
.setIsShowEmojiPanel(
!isShowEmojiPanel);
if (!isShowEmojiPanel) {
fn.requestFocus();
} else {
FocusScope.of(context).unfocus();
}
KeyboardUtils.getInstance()
.setIsOpen(!isShowEmojiPanel);
},
)),
),
),
),
GestureDetector(
child: Container(
width: ScreenUtil().setWidth(60),
height: ScreenUtil().setHeight(40),
alignment: Alignment.center,
margin: EdgeInsets.only(left: 10, right: 10),
padding: EdgeInsets.only(left: 10, right: 10),
decoration: BoxDecoration(
color: primaryColor,
borderRadius:
BorderRadius.all(Radius.circular(10)),
border: Border.all(color: Colors.white)),
child: Text(
"发送",
style: TextStyle(
color: Colors.white, fontSize: rpx(12)),
),
),
onTap: () {
Navigator.pop(context);
},
)
],
),
Expanded(
child: Stack(
children: [
Positioned.fill(child: Container(
color: Colors.grey[300],
child: SingleChildScrollView(
padding: EdgeInsets.all(0),
child: Column(
children: [
Container(
padding: p,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
getEmojiList(tc)[39],
getEmojiList(tc)[1],
getEmojiList(tc)[2],
getEmojiList(tc)[3],
getEmojiList(tc)[4],
getEmojiList(tc)[5],
getEmojiList(tc)[6],
],
),
),
Container(
padding: p,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
getEmojiList(tc)[7],
getEmojiList(tc)[8],
getEmojiList(tc)[9],
getEmojiList(tc)[10],
getEmojiList(tc)[11],
getEmojiList(tc)[12],
getEmojiList(tc)[13],
],
),
),
Container(
padding: p,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
getEmojiList(tc)[14],
getEmojiList(tc)[15],
getEmojiList(tc)[16],
getEmojiList(tc)[17],
getEmojiList(tc)[18],
getEmojiList(tc)[19],
getEmojiList(tc)[20],
],
),
),
Container(
padding: p,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
getEmojiList(tc)[21],
getEmojiList(tc)[22],
getEmojiList(tc)[23],
getEmojiList(tc)[24],
getEmojiList(tc)[25],
getEmojiList(tc)[26],
getEmojiList(tc)[27],
],
),
),
Container(
padding: p,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
getEmojiList(tc)[28],
getEmojiList(tc)[29],
getEmojiList(tc)[30],
getEmojiList(tc)[31],
getEmojiList(tc)[32],
getEmojiList(tc)[33],
getEmojiList(tc)[34],
],
),
),
Container(
padding: p,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
getEmojiList(tc)[28],
getEmojiList(tc)[29],
getEmojiList(tc)[30],
getEmojiList(tc)[31],
getEmojiList(tc)[32],
getEmojiList(tc)[33],
getEmojiList(tc)[34],
],
),
),
Container(
padding: p,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
getEmojiList(tc)[28],
getEmojiList(tc)[29],
getEmojiList(tc)[30],
getEmojiList(tc)[31],
getEmojiList(tc)[32],
getEmojiList(tc)[33],
getEmojiList(tc)[34],
],
),
),
Container(
padding: p,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
getEmojiList(tc)[28],
getEmojiList(tc)[29],
getEmojiList(tc)[30],
getEmojiList(tc)[31],
getEmojiList(tc)[32],
getEmojiList(tc)[33],
getEmojiList(tc)[34],
],
),
),
Container(
padding: p,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
getEmojiList(tc)[28],
getEmojiList(tc)[29],
getEmojiList(tc)[30],
getEmojiList(tc)[31],
getEmojiList(tc)[32],
getEmojiList(tc)[33],
getEmojiList(tc)[34],
],
),
),
Container(height: 60,)
],
),
),
)),
Positioned(
bottom: 20,right: 20,
child: Container(
height: 40,width: 70,
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(10)),
),
//width: 10,
//color: Colors.redAccent,
child: SvgPicture.asset("assets/svgs/回退.svg",color: primaryColor,),
))
],
))
],
)))
],
));
},
);
});
}
class KeyboardUtils {
KeyboardUtils._();
double keyboardHeight = 0.0;
bool isOpen = true;
bool isInited = false;
bool isShowEmojiPanel = false;
static KeyboardUtils _instance = KeyboardUtils._();
static KeyboardUtils getInstance() {
if (_instance == null) {
_instance = KeyboardUtils._();
}
return _instance;
}
void setKeyboardHeight(double h) {
this.keyboardHeight = h;
}
void printHash() {
print("==> KeyboardUtils printHash #### ${this.hashCode}");
}
double getKeyboardHeight() {
print("==> 键盘高度#### ${this.keyboardHeight}");
return this.keyboardHeight;
}
void setIsOpen(bool b) {
this.isOpen = b;
}
bool getIsOpen() {
print("==> KeyboardUtils getIsOpen #### ${this.isOpen}");
return this.isOpen;
}
void setIsInited(bool b){
this.isInited = b;
}
bool getIsInited(){
return this.isInited;
}
void setIsShowEmojiPanel(bool b){
this.isShowEmojiPanel = b;
}
bool getIsShowEmojiPanel(){
return this.isShowEmojiPanel;
}
}
import 'package:flutter/material.dart';
import 'package:my_pets_app/utils/rpx.dart';
List getEmojiList(TextEditingController tc){
final TextStyle ts = TextStyle(
fontSize: rpx(20)
);
final TextStyle ts_header = TextStyle(
fontSize: rpx(15)
);
List data = [
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("☹️",style: ts,),onTap:() {tc.text+="☹️";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts,),onTap:() {tc.text+="";},),
GestureDetector(child: Text("",style: ts_header,),onTap:() {tc.text+="";},),//85
GestureDetector(child: Text("",style: ts_header,),onTap:() {tc.text+="";},),//86
GestureDetector(child: Text("",style: ts_header,),onTap:() {tc.text+="";},),//87
GestureDetector(child: Text("",style: ts_header,),onTap:() {tc.text+="";},),//88
GestureDetector(child: Text("",style: ts_header,),onTap:() {tc.text+="";},),//89
GestureDetector(child: Text("",style: ts_header,),onTap:() {tc.text+="";},),//90
GestureDetector(child: Text("",style: ts_header,),onTap:() {tc.text+="";},),//91
];
return data;
}