flutter - 如何在 FutureBuilder Flutter 中停止循环 SetState
问题描述
我有构建小部件。在构建内部,我调用 FutureBuilder 从 API 加载数据。所以我在 FutureBuilder 中添加了 setState 。当我单击编辑按钮将某些内容添加到文本表单中时,这对屏幕进行了不寻常的刷新。我想将未来移出... initState 。这样做的正确方法是什么?
我的代码:
class _ProfileState extends State<Profile> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final Color blue = Color(0xFF010611);
BoxApi boxApi = BoxApi();
UserApi userApi = UserApi();
@override
void initState() {
super.initState();
myFocusNode = FocusNode();
telephoneNode = FocusNode();
adresseNode = FocusNode();
emailNode = FocusNode();
passwordNode = FocusNode();
_isHidden = true;
}
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return SafeArea(
/* minimum: const EdgeInsets.only(
top: 20.0, right: 5.0, left: 5.0, bottom: 10.0),*/
child: Center(
child: Scaffold(
resizeToAvoidBottomInset: true,
backgroundColor: Color(0xFFF6F7F8),
body: SingleChildScrollView(
child: Form(
key: _formKey,
child: FutureBuilder<User>(
future: boxApi.getUser(),
builder: (context, snapshot) {
// ignore: missing_return
print(snapshot.data);
switch (snapshot.connectionState) {
case ConnectionState.none:
return Text('no connection');
case ConnectionState.active:
case ConnectionState.waiting:
return Center(
child: CircularProgressIndicator(),
);
break;
case ConnectionState.done:
if (snapshot.hasError) {
return Text('error');
} else if (snapshot.hasData) {
// String price = snapshot.data['body'].;
// print("${snapshot.data}");
return Column(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: [
Container(
padding: EdgeInsets.only(top: 16),
width: MediaQuery.of(context).size.width,
height:
MediaQuery.of(context).size.height / 4,
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.white60,
blurRadius: 15.0,
offset: Offset(0.0, 0.75))
],
gradient: LinearGradient(
begin: Alignment(0.5, 0.85),
end: Alignment(0.48, -1.08),
colors: [
const Color(0xFF0B0C3A),
const Color(0xFF010611),
],
stops: [
0.0,
0.5,
],
),
//color: blue,
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(32),
bottomLeft: Radius.circular(32))),
child: Column(
children: [
Row(
children: [
SizedBox(
width: 30,
),
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
"${snapshot.data.name}",
style: TextStyle(
color: Colors.white,
fontSize: 25,
fontWeight:
FontWeight.bold),
),
SizedBox(
height: 10,
),
Text(
"${snapshot.data.phone}",
style: TextStyle(
color: Colors.white60,
fontSize: 18,
//fontWeight: FontWeight.w300
),
),
])
],
),
Row(
mainAxisAlignment:
MainAxisAlignment.end,
children: [
Container(
margin: EdgeInsets.symmetric(
vertical: 10),
width: size.width * 0.4,
child: ElevatedButton(
/*onPressed: () => [
modifyUserName(),
// modifyUserEmail(),
// modifyUserAdress()
],*/
onPressed: () {
editUserProfile();
// modifyUserEmail();
},
child: Text('Enregistrer'),
style:
ElevatedButton.styleFrom(
primary: Colors.transparent,
shape:
RoundedRectangleBorder(
borderRadius:
BorderRadius
.circular(
20),
side: BorderSide(
color: Colors
.white)),
),
)),
SizedBox(
width: 20,
),
],
)
],
),
),
Container(
height: MediaQuery.of(context).size.height /
1.5,
// padding: EdgeInsets.only(
// top: 32,
// ),
child: Column(
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Column(
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Container(
width: size.width * 0.94,
child: Column(
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Container(
padding: EdgeInsets.only(
left: 10,
right: 10,
bottom: 20,
top: 20),
child: Column(
mainAxisAlignment:
MainAxisAlignment
.start,
crossAxisAlignment:
CrossAxisAlignment
.start,
children: [
Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Text(
'Votre nom :',
style: TextStyle(
color: Color(
0xFF4053FCF),
fontSize: 16,
fontWeight:
FontWeight
.w600),
),
IconButton(
icon: Icon(
CommunityMaterialIcons
.pencil,
color: Colors
.grey,
),
onPressed: () {
myFocusNode
.requestFocus();
setState(() {
enableup =
true;
});
})
],
),
TextFormField(
controller:
_nameController,
enabled: enableup,
focusNode:
myFocusNode,
enableInteractiveSelection:
false,
keyboardType:
TextInputType
.text,
decoration: InputDecoration(
hintText:
"${snapshot.data.name}",
hintStyle: TextStyle(
color: Colors
.grey,
fontSize:
14.0)),
),
SizedBox(
height: 15,
),
Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Text(
'N° Téléphone :',
style: TextStyle(
color: Color(
0xFF4053FCF),
fontSize: 16,
fontWeight:
FontWeight
.w600),
),
/* IconButton(
icon: Icon(
CommunityMaterialIcons
.pencil,
color: Colors
.grey,
),
onPressed: () {
telephoneNode
.requestFocus();
setState(() {
enabletel =
true;
});
})*/
],
),
TextFormField(
enabled: false,
focusNode:
telephoneNode,
enableInteractiveSelection:
false,
keyboardType:
TextInputType
.text,
decoration: InputDecoration(
hintText:
"${snapshot.data.phone}",
hintStyle: TextStyle(
color: Colors
.grey,
fontSize:
14.0)),
),
Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Text(
'Adresse :',
style: TextStyle(
color: Color(
0xFF4053FCF),
fontSize: 16,
fontWeight:
FontWeight
.w600),
),
IconButton(
icon: Icon(
CommunityMaterialIcons
.pencil,
color: Colors
.grey,
),
onPressed: () {
adresseNode
.requestFocus();
setState(() {
enableadress =
true;
});
})
],
),
TextFormField(
enabled: enableadress,
controller:
_adressController,
focusNode:
adresseNode,
enableInteractiveSelection:
false,
keyboardType:
TextInputType
.text,
decoration: InputDecoration(
hintText:
"${snapshot.data.adress}",
hintStyle: TextStyle(
color: Colors
.grey,
fontSize:
14.0)),
),
} else {
return Text('No Data');
}
break;
default:
return Container();
break;
}
}
我如何在 initState tp 中运行 getUser() 以防止 FutureBuilder 和 setState 之间的循环?
解决方案
像这样的东西:
StatefulBuilder(
builder: (context, setState2) => FutureBuilder<User>(...))
并将 FutureBuilder 中的任何 setState 替换为 setState2,这样当您使用 setState2 时,他只会刷新 FutureBuilder 而不是整个页面。
推荐阅读
- whmcs - WHMCS:如何在可配置选项中添加域检查器
- javascript - 如何设置边界框的最小距离?
- php - 通过 URL 中的参数推送 CSS(路径)
- kubernetes - 将 EC2 上的文件夹添加为 EKS 集群上的卷
- reactjs - 在下载 react pacakge 时,我没有得到 src gitnore 和其他一些文件
- java - Mockito 实例间谍对内部和外部调用的工作方式不同
- javascript - 在对象字面量函数中需要等效于 switch case 的默认值
- unity3d - UnityHub 选项“Unity 编辑器文件夹”无效。想要更改 Unity 编辑器的安装位置?
- bash - 从 Bash 脚本启动时的不同版本的 Vim
- google-apps-script - 如何使用 Sheets API 在最后一列之后插入列?