有没有一种方法可以帮助键盘正确地聚焦在 textformfield 上
Is there a way which helps the keyboard focus correctly on the textformfield
我用 flutter 编写了一个 android 应用程序。作为我代码的一部分,我创建了一个用户页面,让用户可以更新他们的信息,例如姓名或类似的信息。
它工作正常,但是当我点击该页面时,出现了一些错误。
1 is I/ple.flutter_ap(18747): ClassLoaderContext 是一个特殊的共享库。
2nd is W/ple.flutter_ap(18747): Accessing hidden field 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);
},
),
],
);
},
);
})
)
);
}
}
如何解决这个问题?
要关注下一个文本输入字段,您必须使用“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 中设置默认值,然后键盘获取
正常关闭。
所以要解决这个问题,请执行以下操作:
首先使用 "new" 键盘初始化您的 "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()。它将毫无问题地工作和聚焦。
我用 flutter 编写了一个 android 应用程序。作为我代码的一部分,我创建了一个用户页面,让用户可以更新他们的信息,例如姓名或类似的信息。
它工作正常,但是当我点击该页面时,出现了一些错误。
1 is I/ple.flutter_ap(18747): ClassLoaderContext 是一个特殊的共享库。
2nd is W/ple.flutter_ap(18747): Accessing hidden field 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);
},
),
],
);
},
);
})
)
);
}
}
如何解决这个问题?
要关注下一个文本输入字段,您必须使用“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 中设置默认值,然后键盘获取 正常关闭。
所以要解决这个问题,请执行以下操作:
首先使用 "new" 键盘初始化您的 "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()。它将毫无问题地工作和聚焦。