有没有一种方法可以帮助键盘正确地聚焦在textformfield上

时间:2019-04-20 15:35:49

标签: flutter keyboard textfield lost-focus

我写了一个有浮躁的Android应用程序。作为代码的一部分,我创建了一个用户页面,以使用户可以更新其信息,例如姓氏或类似的信息。

它正在运行,但是当我单击页面时,我得到的错误很少。

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

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

另一个问题是键盘没有聚焦在文本字段上。当我单击文本字段时,键盘显示为“立即打开和关闭”。当我再次单击时,它会显示并再次立即关闭。

我尝试了自动对焦:是的,但是这次它试图自动对焦。它被打开和关闭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);
                          },
                        ),
                      ],
                    );
                  },
                );
              })
      )
  );
}
}

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

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

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

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

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()。它将毫无问题地工作并集中精力。