頁面中有輸入框呻澜,鍵盤彈起,頁面溢出
可以使用 SingleChildScrollView 包裹布局
這里還需要了解一個 Scaffold 中的一個屬性 resizeToAvoidBottomInset
/// If true the [body] and the scaffold's floating widgets should size
/// themselves to avoid the onscreen keyboard whose height is defined by the
/// ambient [MediaQuery]'s [MediaQueryData.viewInsets]bottom
property.
///
/// For example, if there is an onscreen keyboard displayed above the
/// scaffold, the body can be resized to avoid overlapping the keyboard, which
/// prevents widgets inside the body from being obscured by the keyboard.
///
/// Defaults to true.
官方文檔給出的解釋就是處理鍵盤遮擋問題,默認是 true亚皂,如果不希望頂起需要設置為 false这橙。
在 sdk 低版本的時候是使用 resizeToAvoidBottomPadding 需要將其設置為 false,現(xiàn)在已經(jīng)棄用扭粱。但網(wǎng)上很多文章還沒有改正,仍然用的 resizeToAvoidBottomPadding震檩。
鍵盤彈起的情況下琢蛤,返回前先收起鍵盤
分兩種情況
一種是使用系統(tǒng)的返回鍵蜓堕,比如 android 底部導航自帶的返回,
另一種是使用導航欄自定義的返回鍵
第一種情況需要在頁面根布局使用 WillPopScope 在 onWillPop 中攔截返回處理博其。
原理都是通過判斷輸入框是否獲取了焦點
onWillPop: () {
if (_focusNode.hasFocus) {
FocusScope.of(context).unfocus();
} else {
return Future.value(true);
}
},
編輯頁面底部有懸浮按鈕套才,鍵盤彈起的時候,要頂上去慕淡,保證按鈕不被鍵盤遮擋
當?shù)撞坑泄潭ǖ慕M件背伴,比如提交按鈕,我們在鍵盤彈起的時候希望按鈕貼著鍵盤頂部固定峰髓,但是中間滾動視圖可以自由滾動
可以在 SingleChildScrollView 外部再使用 Stack 包裹傻寂,懸浮按鈕使用 Positioned 定位,
還要??注意要給滾動組件底部留出距離防遮擋携兵,同時還有動態(tài)加上 bottomBar 的高度疾掰,因為在 iphoneX 以上的手機,會有個虛擬按鍵徐紧,如果不加上該按鍵高度静檬,同樣會被遮擋
高度獲取方法:MediaQuery.of(context).padding.bottom
dialog彈窗中有輸入框,彈起鍵盤布局溢出
在 showDialog 布局中使用 Scaffold 包裹并级,不要忘了將 backgroundColor 設為透明拂檩。
如果彈窗過高,還是需要將高度固定嘲碧,然后使用 SingleChildScrollView 广恢,彈窗中同樣也可以在執(zhí)行關閉的時候攔截,判斷鍵盤是否彈起呀潭,如果彈起則要先關閉鍵盤钉迷。
showDialog(
context: context,
builder: (c) {
return Scaffold(
backgroundColor: Colors.transparent,
body: Container(
height: BaseTheme.getScreenHeight() * 0.4,
padding: EdgeInsets.only(left: 8.w, right: 8.w),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
],
),
),
),
);
});
鍵盤焦點完成切換,切換到最后一個后钠署,關閉
給所有輸入框綁定 FoucusNode
在 maxLines=1 的情況下糠聪,輸入框不支持換行,換行按鈕會變成 done
監(jiān)聽 onEditingComplete 方法
onEditingComplete: () {
if (code.isEmpty) {
//如果還有其它未填寫的輸入框谐鼎,則切換焦點過去
FocusScope.of(context).requestFocus(_focusNode);
return;
}
//收起鍵盤
FocusScope.of(context).unfocus();
},
點擊輸入框以外的區(qū)域收起鍵盤
根布局使用 GestureDetector 或者 InkWell 包裹舰蟆,點擊的時候收起鍵盤。
監(jiān)聽軟鍵盤是否彈出
- 可以用第三方插件比如
https://pub.dev/packages/flutter_keyboard_visibility
大概使用用法是使用組件包裹狸棍,通過回調(diào)監(jiān)聽身害,然后根據(jù)狀態(tài)自己處理 - _focusNode.hasFocus
這個方法在前面有提過,也是最簡單的辦法草戈,局限性就是需要動作去觸發(fā)檢測塌鸯。此方法適用于在點擊返回按鈕的時候
onTap: () {
if (_focusNode.hasFocus || _focusNodeNote.hasFocus) {
FocusScope.of(context).unfocus();
return;
}
Navigator.pop(context);
}
- 使用 WidgetsBinding 添加監(jiān)聽
首先頁面要 with WidgetsBindingObserver
然后 在 initState() 實例化監(jiān)聽
WidgetsBinding.instance.addObserver(this);
實現(xiàn) didChangeMetrics() 方法
void didChangeMetrics() {
super.didChangeMetrics();
WidgetsBinding.instance.addPostFrameCallback((_) {
if(MediaQuery.of(context).viewInsets.bottom==0){
LogUtils.v("關閉鍵盤");
}else{
LogUtils.v("顯示鍵盤");
}
});
}
最后要記得銷毀
@override
void dispose() {
// TODO: implement dispose
//銷毀
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}