Есть ли способ, который помогает клавиатуре правильно фокусироваться на textformfield

#flutter #keyboard #textfield #lost-focus

#flutter #клавиатура #текстовое поле #потерянный фокус

Вопрос:

Я пишу приложение для Android с помощью flutter. Как часть моего кода я создал страницу пользователя, чтобы позволить пользователю обновлять свою информацию, такую как имя, фамилия или что-то в этом роде.

Он работает, но когда я нажимаю на страницу, я получаю несколько ошибок.

1 — это I / ple.flutter_ap(18747): ClassLoaderContext — это специальная разделяемая библиотека.

2-й — это W / ple.flutter_ap(18747): доступ к скрытому полю Ldalvik/system/BaseDexClassLoader;-> Список путей: Ldalvik/system/ DexPathList; (светло-серый список, отражение)

И другая проблема заключается в том, что клавиатура не фокусируется на текстовом поле. Когда я щелкнул по текстовому полю, клавиатура немедленно открывается и закрывается. Когда я снова щелкнул, он появляется и снова немедленно закрывается.

Я попробовал автофокусировку: 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);
                          },
                        ),
                      ],
                    );
                  },
                );
              })
      )
  );
}
}
  

Как мне решить эту проблему?

Ответ №1:

Чтобы перейти к следующему текстовому полю ввода, вы должны использовать « FocusNode(); «, например, как показано ниже: В «TextFormField (» мы можем использовать этот метод для фокусировки:

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

Также для установки различных параметров для поля ввода текста, таких как параметры next и done на клавиатуре, вы можете использовать метод ниже:

1) Для следующего параметра: «textInputAction: TextInputAction.next,»

2) Для опции done: «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);
                      },
                    ),
                  ),


                ],

              ),

            ),
        ),

    );
  }

}
  

Проблема в том, что вы устанавливаете текст в TextFormField, когда клавиатура открывается с помощью TextEditingController.Это означает
, что вы каждый раз присваиваете значение в 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(). он будет работать и фокусироваться без каких-либо проблем.

Комментарии:

1. Моя главная проблема заключается в том, что когда я нажимаю на форму, клавиатура отображается и немедленно закрывается. Это можно увидеть на следующем видео. youtube.com/watch?v=2yNH5dPkP1U

2. привет, после просмотра вашего видео и кода я обновил свой ответ, выделив жирный текст. пожалуйста, проверьте

3. Привет, прежде всего, спасибо за вашу помощь. Он пытался, но не сработал. Я использовал onFieldSubmitted. Потому что, когда я использовал onSubmitted, он сказал: «параметр’onSubmitted’ не определен». Таким образом, я изменил его. Но не сработало. Я установил автофокусировку: true, на этот раз на консоли было несколько предупреждений, таких как: beginBatchEdit при неактивном InputConnection getTextBeforeCursor при неактивном InputConnection getTextAfterCursor при неактивном InputConnection getSelectedText при неактивном InputConnection endBatchEdit при неактивном InputConnection Это предупреждение отображалось 4 раза в десять при фокусировке клавиатуры. С наилучшими пожеланиями

4. если возможно, сначала попробуйте использовать мой код, а также свой код без FutureBuilder только для тестирования и проверьте, возникает проблема или нет

5. Когда я удалил Future builder и сохранил только StreamBuilder, он работает и фокусируется без каких-либо проблем