在这里,我有一个修剪过的页面,它创建了一个 ReorderableListView
,它的主体设置为两个 RecipeStepWidget
与 UniqueKey
s集(我也曾尝试过用。ValueKey
和 ObjectKey
)
import 'package:flutter/material.dart';
import 'consts.dart';
import 'recipeStep.dart';
import 'recipeStepWidget.dart';
class NewRecipePage extends StatefulWidget {
@override
_NewRecipePageState createState() => _NewRecipePageState();
}
class _NewRecipePageState extends State<NewRecipePage> {
final TextEditingController _nameController = TextEditingController();
@override
Widget build(BuildContext context) {
List<RecipeStep> recipeSteps = [];
List<RecipeStepWidget> stepWidgets = [
RecipeStepWidget(key: UniqueKey()),
RecipeStepWidget(key: UniqueKey())
];
void _onReorder(int oldIndex, int newIndex) {
setState(
() {
if (newIndex > oldIndex) {
newIndex -= 1;
}
final RecipeStepWidget item = stepWidgets.removeAt(oldIndex);
stepWidgets.insert(newIndex, item);
},
);
}
return Scaffold(
appBar: AppBar(title: Text("New Recipe")),
body: Column(
children: <Widget>[
Expanded(
child: ReorderableListView(
header: Text("Steps"),
onReorder: _onReorder,
children: stepWidgets,
),
),
],
),
);
}
}
该 RecipeStepWidget
类是(忽略包括)。
class RecipeStepWidget extends StatefulWidget {
RecipeStepWidget({@required Key key}) : super(key: key);
_RecipeStepWidgetState createState() => _RecipeStepWidgetState();
}
class _RecipeStepWidgetState extends State<RecipeStepWidget> {
TextEditingController _controller = TextEditingController();
TextEditingController _durationLowController = TextEditingController();
TextEditingController _durationHighController = TextEditingController();
bool concurrent = false;
RecipeStep toRecipeStep() {
return RecipeStep(
text: _controller.text,
);
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
TextField(
controller: _controller,
decoration: InputDecoration(hintText: "Step text"),
),
Row(
children: <Widget>[
Text("Duration min: "),
Container(
width: 40.0,
//height: 100.0,
child: TextField(
controller: _durationLowController,
keyboardType: TextInputType.number,
decoration: InputDecoration(hintText: "0"),
onChanged: (String val) {
if (_durationHighController.text.isEmpty ||
int.parse(val) >
int.parse(_durationHighController.text)) {
_durationHighController.text = val;
}
},
),
),
Text(" max: "),
Container(
width: 40.0,
//height: 100.0,
child: TextField(
controller: _durationHighController,
keyboardType: TextInputType.number,
decoration: InputDecoration(hintText: "0"),
),
),
],
),
Row(
children: <Widget>[
Text("Start concurrently with previous step"),
Checkbox(
value: concurrent,
onChanged: (bool val) => {
setState(() {
concurrent = val;
})
}),
],
),
],
);
}
}
当我编辑文本字段或复选框时,我在 RecipeStateWidgets
然后通过点击+拖动它们在列表中重新排序,小部件被重置为默认状态。
有人知道为什么会发生这种情况吗?我想我所要做的只是为了得到 ReorderableListView
以达到预期的工作效果,就是在它的每个子代上设置一个键。这样做不对吗?
谢谢!
我想你可以像这样使用AutomaticKeepAliveClientMixin。
class _RecipeStepWidgetState extends State<RecipeStepWidget> with AutomaticKeepAliveClientMixin {
@override
bool get wantKeepAlive => true;