问题描述
我在使用此代码时遇到了一些问题.. 我使用 initState() 将我的小部件“ComponentsHistoriqueDeployment”移动到一个有状态的小部件,以解决每次小部件重建时的焦点问题。 所以实际上数据是第一次获取的,但是当我在搜索栏“Sélectionnez le composant”中录制某些内容或通过更改 datePicker 时它不会改变。
我不明白为什么...
这是父级:
class HistoriquePage extends StatefulWidget {
final String pageName;
final String namespace;
const HistoriquePage({Key? key,required this.pageName,required this.namespace}) : super(key: key);
@override
_HistoriquePageState createState() => _HistoriquePageState();
}
class _HistoriquePageState extends State<HistoriquePage> {
final _debounce = Debounce();
DateTimeRange? daterange;
String searchedValue = "";
Post? user;
void _sendSearch(String value) {
_debounce.run(() {
setState(() {
searchedValue = value;
});
});
}
@override
Widget build(BuildContext context) => GestureDetector(
onTap: () => FocusManager.instance.primaryFocus?.unfocus(),child: Scaffold(
appBar: AppBar(
title: Text(widget.pageName),),body: SingleChildScrollView(
child: Column(
children: [
Container(
child: DaterangeField(
enabled: true,firstDate: new DateTime(2020),helpText: 'Sélectionnez un interval de dates',fieldStartLabelText: 'Date de début',fieldEndLabelText: 'Date de fin',fieldStartHintText: 'Début',fieldEndHintText: 'Fin',dateFormat: DateFormat('dd/MM/yyyy'),saveText: 'OK',decoration: Inputdecoration(
prefixIcon: Icon(Icons.date_range,color: Theme.of(context).primaryColor),hintText: 'Sélectionnez un intervalle de dates',hintStyle: Theme.of(context).textTheme.headline6,border: OutlineInputBorder(),onChanged: (value) {
setState(() {
daterange = value!;
});
}),Container(
padding: EdgeInsets.all(16),child: TextField(
decoration: Inputdecoration(
prefixIcon: Icon(Icons.search,labelText: 'Sélectionnez le composant',labelStyle: Theme.of(context).textTheme.headline6),onChanged: _sendSearch),Container(height: MediaQuery.of(context).size.height - 150,child: ComponentsHistoriqueDeployment(searchedValue,daterange: daterange))
],));
}
以及应该重建的小部件:
class ComponentsHistoriqueDeployment extends StatefulWidget {
ComponentsHistoriqueDeployment(this.searchedValue,{this.daterange,Key? key}) : super(key: key);
final String searchedValue;
final DateTimeRange? daterange;
@override
ComponentsHistoriqueDeploymentState createState() => ComponentsHistoriqueDeploymentState();
}
class ComponentsHistoriqueDeploymentState extends State<ComponentsHistoriqueDeployment> {
List<User>? listofGroups;
@override
void initState() {
getGroupsList();
super.initState();
}
getGroupsList() async {
listofGroups = await HistoriqueService.fetchHistorique(widget.searchedValue,daterange: widget.daterange);
setState(() {
listofGroups = listofGroups;
});
}
@override
Widget build(BuildContext context) {
return listofGroups == null
? Center(child: CircularProgressIndicator())
: ListView.separated(
separatorBuilder: (BuildContext context,int index) => const Divider(),itemCount: listofGroups!.length,itemBuilder: (context,index) {
return Card(
child: Column(children: [
Padding(
padding: const EdgeInsets.only(top: 8),child: Badge(
toAnimate: true,animationDuration: Duration(seconds: 2),shape: BadgeShape.square,badgeColor: Theme.of(context).primaryColor,borderRadius: BorderRadius.circular(8),badgeContent: Text(listofGroups![index].name,style: TextStyle(color: Specific.getWhite,fontSize: 16)),_displayMoreinformationOnComponent(listofGroups,index,context)
]),);
});
}
Widget _displayMoreinformationOnComponent(result,context) {
return Container(
child: ListTile(
title: Text('Tag: ' + result[index].username),subtitle: Text('Date: ' + result[index].address.street),leading: Icon(Icons.label),trailing: Wrap(
spacing: 20,children: <Widget>[
IconButton(
icon: Icon(Icons.help),onpressed: () => Dialogs.bottomMaterialDialog(
msgStyle: TextStyle(color: Theme.of(context).textTheme.bodyText2?.color),msg: 'Tag: ' +
result[index].name +
'\nStatus: ' +
result[index].name +
'\nDernier déploiement: ' +
result[index].name +
'\nType de route: ' +
result[index].name +
'\nDernier commit par: ' +
result[index].name +
'\n',title: result[index].name,color: Specific.getorange,context: context,actions: [
IconsButton(
text: "OK",iconData: Icons.check_circle,color: Colors.green,textStyle: TextStyle(color: Specific.getWhite),iconColor: Specific.getWhite,onpressed: () {
Navigator.of(context).pop();
},]),],);
}
}
解决方法
这是预期的行为:initState()
在小部件初始化期间仅调用一次。即使属性更改了它们的值,也不会重新创建 State
对象,因此不会调用 getGroupsList()
。
在这种情况下,我建议您将 getGroupsList()
向上移动到 _HistoriquePageState
小部件,并在搜索值或日期范围更改时调用它。然后,不是将 searchedValue
和 dateRange
属性传递给 ComponentsHistoriqueDeployment
,而是传递 listOfGroups
值。
通过这种方式,您可以确保每次调用 getGroupsList()
并更新 UI。