【问题标题】:Hide FAB when onscreen keyboard appear出现屏幕键盘时隐藏 FAB
【发布时间】:2018-06-28 11:27:40
【问题描述】:

在Flutter中,如何让FAB button在屏幕键盘出现时隐藏?

当屏幕键盘出现时,FAB 按钮会覆盖其他元素。

【问题讨论】:

    标签: material-design flutter floating-action-button


    【解决方案1】:

    您可以通过使用viewInsets 检查键盘可见性并基于它隐藏 fab 来实现它。

    例子:

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(new MaterialApp(
        title: "Example",
        home: new FabHideOnKeyboard(),
      ));
    }
    
    class FabHideOnKeyboard extends StatefulWidget {
      @override
      _FabHideOnKeyboardState createState() => new _FabHideOnKeyboardState();
    }
    
    class _FabHideOnKeyboardState extends State<FabHideOnKeyboard> {
      @override
      Widget build(BuildContext context) {
        final bool showFab = MediaQuery.of(context).viewInsets.bottom==0.0;
        return Scaffold(
          resizeToAvoidBottomPadding: true,
          body:Container(
            alignment: Alignment.center,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text("TextField:"),
                TextField()
              ],
            ),
          ),
          floatingActionButton: showFab?Icon(Icons.add):null,
        );
      }
    }
    

    【讨论】:

    • 不是MediaQuery.of(context) 会在每次该值更改时触发重建,然后它会再次触发重建...最终进入循环?
    • 这会导致小部件重建。
    【解决方案2】:

    为了将来参考,这是一个遵循 https://github.com/flutter/flutter/issues/26100 基本思想的实现,但使用现有的 mixin 来减少怪癖和代码:

    class FixedCenterDockedFabLocation extends StandardFabLocation
        with FabCenterOffsetX, FabDockedOffsetY {
      const FixedCenterDockedFabLocation();
    
      @override
      String toString() => 'FloatingActionButtonLocation.fixedCenterDocked';
    
      @override
      double getOffsetY(
          ScaffoldPrelayoutGeometry scaffoldGeometry, double adjustment) {
        final double contentBottom = scaffoldGeometry.contentBottom;
        final double bottomMinInset = scaffoldGeometry.minInsets.bottom;
        if (bottomMinInset > 0) {
          // Hide if there's a keyboard
          return contentBottom;
        }
        return super.getOffsetY(scaffoldGeometry, adjustment);
      }
    }
    

    然后您可以像 floatingActionButtonLocation: const FixedCenterDockedFabLocation(), 一样简单地使用它(不要忘记 const ;))。

    随意使用此代码,不受限制或归属。

    【讨论】:

      【解决方案3】:

      使用Visibility 小部件包装您的FloatingActionButton,并使用bool 值控制可见性。

      片段:
      Widget build(context) {
        bool keyboardIsOpen = MediaQuery.of(context).viewInsets.bottom != 0;
        return Scaffold(
          body: // ...
          floatingActionButton: Visibility(
            visible: !keyboardIsOpen,
            child: // your FloatingActionButton
          ),
        );
      }
      

      这个解决方案也去掉了按钮消失和出现时的动画。

      确保类 extends StatefulWidget 和你已经为它创建了一个状态

      【讨论】:

      • 我更喜欢这个解决方案而不是答案
      • 很好的解决方案,但不需要变量或StatefulWidget,简化为... visible:MediaQuery.of(context).viewInsets.bottom == 0
      • 我在我的项目中实现了这个。只在其中两个屏幕上工作,其余的没有变化。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-22
      • 1970-01-01
      相关资源
      最近更新 更多