当前位置:   article > 正文

Flutter关于软键盘的一些问题_flutter resizetoavoidbottominset

flutter resizetoavoidbottominset

Scaffold类有个resizeToAvoidBottomInset 属性,它的作用是当弹出软键盘的时候,可以自动调节body区域的高度,撑起body的内容,使其底部高度刚好为键盘的高度,这样一来就不至于让键盘覆盖内容。

Scaffold( /// ..... /// 当弹出软键盘的时候,是否自动调节body区域,默认为true resizeToAvoidBottomInset: true, /// .....
) 
  • 1
  • 2

resizeToAvoidBottomInset 默认值为true,自动调节body的高度,设置为false则停止这一行为。当然resizeToAvoidBottomInset 为ture,自动调节高度也是需要条件的:

1、body区域不能为一个滚动区域。

如使用了SingleChildScrollViewListView包裹,它就会失去自动调节的功能,道理很简单,因为一个非固定高度的组件它无法自动计算高度。

2、需要存在TextField组件

一般来说当存在TextField组件,才会出现软键盘,resizeToAvoidBottomInset 才会有作用。

body自动调节高度会存在一些组件重叠问题,引起界面错乱。因为body的高度改变了,如果body中的组件依赖于高度,就会产生畸变。所以为了避免这个问题你可以选择将resizeToAvoidBottomInset 设置为false,只是软键盘遮挡问题仍然存在。当然,还是有解决的方法的:

这个时候你可以通过判断键盘是否弹起,给body的底部增加一个SizedBox高度,就能解决这个问题。但,这里存在三个技术问题:

1、我要怎么判断键盘是否弹起?

继承WidgetsBindingObserver类,重写didChangeMetrics方法,该方法可用于检测页面的变化,软键盘的弹出和收起都会触发应该事件。然后通过判断MediaQuery.of(context).viewInsets.bottom的值来确定键盘是否弹起。当它的值大于0时,说明键盘弹起,反之为收起。

class _KeyboardDemoState extends State<KeyboardDemo>with WidgetsBindingObserver {// 键盘是否打开bool isKeyboardOpen = false;@overridevoid initState() {super.initState();// 注册监听WidgetsBinding.instance?.addObserver(this);}@overridevoid dispose() {super.dispose();// 移除监听WidgetsBinding.instance?.removeObserver(this);}/// 页面尺寸改变时回调@overridedidChangeMetrics() {super.didChangeMetrics();// 在页面重新渲染完成之后,通过MediaQuery.of(context).viewInsets.bottom获取软键盘高度WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {isKeyboardOpen = MediaQuery.of(context).viewInsets.bottom > 0;});}/// .....
} 
  • 1
  • 2
2、我要怎么获取当前键盘的高度?

答案已经在上面说了,MediaQuery.of(context).viewInsets.bottom 就是获取当前软键盘的高度。

3、我要怎么关闭软键盘?

可能有人会说,这是个问题吗,直接点击软键盘上的三角图标不就行了。问出这个问题的人,估计是没有考虑过ios系统。

在iOS中,系统默认的软键盘是没有收起的按钮的。这个时候我们就要想个办法来处理软键盘收起问题。一般来说我们都会在键盘以外的区域增加一个单击事件,然后使用FocusManager.instance.primaryFocus?.unfocus()将键盘关闭。

GestureDetector( /// 点击内容包含透明区域 behavior: HitTestBehavior.opaque, onTap: () { /// 取消当前软键盘焦点并收起 FocusManager.instance.primaryFocus?.unfocus(); }
} 
  • 1
  • 2

那么,单击事件使用什么组件呢?这里还是有些讲究的,可以使用InkWell或者GestureDetectoronTap事件 ,但前者点击时会产生水波纹的效果 ,后者要注意点击区域,默认情况下GestureDetector的onTap单击事件点击区域是不包括透明区域的,需要将behavior属性设为 HitTestBehavior.opaque,包含透明区域,不然你可能在空白区域点半天,也没见键盘收起。当然,我比较推荐使用GestureDetector来处理单击事件。

完整代码:

import 'package:flutter/material.dart';

class KeyboardDemo extends StatefulWidget {final String inquiryCode;const KeyboardDemo({Key? key,required this.inquiryCode,}) : super(key: key);@overrideState<KeyboardDemo> createState() => _KeyboardDemoState();
}

class _KeyboardDemoState extends State<KeyboardDemo>with WidgetsBindingObserver {// 键盘是否打开bool isKeyboardOpen = false;@overridevoid initState() {super.initState();// 注册监听WidgetsBinding.instance?.addObserver(this);}@overridevoid dispose() {super.dispose();// 移除监听WidgetsBinding.instance?.removeObserver(this);}/// 页面尺寸改变时回调@overridedidChangeMetrics() {super.didChangeMetrics();// 在页面重新渲染完成之后,通过MediaQuery.of(context).viewInsets.bottom获取软键盘高度WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {isKeyboardOpen = MediaQuery.of(context).viewInsets.bottom > 0;});}@overrideWidget build(BuildContext context) {return Scaffold(appBar: PreferredSize(preferredSize: const Size.fromHeight(5),child: Container(color: Colors.white,),),/// 当弹出软键盘的时候,是否自动调节body区域,默认为trueresizeToAvoidBottomInset: false,body: GestureDetector(/// 点击内容包含透明区域behavior: HitTestBehavior.opaque,onTap: () {/// 取消当前软键盘焦点并收起FocusManager.instance.primaryFocus?.unfocus();},child: Column(mainAxisAlignment: MainAxisAlignment.spaceBetween,children: [SizedBox(height: 200,child: Container(margin: const EdgeInsets.all(12),padding: const EdgeInsets.all(12),decoration: BoxDecoration(border: Border.all(width: 1.r,color: Colors.black,)),child: const TextField(decoration: InputDecoration(hintText: '请输入内容',border: InputBorder.none,),),),),Container(width: double.infinity,margin: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),child: ElevatedButton(onPressed: () {},child: const Text('确定'),),),],),),);}
} 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

最后

最近找到一个VUE的文档,它将VUE的各个知识点进行了总结,整理成了《Vue 开发必须知道的36个技巧》。内容比较详实,对各个知识点的讲解也十分到位。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/268699
推荐阅读
相关标签
  

闽ICP备14008679号