我从一个API获取一个列表,这个列表已经定义了一些字段。我想写一些字段并将其发送回来,所以我使用Form,并在表单下使用Consumer和Listview.separated来表示列表。在我想写的字段上,我使用textformfield。所有这些都正常工作,除了一个问题。当我点击textformfields之外的内容时,ui会再次重建,字段会取它们的初始值。是否可以使用Selector而不是Consumer来防止ui重建?
Form(
key: _calendarFormKey,
child: Consumer<CalendarViewProvider>(
builder: (context, cal, child) {
if (cal.length == 0) {
return Center(
child: Text('List is empty'),
);
} else {
textControllers.clear();
int? numOfControllers = cal.length;
for (int i = 0; i < numOfControllers; i++) {
textControllers.add(TextEditingController());
}
return ListView.separated(
separatorBuilder: (context, index) {
return SizedBox(height: 10);
},
itemCount: cal.length,
itemBuilder: (context, index) {
var _cale = cal[index];
textControllers[index].text =
'${_cale.description}';
void clearController() {
context
.read<CalendarViewProvider>()
.removeCalendar(code: _cale.code);
textControllers[index].clear();
}
addToList(String text) {
caleList.clear();
for (int i = 0; i < numOfControllers; i++) {
var _cal = cal[i];
Map<String, dynamic> caleData = {
'code': _cal.code,
'start': _cal.start,
'end': _cal.end,
'title': _cal.title,
'description': textControllers[i].text,
};
caleList.add(caleData);
}
}
return Container(
height: ScreenConfig.screenHeight * .08,
child: Row(
children: [
SizedBox(width: 3),
Text(
_cale.start?.substring(11, 16) ?? '',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.grey[600]),
),
Stack(
children: [
Image.asset(
AppImages.dietDayImg,
height:
ScreenConfig.screenHeight * .15,
width: ScreenConfig.screenWidth * .21,
),
Positioned.fill(
child: Center(
child: Text(
_cale.title?.substring(0, 1) ??
'',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 14,
),
),
),
),
],
),
SizedBox(width: 1),
SingleChildScrollView(
child: Container(
height:
ScreenConfig.screenHeight * .078,
width: ScreenConfig.screenWidth * .55,
decoration: BoxDecoration(
color: Color(0xFFd6e7ea),
borderRadius: BorderRadius.all(
Radius.circular(10),
),
),
child: Padding(
padding:
const EdgeInsets.only(left: 5),
child: TextFormField(
controller: textControllers[index],
maxLines: 20,
decoration: InputDecoration(
border: InputBorder.none,
),
onSaved: (newValue) {
addToList(
textControllers[index].text);
textControllers[index].text =
newValue!;
},
onChanged: (value) {
caleList[index]['description'] =
value;
addToList(
textControllers[index].text);
textControllers[index].text =
value;
},
),
),
),
),
IconButton(
onPressed: () {
deleteDialog();
},
icon: Icon(Icons.delete),
iconSize: 12,
color: Colors.red,
),
],
),
);
});
}
},
),
),
1条答案
按热度按时间v2g6jxz61#
由于您标记了(但没有提到)提供程序,我假设您正在使用提供程序。如果你在build方法中填充“cal”,比如:
它总是会更新。可以在initstate中填写cal。但也许你也必须这样做(这里我猜,因为我只能看到你的“表单代码”),或者它也可以工作,如果你使用“AutomaticKeepAliveClientMixin”。在这里,你必须使小部件你想保持生活状态,然后添加这样的