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<TestKeyboardPage>
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<void>('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<GestureDetector> getEmojiList(TextEditingController tc){
final TextStyle ts = TextStyle(
fontSize: rpx(20)
);
final TextStyle ts_header = TextStyle(
fontSize: rpx(15)
);
List<GestureDetector> 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;
}