Flutter textField随着键盘弹出升高,点击空白处收回键盘

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter textField随着键盘弹出升高,点击空白处收回键盘相关的知识,希望对你有一定的参考价值。

参考技术A 1、Flutter中的textField要想实现随着键盘弹出自动升高,必须要在Scaffold中,如下所示

2、如果textfield位置比较下面或者小屏幕时,在键盘弹出的时候导致溢出bug

这时候可以嵌套一层SingleChildScrollView(具体嵌套位置可以根据需要调整),如下所示

效果如下:

3、点击空白处收起键盘,直接嵌套一层GestureDetector即可,嵌套位置可以在Scaffold的body层,可以自己调整。

Flutter TextField被键盘隐藏,尝试了很多解决方案但不起作用

【中文标题】Flutter TextField被键盘隐藏,尝试了很多解决方案但不起作用【英文标题】:Flutter TextField hidden by Keyboard, try many solution but not working 【发布时间】:2020-05-04 00:59:19 【问题描述】:

当聚焦于 TextField 时,键盘会隐藏在 TextField 上方。下面我附上了带有代码的屏幕截图。请指导我解决此问题。

signup.dart

import 'package:flutter/material.dart';
import 'package:yfobs/utilities/desc.dart';

class SignUpPage extends StatefulWidget 
  static String tag = 'SignUpPage';
  @override
  _SignUpPageState createState() => _SignUpPageState();


class _SignUpPageState extends State<SignUpPage> 
  
  @override
  Widget build(BuildContext context) 
    return Scaffold(
      resizeToAvoidBottomPadding: false,
      body: Container(
        width: double.infinity,
        decoration: BoxDecoration(
            gradient: LinearGradient(begin: Alignment.topCenter, colors: [
          Color(0xFF832685),
          Color(0xFFC81379),
        ])),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            SizedBox(
              height: 80,
            ),
            Padding(
              padding: EdgeInsets.only(top: 0, bottom: 20, left: 20, right: 20),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  Text(
                    "SignUp",
                    style: TextStyle(color: Colors.white, fontSize: 28),
                  ),
                  SizedBox(
                    height: 10,
                  ),
                  Text(
                    "",
                    style: TextStyle(color: Colors.white, fontSize: 14),
                  ),
                ],
              ),
            ),
            SizedBox(
              height: 20,
            ),
            Expanded(
              child: Container(
                decoration: BoxDecoration(
                    color: Colors.white,
                    borderRadius: BorderRadius.only(
                        topLeft: Radius.circular(60),
                        topRight: Radius.circular(60))),
                child: Padding(
                  padding:
                      EdgeInsets.only(top: 20, bottom: 0, right: 20, left: 20),
                  child: Column(
                    children: <Widget>[
                      Container(
                        height: MediaQuery.of(context).size.height / 1.5,
                        width: MediaQuery.of(context).size.width,
                        padding: EdgeInsets.only(top: 60),
                        child: Column(
                          children: <Widget>[
                            Container(
                              width: MediaQuery.of(context).size.width / 1.2,
                              height: 45,
                              padding: EdgeInsets.only(
                                  top: 0, left: 16, right: 16, bottom: 0),
                              decoration: BoxDecoration(
                                  borderRadius:
                                      BorderRadius.all(Radius.circular(50)),
                                  color: Colors.white,
                                  boxShadow: [
                                    BoxShadow(
                                        color: Colors.black12, blurRadius: 5)
                                  ]),
                              child: TextField(
                                decoration: InputDecoration(
                                  border: InputBorder.none,
                                  icon: Icon(
                                    Icons.person,
                                    color: Colors.grey,
                                  ),
                                  hintText: 'Full Name',
                                ),
                              ),
                            ),

                            Container(
                              width: MediaQuery.of(context).size.width / 1.2,
                              height: 45,
                              padding: EdgeInsets.only(
                                  top: 0, left: 16, right: 16, bottom: 0),
                              margin: EdgeInsets.only(top: 16),
                              decoration: BoxDecoration(
                                  borderRadius:
                                      BorderRadius.all(Radius.circular(50)),
                                  color: Colors.white,
                                  boxShadow: [
                                    BoxShadow(
                                        color: Colors.black12, blurRadius: 5)
                                  ]),
                              child: TextField(
                                decoration: InputDecoration(
                                  border: InputBorder.none,
                                  icon: Icon(
                                    Icons.email,
                                    color: Colors.grey,
                                  ),
                                  hintText: 'Email',
                                ),
                              ),
                            ),

                            Container(
                              width: MediaQuery.of(context).size.width / 1.2,
                              height: 45,
                              padding: EdgeInsets.only(
                                  top: 0, left: 16, right: 16, bottom: 0),
                              margin: EdgeInsets.only(top: 16),
                              decoration: BoxDecoration(
                                  borderRadius:
                                      BorderRadius.all(Radius.circular(50)),
                                  color: Colors.white,
                                  boxShadow: [
                                    BoxShadow(
                                        color: Colors.black12, blurRadius: 5)
                                  ]),
                              child: TextField(
                                decoration: InputDecoration(
                                  border: InputBorder.none,
                                  icon: Icon(
                                    Icons.call,
                                    color: Colors.grey,
                                  ),
                                  hintText: 'Mobile Number',
                                ),
                              ),
                            ),

                            Container(
                              width: MediaQuery.of(context).size.width / 1.2,
                              height: 45,
                              padding: EdgeInsets.only(
                                  top: 0, left: 16, right: 16, bottom: 0),
                              margin: EdgeInsets.only(top: 16),
                              decoration: BoxDecoration(
                                  borderRadius:
                                      BorderRadius.all(Radius.circular(50)),
                                  color: Colors.white,
                                  boxShadow: [
                                    BoxShadow(
                                        color: Colors.black12, blurRadius: 5)
                                  ]),
                              child: TextField(
                                decoration: InputDecoration(
                                  border: InputBorder.none,
                                  icon: Icon(
                                    Icons.***_key,
                                    color: Colors.grey,
                                  ),
                                  hintText: 'Password',
                                ),
                                obscureText: true,
                              ),
                            ),
                            Spacer(),

                            Container(
                              padding: EdgeInsets.all(16),
                              width: double.infinity,
                              child: RaisedButton(
                                elevation: 5.0,
                                padding: EdgeInsets.all(12),
                                shape: RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(30),
                                ),
                                color: Color(0xFFC81379),
                                child: Text(
                                  'Sign Up'.toUpperCase(),
                                  style: TextStyle(
                                      color: Colors.white,
                                      fontWeight: FontWeight.bold),
                                ),
                                onPressed: () 
                                  //Navigator.of(context).pushNamed('HomePage');
                                ,
                              ),
                            ),

                            Align(
                              alignment: Alignment.center,
                              child: Column(
                                  mainAxisAlignment: MainAxisAlignment.center,
                                  children: <Widget>[
                                    new FlatButton(
                                      child: Padding(
                                        padding: const EdgeInsets.only(
                                            top: 0, right: 16, left: 16),
                                        child: new Text(
                                          Desc.alreadyUser,
                                          style: TextStyle(color: Colors.grey),
                                        ),
                                      ),
                                      onPressed: () 
                                        Navigator.of(context)
                                            .pushNamed('SignInPage');
                                      ,
                                      color: Colors.white,
                                      highlightColor: Colors.transparent,
                                    ),
                                  ]),
                            )
                          ],
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  

我正在尝试这个解决方案:

TextFormField hidden by keyboard - Flutter

Flutter/Dart Scrolling textfield above keyboard

in flutter page textfield hidden by keyboard

TextField gets hidden when the keyboard pops in

Flutter Keyboard makes textfield hide

Flutter TextFormField hidden by keyboard

When I select a Textfield the keyboard moves over it

【问题讨论】:

试试这个解决方案:***.com/questions/53586892/… 已经试过了兄弟,我也添加了链接,在我的问题中 【参考方案1】:

你能用 SingleChildScrollView 包裹你的 Scaffold 的 body 并用 ConstrainedBox 包裹你的 Container

这是我得到的输出 https://prnt.sc/qozsvc

键盘仍将位于文本字段的顶部,但通过使用 SingleChildScrollView,屏幕将可滚动,因此您可以向下滚动并再次查看文本字段。

这个解决方案对我有用。

Scaffold(
  body: SingleChildScrollView(
    child: ConstrainedBox(
      constraints: BoxConstraints(maxHeight: MediaQuery.of(context).size.height),
      child: Container(
        .
        .
        .

【讨论】:

我试试,不行【参考方案2】:

嘿,我使用 Expanded 小部件解决了您的问题,只需使用 Expanded 小部件包装您的 child content。并删除一些我们不需要的额外列,试试我的 Below 代码,让我知道它是否有效

import 'package:flutter/material.dart';
import 'package:yfobs/utilities/desc.dart';


    class SignUpPage extends StatefulWidget 
      static String tag = 'SignUpPage';
      @override
      _SignUpPageState createState() => _SignUpPageState();
    

    class _SignUpPageState extends State<SignUpPage> 

      @override
      Widget build(BuildContext context) 
        return Scaffold(
          resizeToAvoidBottomPadding: false,
          resizeToAvoidBottomInset: true,
          body: Container(
            width: double.infinity,
            decoration: BoxDecoration(
                gradient: LinearGradient(begin: Alignment.topCenter, colors: [
                  Color(0xFF832685),
                  Color(0xFFC81379),
                ])),
            child: Column(
              children: <Widget>[
                Expanded(
                  child: signUpCardUI(context),
                ),
              ],
            )
          ),
        );
      
    

    Widget signUpCardUI(BuildContext context)
      return SingleChildScrollView(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            SizedBox(
              height: 80,
            ),
            Padding(
              padding: const EdgeInsets.only(left:20.0),
              child: Text(
                "SignUp",
                style: TextStyle(color: Colors.white, fontSize: 28),
              ),
            ),
            SizedBox(
              height: 30,
            ),
            Card(
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(50.0),
              ),
              child: Padding(
                padding:
                EdgeInsets.only(bottom: 0, right: 20, left: 20),
                child: Column(
                  children: <Widget>[
                    Container(
                      height: MediaQuery.of(context).size.height / 1.5,
                      width: MediaQuery.of(context).size.width,
                      padding: EdgeInsets.only(top: 60),
                      child: Column(
                        children: <Widget>[
                          Container(
                            width: MediaQuery.of(context).size.width / 1.2,
                            height: 40,
                            padding: EdgeInsets.only(
                                top: 0, left: 16, right: 16, bottom: 0),
                            decoration: BoxDecoration(
                                borderRadius:
                                BorderRadius.all(Radius.circular(50)),
                                color: Colors.white,
                                boxShadow: [
                                  BoxShadow(
                                      color: Colors.black12, blurRadius: 5)
                                ]),
                            child: TextField(
                              decoration: InputDecoration(
                                border: InputBorder.none,
                                icon: Icon(
                                  Icons.person,
                                  color: Colors.grey,
                                ),
                                hintText: 'Full Name',
                              ),
                            ),
                          ),

                          Container(
                            width: MediaQuery.of(context).size.width / 1.2,
                            height: 40,
                            padding: EdgeInsets.only(
                                top: 0, left: 16, right: 16, bottom: 0),
                            margin: EdgeInsets.only(top: 16),
                            decoration: BoxDecoration(
                                borderRadius:
                                BorderRadius.all(Radius.circular(50)),
                                color: Colors.white,
                                boxShadow: [
                                  BoxShadow(
                                      color: Colors.black12, blurRadius: 5)
                                ]),
                            child: TextField(
                              decoration: InputDecoration(
                                border: InputBorder.none,
                                icon: Icon(
                                  Icons.email,
                                  color: Colors.grey,
                                ),
                                hintText: 'Email',
                              ),
                            ),
                          ),

                          Container(
                            width: MediaQuery.of(context).size.width / 1.2,
                            height: 40,
                            padding: EdgeInsets.only(
                                top: 0, left: 16, right: 16, bottom: 0),
                            margin: EdgeInsets.only(top: 16),
                            decoration: BoxDecoration(
                                borderRadius:
                                BorderRadius.all(Radius.circular(50)),
                                color: Colors.white,
                                boxShadow: [
                                  BoxShadow(
                                      color: Colors.black12, blurRadius: 5)
                                ]),
                            child: TextField(
                              decoration: InputDecoration(
                                border: InputBorder.none,
                                icon: Icon(
                                  Icons.call,
                                  color: Colors.grey,
                                ),
                                hintText: 'Mobile Number',
                              ),
                            ),
                          ),

                          Container(
                            width: MediaQuery.of(context).size.width / 1.2,
                            height: 40,
                            padding: EdgeInsets.only(
                                top: 0, left: 16, right: 16, bottom: 0),
                            margin: EdgeInsets.only(top: 16),
                            decoration: BoxDecoration(
                                borderRadius:
                                BorderRadius.all(Radius.circular(50)),
                                color: Colors.white,
                                boxShadow: [
                                  BoxShadow(
                                      color: Colors.black12, blurRadius: 5)
                                ]),
                            child: TextField(
                              decoration: InputDecoration(
                                border: InputBorder.none,
                                icon: Icon(
                                  Icons.***_key,
                                  color: Colors.grey,
                                ),
                                hintText: 'Password',
                              ),
                              obscureText: true,
                            ),
                          ),
                          Spacer(),

                          Container(
                            padding: EdgeInsets.all(10),
                            width: double.infinity,
                            child: RaisedButton(
                              elevation: 5.0,
                              padding: EdgeInsets.all(12),
                              shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(30),
                              ),
                              color: Color(0xFFC81379),
                              child: Text(
                                'Sign Up'.toUpperCase(),
                                style: TextStyle(
                                    color: Colors.white,
                                    fontWeight: FontWeight.bold),
                              ),
                              onPressed: () 
                                //Navigator.of(context).pushNamed('HomePage');
                              ,
                            ),
                          ),

                          Align(
                            alignment: Alignment.center,
                            child: Column(
                                mainAxisAlignment: MainAxisAlignment.center,
                                children: <Widget>[
                                  new FlatButton(
                                    child: Padding(
                                      padding: const EdgeInsets.only(
                                          top: 0, right: 16, left: 16),
                                      child: new Text(
                                         Desc.alreadyUser,
                                        style: TextStyle(color: Colors.grey),
                                      ),
                                    ),
                                    onPressed: () 
                                      Navigator.of(context)
                                          .pushNamed('SignInPage');
                                    ,
                                    color: Colors.white,
                                    highlightColor: Colors.transparent,
                                  ),
                                ]),
                          )
                        ],
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ],
        ),
      );
    

快乐编码:)

【讨论】:

兄弟我想要我的页面滚动,你的代码给我这个输出prnt.sc/qoyt9u,你的代码减少了我的空间,而不是滚动我的页面【参考方案3】:

您是否尝试过使用表单小部件? 添加子作为 SingleChildScrollView 可以有 textformfield。

【讨论】:

Scaffold( body: SingleChildScrollView( child: Form( child: Container( ... body>form>SingleChildScrollView>column>Textformfield..... 像这样 请在线查看表单小部件 - 上述解决方案将起作用。【参考方案4】:

这个对我有用signup.dart

import 'package:flutter/material.dart';
import 'package:yfobs/utilities/desc.dart';    

ScrollController _scrollController;                                 //<==  

class SignUpPage extends StatefulWidget 
  static String tag = 'SignUpPage';
  @override
  _SignUpPageState createState() => _SignUpPageState();


class _SignUpPageState extends State<SignUpPage> 

//Implementing scrollController by detecting keyboard               //<==
  bool scrolled = false;
  _scrollListener() 
    if (!scrolled && MediaQuery.of(context).viewInsets.bottom != 0) 
      _scrollController.animateTo(
        _scrollController.position.maxScrollExtent,
        duration: Duration(milliseconds: 100),
        curve: Curves.easeOut,
      );
      scrolled = true;
    
    if (MediaQuery.of(context).viewInsets.bottom == 0) 
      scrolled = false;
    
  

  @override
  void initState() 
    _scrollController = ScrollController();
    _scrollController.addListener(_scrollListener);
    super.initState();
  




  Widget build(BuildContext context) 
    .
    .
    //rest is same
    .
    .

【讨论】:

以上是关于Flutter textField随着键盘弹出升高,点击空白处收回键盘的主要内容,如果未能解决你的问题,请参考以下文章

Flutter控制某个TextField获取焦点及失去焦点

android中TextView在界面显示的时候,我想在键盘显示的上方加两个按钮,一个是确定,一个是取消.

完美解决flutter 键盘遮挡/超出(overflow)的坑

Flutter TextField被键盘隐藏,尝试了很多解决方案但不起作用

Flutter TextField在键盘上溢出底部

当焦点在 TextField 上并且在 Flutter 中打开键盘时,如何向上推送内容?