#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, он работает и фокусируется без каких-либо проблем