解决 Flutter 键盘遮挡输入框问题

44 min read

Flutter 键盘遮挡输入框问题可以通过以下几种方式解决:

  1. SingleChildScrollView + MediaQuery

使用 SingleChildScrollView 包装输入框所在的 Widget,并在外层添加 MediaQuery 获取屏幕的大小和键盘高度,当键盘弹出时自动滚动页面,以确保输入框不被键盘遮挡。示例代码如下:

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MediaQuery(
      data: MediaQuery.of(context).copyWith(viewInsets: EdgeInsets.zero),
      child: Scaffold(
        body: SingleChildScrollView(
          child: Column(
            children: [
              TextFormField(
                autofocus: true,
                decoration: InputDecoration(
                  labelText: 'Username',
                ),
              ),
              TextFormField(
                autofocus: true,
                decoration: InputDecoration(
                  labelText: 'Password',
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
  1. ListView + MediaQuery

使用 ListView 包装输入框所在的 Widget,并在外层添加 MediaQuery 获取屏幕的大小和键盘高度,当键盘弹出时自动滚动页面,以确保输入框不被键盘遮挡。示例代码如下:

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MediaQuery(
      data: MediaQuery.of(context).copyWith(viewInsets: EdgeInsets.zero),
      child: Scaffold(
        body: ListView(
          children: [
            TextFormField(
              autofocus: true,
              decoration: InputDecoration(
                labelText: 'Username',
              ),
            ),
            TextFormField(
              autofocus: true,
              decoration: InputDecoration(
                labelText: 'Password',
              ),
            ),
          ],
        ),
      ),
    );
  }
}
  1. SingleChildScrollView + GestureDetector

使用 SingleChildScrollView 包装输入框所在的 Widget,同时在外层添加 GestureDetector 监听输入框的焦点变化,当焦点移动到输入框之后,自动滚动页面,以确保输入框不被键盘遮挡。示例代码如下:

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SingleChildScrollView(
        child: GestureDetector(
          behavior: HitTestBehavior.opaque,
          onTap: () async {
            FocusScopeNode currentFocus = FocusScope.of(context);
            if (!currentFocus.hasPrimaryFocus && currentFocus.focusedChild != null) {
              currentFocus.focusedChild.unfocus();
            }
          },
          child: Column(
            children: [
              TextFormField(
                autofocus: true,
                decoration: InputDecoration(
                  labelText: 'Username',
                ),
              ),
              TextFormField(
                autofocus: true,
                decoration: InputDecoration(
                  labelText: 'Password',
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

以上三种方式均能解决 Flutter 键盘遮挡输入框问题,具体选择哪种方式需要结合具体业务场景进行选择。