简体   繁体   English

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

[英]Is there a way which helps the keyboard focus correctly on the textformfield

I write an android app with flutter. 我写了一个带有颤动的Android应用程序。 As a part of my code I created a user page to let the user to update their information such as name surname or something like that. 作为我的代码的一部分,我创建了一个用户页面,让用户更新他们的信息,如姓氏或类似的东西。

It is working but when I clicked the page I am getting few errors. 它正在工作,但当我点击页面时,我收到的错误很少。

1 is I/ple.flutter_ap(18747): The ClassLoaderContext is a special shared library. 1是I / ple.flutter_ap(18747):ClassLoaderContext是一个特殊的共享库。

2nd is W/ple.flutter_ap(18747): Accessing hidden field Ldalvik/system/BaseDexClassLoader;->pathList:Ldalvik/system/DexPathList; 第二个是W / ple.flutter_ap(18747):访问隐藏字段Ldalvik / system / BaseDexClassLoader; - > pathList:Ldalvik / system / DexPathList; (light greylist, reflection) (浅灰名单,反射)

And the other problem is The keyboard is not focusing on the textfield. 另一个问题是键盘没有专注于文本字段。 When I clicked the textfield the keyborad is Opening and closing immediately. 当我单击文本字段时,keyborad立即打开和关闭。 When I clicked again it shows up and again closing immediately. 当我再次点击时,它会立即显示并再次关闭。

I tried autofocus: true but this time it tried to focus it self. 我试过自动对焦:是的但是这一次它试图把它自己集中起来。 It is opended and closed 5 times but at last it focused. 它被开放和关闭5次,但最后它集中了。 But that shouldnt be happen. 但那不应该发生。

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);
                          },
                        ),
                      ],
                    );
                  },
                );
              })
      )
  );
}
}

How do I solve this problem? 我该如何解决这个问题?

To foucs on next text input field you have to use " FocusNode(); " such as below: In the "TextFormField(" we can use this method to focus: 要对下一个文本输入字段进行填充,您必须使用“ FocusNode(); ”,如下所示:在“TextFormField(”中,我们可以使用此方法进行聚焦:

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

Also to set different options for text input field such as next and done options in keyboard, you can use below method: 另外,要为文本输入字段设置不同的选项,例如键盘中的next和done选项,您可以使用以下方法:

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

2) For done option: "textInputAction: TextInputAction.done," 2)对于完成选项:“textInputAction:TextInputAction.done”

Below is the full example to auto focus on next text input field: 下面是自动关注下一个文本输入字段的完整示例:

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);
                      },
                    ),
                  ),


                ],

              ),

            ),
        ),

    );
  }

}

Problem is you are setting the text in TextFormField when keyboard opens with the TextEditingController. 问题是当键盘打开时使用TextEditingController在TextFormField中设置文本。 It means you are assigning a value every time in TextEditingController so when keyboard opens, "TextEditingController" will fire and it will try to check your condition and set the default value in your TextFormField and then keyboard gets closed as normal behaviour. 这意味着你每次都在TextEditingController中分配一个值,所以当键盘打开时,“TextEditingController”将会触发,它将尝试检查你的状态并在TextFormField中设置默认值,然后键盘将作为正常行为关闭。

So to solve this do as below: 所以要解决这个问题,如下:

First of all initialize your "TextEditingController" with "new" keyboard as below: 首先使用“new”键盘初始化“TextEditingController”,如下所示:

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

Then try to set default text for "TextFormField" after this two lines: 然后尝试在这两行之后为“TextFormField”设置默认文本:

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

Then change your "TextFormField" as below and try to save those value in your variables in "onSubmitted" method: 然后如下所示更改“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);
                          },
                        ),
                      ],
                    );

If above solution not work then try to use StreamBuilder() instead of FutureBuilder(). 如果上面的解决方案不起作用,那么尝试使用StreamBuilder()而不是FutureBuilder()。 it will work and focuse without any problem. 它会工作和专注,没有任何问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM