ReorderableListView中的StatefulWidget在重新排序列表时不会保持其状态

时间:2020-06-06 03:37:37

标签: flutter flutter-layout flutter-state

这里我有一个缩小的页面,它创建了一个ReorderableListView,其正文设置为两个RecipeStepWidget,设置了UniqueKey个(我也尝试过使用{{ 1}}和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正常工作,我要做的就是为每个孩子设置一个钥匙。那不正确吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

我认为您可以像这样使用AutomaticKeepAliveClientMixin:

class _RecipeStepWidgetState extends State<RecipeStepWidget> with AutomaticKeepAliveClientMixin  {

  @override
  bool get wantKeepAlive => true;