Flutter 鍵盤事件監聽

前言

學習 MDC Flutter 教程 的時候有一個登陸頁面,一時好奇在 Flutter 中鍵盤彈出事件怎麼監聽,通過半天折騰終於找到一個比較完善的解決方案.ide

點擊前往輪子學習

解決方案分析(只是分析邏輯,詳細代碼請參考輪子)

首先我找到了一個方法, WidgetsBindingObserver.didChangeMetrics動畫

該方法可以獲取到屏幕的改變(彈出鍵盤,旋轉屏幕),在鍵盤彈出的一瞬間就會回調該方法,因而在輸入框得到焦點的狀況下我經過 ScrollController 將 ListView 滑動到最底部.ui

WidgetsBindingObserver

@override
void didChangeMetrics() {
    super.didChangeMetrics();
    if ((_usernameFocusNode.hasFocus || _passwordFocusNode.hasFocus) &&
        MediaQuery
            .of(context)
            .viewInsets
            .bottom > 50) {
      setState(() {
        _scrollController.animateTo(
          context.size.height - _listKey.currentContext.size.height,
          duration: Duration(
            milliseconds: 300,
          ),
          curve: Curves.decelerate,
        );
      });
    }
}
複製代碼

發現沒有效果,由於spa

Any active animation is canceled. If the user is currently scrolling, that action is canceled.code

也就是說在鍵盤彈出動畫完成前咱們不能調用 ScrollController.animateToserver

無動畫解決方案

@override
void didChangeMetrics() {
    super.didChangeMetrics();
    if ((_usernameFocusNode.hasFocus || _passwordFocusNode.hasFocus) &&
        MediaQuery
            .of(context)
            .viewInsets
            .bottom > 50) {
      setState(() {
        _scrollController.jumpTo(context.size.height - _listKey.currentContext.size.height);
      });
    }
}
複製代碼

有動畫解決方案

WidgetsBinding.addPersistentFrameCallback 這個方法可以完美得到每一幀繪製完成的回調,那麼咱們在該回調下判斷上一幀 viewInsets.bottom 的值是否和當前幀的 viewInsets.bottom 相同,若是相同表明鍵盤動畫完成教程

@override
void didChangeMetrics() {
    _didChangeMetrics = true;
    super.didChangeMetrics();
}

_widgetsBinding.addPersistentFrameCallback((Duration timeStamp) {
    
  if (!_didChangeMetrics) {
    return;
  }

  _preBottomInset = _bottomInset;
  _bottomInset = MediaQuery.of(context).viewInsets.bottom;

  if (_preBottomInset != _bottomInset) {
    WidgetsBinding.instance.scheduleFrame();
    return;
  }

  _didChangeMetrics = false;
  bottomInsertComplete();
});
複製代碼

在 bottomInsertComplete 就是鍵盤徹底彈出收回的回調,這時候咱們能夠經過判斷 viewInsets.bottom 的值來判斷鍵盤的狀態.事件

相關文章
相關標籤/搜索