Flutter:编辑文本字段时键盘立即消失

Far*_*oui 25 keyboard listview flutter

带有颤动的注册表单

我正在尝试使用 flutter 构建应用程序前端,这是我第一次遇到这样的错误:无法编辑我的文本表单字段,因为我将表单元素放在列表视图中!当键盘似乎向该字段输入一些文本时,它会在一秒钟内消失!我需要一个立即的解决方案:(

import 'package:flutter/material.dart';
import'package:dubai274_app/mobile_verif.dart';
import 'EnsureVisible.dart';
class SignUp extends StatefulWidget{
  static String tag = 'Sign_up-page';
  SignUp_Page createState() => SignUp_Page();

}
class SignUp_Page extends State<SignUp>{
  


  List<DropdownMenuItem<String>> _Dropdownmenuitems;
  String _statusSel;
  List<DropdownMenuItem<String>> _getDropdownmenuitem(){

    List<DropdownMenuItem<String>> items=new List();
    items.add(new DropdownMenuItem(value:'Emirates',child: new Text('United Arab Emirates')));
    items.add(new DropdownMenuItem(value:'Tun',child: new Text('Tunisia')));
    return items;
  }
  void changeddropdowselecteditem(String selecteditem){
    setState(() {
_statusSel=selecteditem;
    });
  }
   @override
  void initState() {
    // TODO: implement initState
    //listViewController=new ScrollController().addListener(_scrollListener);
    _Dropdownmenuitems=_getDropdownmenuitem();
    _statusSel=_Dropdownmenuitems[0].value;
  }
@override
  Widget build(BuildContext context) {
  final scaffoldKey = GlobalKey<ScaffoldState>();
  final formKey = GlobalKey<FormState>();
  final TextEditingController _controller = new TextEditingController();
  
final first_value=TextFormField(autofocus: false,
  validator: (val) =>
  val.length < 6 ? 'First name required' : null,
  decoration: InputDecoration(
    labelText: 'First Name',
    hintText: 'First Name',
    contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),


  ),);

final family_value=TextFormField(autofocus: false,
  decoration: InputDecoration(
    labelText: 'Last Name',
    hintText: 'Last Name',
    contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),


  ),);

final Nationality=new DropdownButton(items: _Dropdownmenuitems, value:_statusSel,onChanged: changeddropdowselecteditem);

final email_value=TextFormField(keyboardType: TextInputType.emailAddress,
  autofocus: false,
  decoration: InputDecoration(
    labelText: 'Email',
    hintText: 'Email',
    contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),

  ),);

final password=Column(children: <Widget>[ TextFormField(autofocus: false,

  obscureText: true,
  decoration: InputDecoration(
    labelText: 'Password',
    hintText: 'Password',
    contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),)), Text('Min 8 characters with at least one special character')]);
  void _performsignup() {

    final snackbar = SnackBar(
      content: Text('Email: $email, password: $password'),
    );

    scaffoldKey.currentState.showSnackBar(snackbar);
  }
  void _submit() {
    final form = formKey.currentState;

    if (form.validate()) {
      form.save();
      Navigator.push(
        context,
        MaterialPageRoute(builder: (context) => MobileVerif()),
      );

      _performsignup();
    }
  }
final forward_signedin=FloatingActionButton(tooltip: 'Go forward',
  child: Icon(Icons.arrow_forward,color: Colors.white,size: 38.4,),


  onPressed: (){_submit();},);

return MaterialApp(
      title: 'Sign_Up_Page',
      home: Scaffold(
        appBar: AppBar(
          elevation: 0.0,
      backgroundColor: Colors.transparent,
      title: const Text('Sign Up',style: TextStyle(color: Colors.blueAccent, fontSize: 25.0,fontWeight: FontWeight.bold),textAlign: TextAlign.center,),
  centerTitle: true,
  leading: IconButton(
  tooltip: 'Previous choice',
  icon: const Icon(Icons.arrow_back_ios),
    onPressed: () { Navigator.pop(context);},
    color: Colors.black,
    iconSize: 20.0,
  ),
  ),
        body: new Container(
          decoration: new BoxDecoration(
          image: new DecorationImage(
            image: new AssetImage("assets/background.png"),
            fit: BoxFit.cover,
          ),
        ),
        child: new Form( key: formKey,
            child: new Padding( padding: new EdgeInsets.all(40.0), child: ListView(
      children: <Widget>[

       first_value,
       family_value,
       Nationality,
       email_value,
       password,
       new ListTile( title:forward_signedin,)],
)) )

        ),


        ),

      );


  }
}
Run Code Online (Sandbox Code Playgroud)

apc*_*apc 33

您的构建函数中有以下代码:

final formKey = GlobalKey<FormState>();
Run Code Online (Sandbox Code Playgroud)

这就是问题。您必须将其设为静态或移动到 initState()

  • 我遇到了类似的问题。基本上,我有一个想要重用的表单,因此我创建了一个单独的小部件。然后,无论我在哪里使用该小部件,我都会将 GlobalKey&lt;FormState&gt; 传递给该小部件。一种形式可以正常工作,另一种形式将表现出键盘关闭行为。然而,密钥的创建不在构建方法中。按照您的建议创建静态密钥似乎可以修复它,但不知道为什么...... (3认同)
  • 有人愿意解释为什么在不将其声明为静态时会发生这种情况吗? (3认同)
  • 当您将 GlobalKey&lt;FormState&gt; 放入构建函数时会发生这种情况 (2认同)

Sri*_*nth 15

拥有表单的 GlobalKey 并不适合我。有用的是这个github 评论。本质上,获取MediaQuery.of(context)屏幕大小的 a 会导致重建,从而使文本字段失去焦点。就我而言,MediaQuery 访问小部件位于小部件树的非常高的位置。我必须查找它并将其替换为LayoutBuilder

class ScreenSizeGetter extends StatelessWidget {
  const ScreenSizeGetter({Key? key, required this.child}) : super(key: key);
  final Widget child;

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (BuildContext context, BoxConstraints constraints) {
          double screenWidth = constraints.maxWidth;
          double screenHeight = constraints.maxHeight;
          
          // Can pass these sizes down to the child by Bloc pattern or other ways
          return child;
      },
    );
  }
}
Run Code Online (Sandbox Code Playgroud)


Art*_*tov 11

如果您正在使用StatelessWidget,请将其转换为StatefulWidget. 确保密钥是状态的属性,而不是小部件的。发生这种情况是因为每次重建时都会一遍又一遍地重新创建表单密钥。为了保留密钥,它应该是国家的一部分。


kri*_*ris 7

我将在这里发布我的答案,尽管它与OP的问题并不完全相同。

我在互联网上到处搜索键盘出现和消失的问题,
1.这是我发现的唯一一个描述键盘出现和消失问题的问题,
2.其他解决方案,比如@apc的答案和这个github答案都集中在formKeybeingstatic和/或aGlobalKey上,这绝对不是我的问题的原因(为我的表单和/或其字段保留不变的键或重新创建的键,对问题)。

我的具体问题涉及class AuthService with ChangeNotifier多种Future方法。
经过几天的尝试不同的方法后,我发现避免键盘出现并立即消失在表单字段焦点问题上的唯一AuthService()方法是让其位于我的应用程序的顶层,runApp():

void main() => runApp(
  ChangeNotifierProvider<AuthService>(
    child: TheWidgetThatIsMyAppAndHasAllBusinessLogicInIt(),
    builder: (BuildContext context) {
      return AuthService();
    },
  ),
);
Run Code Online (Sandbox Code Playgroud)

ChangeNotifierProvider代码中的其他任何地方都会出现键盘消失的问题)

然后,我必须在如何构建逻辑方面发挥创意 - 因为我只真正关心应用程序某些部分的 AuthService,但我对 Flutter 非常陌生,这都是很好的学习。

我不知道为什么会这样,我很想了解更多,而且我知道我还没有阐明我的全部情况......
但我花了几天时间解决这个问题,我需要把我的在此回答,希望能帮助到其他人。


Jkh*_*led 5

我遇到了同样的问题,正如@apc 所说,只需将密钥设为静态或将其初始化 iniState()...

如果您使用无状态小部件,请将其设为静态

static final GlobalKey<FormState> _key = GlobalKey<FormState>();


Moh*_*eda 5

您应该定义所有这些:

  final scaffoldKey = GlobalKey<ScaffoldState>();
  final formKey = GlobalKey<FormState>();
  final TextEditingController _controller = new TextEditingController();
Run Code Online (Sandbox Code Playgroud)

作为 SignUp_Page 的字段而不是构建函数。