[英]Page refreshes when textformfield is focused on
在“編輯配置文件”頁面中,當 Textformfield 專注於編輯文本時,整個頁面會重新加載,並且不允許我更改或輸入任何內容。 代碼是這樣的:
body: Form(
key: _formKey,
child: FutureBuilder<DocumentSnapshot<Map<String, dynamic>>>(
future: FirebaseFirestore.instance
.collection('appusers')
.doc(widget.id)
.get(),
builder: (_, snapshot) {
if (snapshot.hasError) {
print('Something went wrong');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
}
var data = snapshot.data!.data();
var name = data!['name'];
return Padding(
padding: EdgeInsets.symmetric(vertical: 20, horizontal: 30),
child: Column(
children: [
Container(
margin: EdgeInsets.symmetric(vertical: 10),
child: TextFormField(
initialValue: name,
autofocus: false,
onChanged: (value) => name = value,
decoration: InputDecoration(
labelText: 'Name: ',
border: OutlineInputBorder(),
errorStyle:
TextStyle(color: Colors.redAccent, fontSize: 12),
),
validator: (value) {
RegExp regex = new RegExp(r'^.{3,}$');
if (value == null || value.isEmpty) {
return 'Please enter full name.';
}
if (!regex.hasMatch(value)) {
return ("Please enter a name.");
}
return null;
},
),
),
SizedBox(height: 40),
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
updateUser(widget.id, name);
}
Navigator.of(context).pop();
},
child: Text(
'Update',
style: TextStyle(fontSize: 15),
),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(
'Cancel',
style: TextStyle(fontSize: 15),
),
),
],
),
)
],
),
);
},
)),
頁面不斷刷新是否有原因? 還有其他類似於“名稱”的文本字段,單擊其中任何一個都會導致此頁面重新加載。 formkey 在 Widget 構建之前已聲明為final _formKey = GlobalKey<FormState>();
.
讓您了解 flutter 在打開鍵盤時如何處理應用程序。
打開鍵盤時,flutter 實際上會改變屏幕大小(即底部填充更改),因為當您訪問此小部件中的MediaQuery.of(context)
時,它將導致小部件重建,以便MediaQuery.of(context)
將返回更新后的MediaQueryData
。 這個重建很好。
問題在於您使用FutureBuilder
的future
參數的方式。 FirebaseFirestore.instance.collection('appusers').doc(widget.id).get()
將在每次重建此EditProfile
小部件時執行,但您可能希望在加載小部件時僅調用一次第一次。 所以你需要在StatefulWidget
initState 中初始化未來,比如:
Future future;
@override
void initState() {
super.initState();
future = FirebaseFirestore.instance.collection('appusers').doc(widget.id).get();
}
現在,每當小部件重建時,它都不會調用 FirebaseFirestore 調用。 但是您的TextFormField
的initialValue
參數還有另一個問題。 它使用在看起來不正確的build
方法中聲明和初始化的name
變量。 您可以執行以下操作:
var name:
Future future;
@override
void initState() {
super.initState();
future = FirebaseFirestore.instance.collection('appusers').doc(widget.id).get();
future.then((value) {
if(value != null) {
var name = value.data!['name'];
}
});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.