【问题标题】:Is there a way which helps the keyboard focus correctly on the textformfield有没有一种方法可以帮助键盘正确聚焦在 textformfield 上
【发布时间】:2019-09-10 12:03:35
【问题描述】:

我用 Flutter 编写了一个 Android 应用程序。作为我的代码的一部分,我创建了一个用户页面,让用户更新他们的信息,例如姓名姓氏或类似的东西。

它可以工作,但是当我点击页面时,我得到了一些错误。

1 是 I/ple.flutter_ap(18747):ClassLoaderContext 是一个特殊的共享库。

第二个是 W/ple.flutter_ap(18747): 访问隐藏字段 Ldalvik/system/BaseDexClassLoader;->pathList:Ldalvik/system/DexPathList; (浅灰名单,反射)

另一个问题是键盘没有专注于文本字段。当我单击文本字段时,键盘会立即打开和关闭。当我再次单击时,它会显示出来并立即再次关闭。

我尝试了 autofocus: true 但这一次它尝试自己聚焦。它被打开和关闭了 5 次,但最后它集中了。但这不应该发生。

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';

class Screen1 extends StatefulWidget {
  @override
  _Screen1State createState() => _Screen1State();
}

class _Screen1State extends State<Screen1> {


  var _AdContr = TextEditingController();
  var _SoyadContr = TextEditingController();
  final _NicknameContr = TextEditingController();
  final _getContr = TextEditingController();
  final _myUpdateContr = TextEditingController();

  var _transactionListener;

  @override
  void dispose() {
     // Clean up controllers when disposed
    _AdContr.dispose();
    _SoyadContr.dispose();
    _NicknameContr.dispose();
    _getContr.dispose();
    _myUpdateContr.dispose();
    // Cancel transaction listener subscription
    _transactionListener.cancel();
    super.dispose();
  }


  void clickUpdate(_formKey1, _formKey2) async {
    FirebaseUser user = await FirebaseAuth.instance.currentUser();
    String uid = user.uid.toString();
    await Firestore.instance
        .collection('kitaplar')
        .document(uid)
        .updateData({'adi': _formKey1, 'Soyadi': _formKey2});
    Navigator.pop(context);
  }



  @override
  void initState() {
    super.initState();


  }    





   @override
   Widget build(BuildContext context) {
     return new Scaffold(
      appBar: AppBar(
        title: Text('Retrieve Text Input'),
      ),
      body: new Container(
          padding: EdgeInsets.only(top: 20.0, left: 10.0, right: 10.0),
          child: FutureBuilder(
              future: FirebaseAuth.instance.currentUser(),
              builder: (BuildContext context,
                  AsyncSnapshot<FirebaseUser> snapshot) {
                if (snapshot.connectionState != ConnectionState.done)
                  return Container();
                return StreamBuilder<DocumentSnapshot>(
                  stream: Firestore.instance.collection('kitaplar')
                      .document(snapshot.data.uid)
                      .snapshots(),
                  builder: (BuildContext context, AsyncSnapshot snapshot) {
                    if (!snapshot.hasData) return Container();
                    var userDocument = snapshot.data;
                    var contentadi = userDocument["adi"].toString();
                    var contentsoyadi = userDocument["Soyadi"].toString();

                    return Column(
                      children: <Widget>[
                        TextFormField(
                          controller: _AdContr = new TextEditingController(text: contentadi == null ? "" : contentadi),
                          //controller: _AdContr,
                          //initialValue: userDocument["adi"].toString(),
                          decoration: new InputDecoration(
                            labelText: 'Adınız',
                            fillColor: Colors.white,
                            border: new OutlineInputBorder(
                              borderRadius: new BorderRadius.circular(25.0),
                              borderSide: new BorderSide(),
                            ),
                            //fillColor: Colors.green
                          ),
                        ),
                        SizedBox(height: 20),
                        TextFormField(
                          controller: _SoyadContr = new TextEditingController(text: contentsoyadi == null ? "" : contentsoyadi),
                          //controller: _AdContr,
                          decoration: new InputDecoration(
                            labelText: 'Soyadınız',
                            fillColor: Colors.white,
                            border: new OutlineInputBorder(
                              borderRadius: new BorderRadius.circular(25.0),
                              borderSide: new BorderSide(),
                            ),
                            //fillColor: Colors.green
                          ),
                        ),
                        RaisedButton(
                          color: Colors.orange,
                          textColor: Colors.white,
                          splashColor: Colors.orangeAccent,
                          child: const Text('Update'),
                          onPressed: () {
                            clickUpdate(_AdContr.text, _SoyadContr.text);
                          },
                        ),
                      ],
                    );
                  },
                );
              })
      )
  );
}
}

我该如何解决这个问题?

【问题讨论】:

    标签: flutter keyboard textfield lost-focus


    【解决方案1】:

    要关注下一个文本输入字段,您必须使用“FocusNode();”,如下所示: 在“TextFormField(”中我们可以使用这个方法来聚焦:

    onFieldSubmitted: (v){
          FocusScope.of(context).requestFocus(focus);
    },
    

    还可以为文本输入字段设置不同的选项,例如键盘中的下一步和完成选项,您可以使用以下方法:

    1) 对于下一个选项:"textInputAction: TextInputAction.next,"

    2) 对于完成选项:"textInputAction: TextInputAction.done,"

    以下是自动聚焦下一个文本输入字段的完整示例:

    class MyApp extends State<MyLoginForm> {
      final _formKey = GlobalKey<FormState>();
      final focus = FocusNode();
    
      @override
      Widget build(BuildContext context) {
        return Container(
            color: Colors.white,
            child: Center(
                child: Form(
    
                  key: _formKey,
                  child: Column(
    
                    mainAxisAlignment: MainAxisAlignment.start,
                    children: <Widget>[
    
                      Padding(
                        padding: const EdgeInsets.only(left: 30, top: 65.0, right: 30, bottom: 0),
                        child:
                        TextFormField(
                          textInputAction: TextInputAction.next,
                          decoration: new InputDecoration(hintText: 'Enter username', contentPadding: EdgeInsets.all(8.0)),
                          style: new TextStyle(fontSize: 18),
                          onFieldSubmitted: (v){
                            FocusScope.of(context).requestFocus(focus);
                          },
                        ),
                      ),
    
                      Padding(
                        padding: const EdgeInsets.only(left: 30, top: 30.0, right: 30, bottom: 0),
                        child:
                        TextFormField(
                          focusNode: focus,
                          textInputAction: TextInputAction.done,
                          decoration: new InputDecoration(hintText: 'Enter password', contentPadding: EdgeInsets.all(8.0)),
                          style: new TextStyle(fontSize: 18),
                          onFieldSubmitted: (v){
                            FocusScope.of(context).requestFocus(focus);
                          },
                        ),
                      ),
    
    
                    ],
    
                  ),
    
                ),
            ),
    
        );
      }
    
    }
    

    问题是您在使用 TextEditingController 打开键盘时在 TextFormField 中设置文本。 这意味着 您每次都在 TextEditingController 中分配一个值,因此当键盘打开时,“TextEditingController”将 开火,它会尝试检查您的条件并在您的 TextFormField 中设置默认值,然后键盘获取 正常关闭。

    所以要解决这个问题,请执行以下操作:

    首先使用“新”键盘初始化您的“TextEditingController”,如下所示:

      var _AdContr = new TextEditingController();
      var _SoyadContr = new TextEditingController();
      final _NicknameContr = new TextEditingController();
      final _getContr = new TextEditingController();
      final _myUpdateContr = new TextEditingController();
    

    然后尝试在这两行之后为“TextFormField”设置默认文本:

    var contentadi = userDocument["adi"].toString();
    var contentsoyadi = userDocument["Soyadi"].toString();
    _AdContr.text = (contentadi == null ? "" : contentadi);
    _SoyadContr.text = (contentsoyadi == null ? "" : contentsoyadi);
    

    然后如下更改您的“TextFormField”并尝试将这些值保存在“onSubmitted”方法中的变量中:

    return Column(
                          children: <Widget>[
                            TextFormField(
                              controller: _AdContr,
                              onSubmitted: (String str){
                                setState(() {
                                    contentadi = str;
                                    _AdContr.text = contentadi;
                                });
                              },
                              decoration: new InputDecoration(
                                labelText: 'Adınız',
                                fillColor: Colors.white,
                                border: new OutlineInputBorder(
                                  borderRadius: new BorderRadius.circular(25.0),
                                  borderSide: new BorderSide(),
                                ),
                                //fillColor: Colors.green
                              ),
                            ),
                            SizedBox(height: 20),
                            TextFormField(
                              controller: _SoyadContr,
                              onSubmitted: (String str){
                                setState(() {
                                    contentsoyadi = str;
                                    _SoyadContr.text = contentsoyadi;
                                });
                              },
                              decoration: new InputDecoration(
                                labelText: 'Soyadınız',
                                fillColor: Colors.white,
                                border: new OutlineInputBorder(
                                  borderRadius: new BorderRadius.circular(25.0),
                                  borderSide: new BorderSide(),
                                ),
                                //fillColor: Colors.green
                              ),
                            ),
                            RaisedButton(
                              color: Colors.orange,
                              textColor: Colors.white,
                              splashColor: Colors.orangeAccent,
                              child: const Text('Update'),
                              onPressed: () {
                                clickUpdate(_AdContr.text, _SoyadContr.text);
                              },
                            ),
                          ],
                        );
    

    如果上述解决方案不起作用,请尝试使用 StreamBuilder() 而不是 FutureBuilder()。它可以正常工作并集中注意力。

    【讨论】:

    • 我的主要问题是,当我单击表单时,键盘出现并立即关闭。可以在下面的视频中看到。 youtube.com/watch?v=2yNH5dPkP1U
    • 嗨,看完您的视频和代码后,我已经更新了我的答案,继续使用粗体字。请检查
    • 您好首先感谢您的帮助。它尝试过但没有用。我使用了 onFieldSubmitted。因为当我使用 onSubmitted 时,它说“参数'onSubmitted'没有定义。”所以我改变了它。但没有奏效。我设置了自动对焦:true,这次控制台上有一些警告,例如: 非活动 InputConnection 上的 beginBatchEdit 非活动 InputConnection 上的 getTextBeforeCursor 非活动 InputConnection 上的 getTextAfterCursor 非活动 InputConnection 上的 getSelectedText 非活动 InputConnection 上的 endBatchEdit 此警告显示 4 倍于键盘聚焦。最好的问候
    • 如果可能的话,首先尝试使用我的代码以及没有 FutureBuilder 的代码仅用于测试并检查问题是否发生
    • 当我删除 Future 构建器并仅保留在 StreamBuilder 上时,它可以正常工作并专注于没有任何问题
    猜你喜欢
    • 2021-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-06
    • 1970-01-01
    • 2015-11-02
    相关资源
    最近更新 更多