mod: 视频评论输入框:可随键盘高度与文本行数移动和缩起;实现失去焦点功能;添加滚动条

This commit is contained in:
orz12
2024-01-20 13:51:17 +08:00
parent 53ce81673b
commit ca6091b90d

View File

@ -34,8 +34,6 @@ class _VideoReplyNewDialogState extends State<VideoReplyNewDialog>
final TextEditingController _replyContentController = TextEditingController(); final TextEditingController _replyContentController = TextEditingController();
final FocusNode replyContentFocusNode = FocusNode(); final FocusNode replyContentFocusNode = FocusNode();
final GlobalKey _formKey = GlobalKey<FormState>(); final GlobalKey _formKey = GlobalKey<FormState>();
double _keyboardHeight = 0.0; // 键盘高度
final _debouncer = Debouncer(milliseconds: 100); // 设置延迟时间
bool ableClean = false; bool ableClean = false;
Timer? timer; Timer? timer;
Box localCache = GStrorage.localCache; Box localCache = GStrorage.localCache;
@ -90,24 +88,6 @@ class _VideoReplyNewDialogState extends State<VideoReplyNewDialog>
} }
} }
@override
void didChangeMetrics() {
super.didChangeMetrics();
WidgetsBinding.instance.addPostFrameCallback((_) {
// 键盘高度
final viewInsets = EdgeInsets.fromViewPadding(
View.of(context).viewInsets, View.of(context).devicePixelRatio);
_debouncer.run(() {
if (mounted) {
setState(() {
_keyboardHeight =
_keyboardHeight == 0.0 ? viewInsets.bottom : _keyboardHeight;
});
}
});
});
}
@override @override
void dispose() { void dispose() {
WidgetsBinding.instance.removeObserver(this); WidgetsBinding.instance.removeObserver(this);
@ -117,8 +97,10 @@ class _VideoReplyNewDialogState extends State<VideoReplyNewDialog>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
double keyboardHeight = EdgeInsets.fromViewPadding(
View.of(context).viewInsets, View.of(context).devicePixelRatio)
.bottom;
return Container( return Container(
height: 500,
clipBehavior: Clip.hardEdge, clipBehavior: Clip.hardEdge,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: const BorderRadius.only( borderRadius: const BorderRadius.only(
@ -130,8 +112,11 @@ class _VideoReplyNewDialogState extends State<VideoReplyNewDialog>
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Expanded( ConstrainedBox(
child: Container( constraints: const BoxConstraints(
maxHeight: 200,
),
child: SingleChildScrollView(
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
top: 6, right: 15, left: 15, bottom: 10), top: 6, right: 15, left: 15, bottom: 10),
child: Form( child: Form(
@ -152,8 +137,7 @@ class _VideoReplyNewDialogState extends State<VideoReplyNewDialog>
style: Theme.of(context).textTheme.bodyLarge, style: Theme.of(context).textTheme.bodyLarge,
), ),
), ),
), )),
),
Divider( Divider(
height: 1, height: 1,
color: Theme.of(context).dividerColor.withOpacity(0.1), color: Theme.of(context).dividerColor.withOpacity(0.1),
@ -169,10 +153,17 @@ class _VideoReplyNewDialogState extends State<VideoReplyNewDialog>
height: 36, height: 36,
child: IconButton( child: IconButton(
onPressed: () { onPressed: () {
if (keyboardHeight > 0) {
FocusScope.of(context).unfocus();
} else {
FocusScope.of(context) FocusScope.of(context)
.requestFocus(replyContentFocusNode); .requestFocus(replyContentFocusNode);
}
}, },
icon: Icon(Icons.keyboard, icon: Icon(
keyboardHeight > 0
? Icons.keyboard_hide
: Icons.keyboard,
size: 22, size: 22,
color: Theme.of(context).colorScheme.onBackground), color: Theme.of(context).colorScheme.onBackground),
highlightColor: highlightColor:
@ -181,7 +172,12 @@ class _VideoReplyNewDialogState extends State<VideoReplyNewDialog>
padding: MaterialStateProperty.all(EdgeInsets.zero), padding: MaterialStateProperty.all(EdgeInsets.zero),
backgroundColor: backgroundColor:
MaterialStateProperty.resolveWith((states) { MaterialStateProperty.resolveWith((states) {
// 如果按钮被按下,返回高亮颜色
if (states.contains(MaterialState.pressed)) {
return Theme.of(context).highlightColor; return Theme.of(context).highlightColor;
}
// 默认状态下,返回透明颜色
return Colors.transparent;
}), }),
)), )),
), ),
@ -196,7 +192,7 @@ class _VideoReplyNewDialogState extends State<VideoReplyNewDialog>
duration: const Duration(milliseconds: 300), duration: const Duration(milliseconds: 300),
child: SizedBox( child: SizedBox(
width: double.infinity, width: double.infinity,
height: _keyboardHeight, height: keyboardHeight,
), ),
), ),
], ],