Flutter 从数组中删除特定项会删除UI中的错误项

Flutter 从数组中删除特定项会删除UI中的错误项,flutter,dart,Flutter,Dart,我为此挣扎了几天,但还是想不出来。我有一个简单的小部件,我想在其中动态添加和删除输入(对于集合/重复)。问题是,如果我要删除第一项,那么最后一项将从UI中删除 我已经为应用程序创建了一个省道板: 我的主要目标。省道: import 'package:flutter/material.dart'; final Color darkBlue = Color.fromARGB(255, 18, 32, 47); void main() { runApp(MyApp()); } class M

我为此挣扎了几天,但还是想不出来。我有一个简单的小部件,我想在其中动态添加和删除输入(对于集合/重复)。问题是,如果我要删除第一项,那么最后一项将从UI中删除

我已经为应用程序创建了一个省道板:

我的主要目标。省道:

import 'package:flutter/material.dart';

final Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return SetBuilderWidget();
  }
}

class TempSet {
  int weight;
  int rep;
  int order;

  TempSet(this.order, this.weight, this.rep);
}

class SetBuilderWidget extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _SetBuilderWidgetState();
}

class _SetBuilderWidgetState extends State<SetBuilderWidget> {
  final sets = [];
  final List<TempSet> tempSet = [];

  Widget _row(int index) {
    return Row(
      children: <Widget>[
        Text("Set $index"),
        Flexible(
          child: Padding(
            padding: const EdgeInsets.symmetric(horizontal: 40),
            child: TextField(
              decoration: InputDecoration(
                labelText: "Rep count",
              ),
            ),
          ),
        ),
        IconButton(
          icon: Icon(Icons.delete),
          onPressed: () => _removeSet(index),
        ),
      ],
    );
  }

  List<Widget> _rows() {
    return tempSet.map((s) => _row(s.order)).toList();
  }

  void _addSet() {
    if (tempSet.length == 0) {
      tempSet.add(TempSet(0, null, null));
    } else {
      final lastSet = tempSet.last;
      tempSet.add(TempSet(tempSet.indexOf(lastSet) + 1, null, null));
    }
  }

  void _removeSet(int index) {
    setState(() {
      tempSet.removeAt(index);
      _updateIndexes();
    });
  }

  void _updateIndexes() {
    tempSet.asMap().forEach((index, s) {
      s.order = index;
    });
  }

  @override
  void initState() {
    _addSet();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        ..._rows(),
        RaisedButton(
          onPressed: () {
            setState(() {
              _addSet();
            });
          },
          child: Text("Add set"),
        )
      ],
    );
  }
}
导入“包装:颤振/材料.省道”;
最终颜色深蓝色=颜色。来自argb(255,18,32,47);
void main(){
runApp(MyApp());
}
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回材料PP(
主题:ThemeData.dark().copyWith(脚手架背景颜色:深蓝色),
debugShowCheckedModeBanner:false,
家:脚手架(
正文:中(
子项:MyWidget(),
),
),
);
}
}
类MyWidget扩展了无状态Widget{
@凌驾
小部件构建(构建上下文){
返回SetBuilderWidget();
}
}
班级临时工{
整数权重;
国际代表;
整数阶;
TempSet(this.order、this.weight、this.rep);
}
类SetBuilderWidget扩展StatefulWidget{
@凌驾
State createState()=>\u SetBuilderWidgetState();
}
类_SetBuilderWidgetState扩展状态{
最终集=[];
最终列表tempSet=[];
小部件_行(整数索引){
返回行(
儿童:[
文本(“设置$index”),
灵活的(
孩子:填充(
填充:常量边集。对称(水平:40),
孩子:TextField(
装饰:输入装饰(
labelText:“代表计数”,
),
),
),
),
图标按钮(
图标:图标(Icons.delete),
按下时:()=>\u移除设置(索引),
),
],
);
}
列表_行(){
返回tempSet.map((s)=>u行(s.order)).toList();
}
void _addSet(){
如果(tempSet.length==0){
add(tempSet(0,null,null));
}否则{
最终lastSet=tempSet.last;
add(tempSet(tempSet.indexOf(lastSet)+1,null,null));
}
}
void _removeSet(整数索引){
设置状态(){
tempSet.removeAt(索引);
_更新索引();
});
}
void _updateIndexes(){
tempSet.asMap().forEach((索引,s){
s、 顺序=索引;
});
}
@凌驾
void initState(){
_addSet();
super.initState();
}
@凌驾
小部件构建(构建上下文){
返回列(
儿童:[
…_行(),
升起的按钮(
已按下:(){
设置状态(){
_addSet();
});
},
子项:文本(“添加集”),
)
],
);
}
}
问题:

import 'package:flutter/material.dart';

final Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return SetBuilderWidget();
  }
}

class TempSet {
  int weight;
  int rep;
  int order;

  TempSet(this.order, this.weight, this.rep);
}

class SetBuilderWidget extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _SetBuilderWidgetState();
}

class _SetBuilderWidgetState extends State<SetBuilderWidget> {
  final sets = [];
  final List<TempSet> tempSet = [];

  Widget _row(int index) {
    return Row(
      children: <Widget>[
        Text("Set $index"),
        Flexible(
          child: Padding(
            padding: const EdgeInsets.symmetric(horizontal: 40),
            child: TextField(
              decoration: InputDecoration(
                labelText: "Rep count",
              ),
            ),
          ),
        ),
        IconButton(
          icon: Icon(Icons.delete),
          onPressed: () => _removeSet(index),
        ),
      ],
    );
  }

  List<Widget> _rows() {
    return tempSet.map((s) => _row(s.order)).toList();
  }

  void _addSet() {
    if (tempSet.length == 0) {
      tempSet.add(TempSet(0, null, null));
    } else {
      final lastSet = tempSet.last;
      tempSet.add(TempSet(tempSet.indexOf(lastSet) + 1, null, null));
    }
  }

  void _removeSet(int index) {
    setState(() {
      tempSet.removeAt(index);
      _updateIndexes();
    });
  }

  void _updateIndexes() {
    tempSet.asMap().forEach((index, s) {
      s.order = index;
    });
  }

  @override
  void initState() {
    _addSet();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        ..._rows(),
        RaisedButton(
          onPressed: () {
            setState(() {
              _addSet();
            });
          },
          child: Text("Add set"),
        )
      ],
    );
  }
}

您的代码有一系列问题。首先,您使用
来显示可能比视图更大的项目列表,而使用
则无法滚动该列表。这也意味着您的
添加集
按钮最终可能会被隐藏。使用
ListView.builder
将是实现您想要构建的内容的最合适的方法,对于
addset
按钮,使用
FloatingActionButton
。请检查我在下面编写的代码,以了解我根据您的原始代码和目的提出的实现示例:

class MainExerciseApp extends StatefulWidget {
  @override
  _MainExerciseAppState createState() => _MainExerciseAppState();
}

class _MainExerciseAppState extends State<MainExerciseApp> {
  int currentIndex = 0;
  List<ExerciseSet> setList = [];

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: Color.fromARGB(255, 18, 32, 47)),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: SetList(
            setList: setList,
            removeSet: _removeSet,
          ),
        ),
        floatingActionButton: FloatingActionButton(
          child: Icon(Icons.add),
          onPressed: _addSet
        ),
      ),
    );
  }

  void _addSet(){
    currentIndex++;
    setState(() {
      setList.add(ExerciseSet(
        index: currentIndex,
        reps: 0
      ));
    });
  }

  void _removeSet(ExerciseSet exerciseSet){
    setState(() {
      setList.remove(exerciseSet);
    });
  }
}


class SetList extends StatefulWidget {
  final List<ExerciseSet> setList;
  final Function removeSet;

  SetList({
    @required this.setList,
    @required this.removeSet,
  });

  @override
  _SetListState createState() => _SetListState();
}

class _SetListState extends State<SetList> {
  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: widget.setList.length,
      itemBuilder: (context, index) {
        return Row(
          children: <Widget>[
            Text("Set ${widget.setList[index].index.toString()}"),
            Flexible(
              child: Padding(
                padding: const EdgeInsets.symmetric(horizontal: 40),
                child: TextFormField(
                  initialValue: widget.setList[index].reps.toString(),
                  decoration: InputDecoration(
                    labelText: "Rep count",
                  ),
                ),
              ),
            ),
            IconButton(
              icon: Icon(Icons.delete),
              onPressed: () => widget.removeSet(widget.setList[index]),
            ),
          ],
        );
      }
    );
  }
}

class ExerciseSet {
  int index;
  double weight;
  int reps;

  ExerciseSet({
    @required this.index,
    this.weight,
    this.reps,
  });
}
class MainExerciseApp扩展StatefulWidget{
@凌驾
_MainExerciseAppState createState()=>\u MainExerciseAppState();
}
类_mainPerciseAppState扩展状态{
int currentIndex=0;
列表setList=[];
@凌驾
小部件构建(构建上下文){
返回材料PP(
theme:ThemeData.dark().copyWith(scaffoldBackgroundColor:Color.fromARGB(255,18,32,47)),
debugShowCheckedModeBanner:false,
家:脚手架(
正文:中(
子:集合列表(
setList:setList,
removeSet:_removeSet,
),
),
浮动操作按钮:浮动操作按钮(
子:图标(Icons.add),
onPressed:\u addSet
),
),
);
}
void _addSet(){
currentIndex++;
设置状态(){
setList.add(ExerciseSet(
索引:当前索引,
销售代表:0
));
});
}
void _removeSet(ExerciseSet ExerciseSet){
设置状态(){
setList.remove(exerciseSet);
});
}
}
类SetList扩展了StatefulWidget{
最终列表集合列表;
最终功能移除集;
集合列表({
@需要此.setList,
@需要此.removeSet,
});
@凌驾
_SetListState createState()=>\u SetListState();
}
类_SetListState扩展了状态{
@凌驾
小部件构建(构建上下文){
返回ListView.builder(
itemCount:widget.setList.length,
itemBuilder:(上下文,索引){
返回行(
儿童:[
Text(“Set${widget.setList[index].index.toString()}”),
灵活的(
孩子:填充(
填充:常量边集。对称(水平:40),
子项:TextFormField(
initialValue:widget.setList[index].reps.toString(),
装饰:输入装饰(
labelText:“代表计数”,
),
),
),
),
图标按钮(
图标:图标(Icons.delete),
onPressed:()=>widget.removeSet(widget.setList[index]),
),
],
);
}
);
}
}
类练习集{
整数指数;
双倍重量;
杰出代表;
练习集({
@需要这个索引,
这个重量,
这个,代表,,
});
}

有些事情会让你的生活变得更轻松。如果您想进一步了解如何构建这样一个可管理的列表,可以查看这个GitHub

您应该在地图中保存这些文本字段的状态

解决方案

import 'package:flutter/material.dart';

final Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return SetBuilderWidget();
  }
}

class TempSet {
  int weight;
  int rep;
  int order;

  TempSet(this.order, this.weight, this.rep);
}

class SetBuilderWidget extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _SetBuilderWidgetState();
}

class _SetBuilderWidgetState extends State<SetBuilderWidget> {
  final sets = [];
  final List<TempSet> tempSet = [];

  Widget _row(int index, int rep) {
    TextEditingController _controller =
        TextEditingController(text: rep != null ? rep.toString() : "0");

    return Row(
      children: <Widget>[
        Text("Set $index"),
        Flexible(
          child: Padding(
            padding: const EdgeInsets.symmetric(horizontal: 40),
            child: TextField(
              onChanged: (text) {
                tempSet[index].rep = num.parse(text).toInt();
                print(tempSet);
              },
              controller: _controller,
              decoration: InputDecoration(
                labelText: "Rep count",
              ),
            ),
          ),
        ),
        IconButton(
          icon: Icon(Icons.delete),
          onPressed: () => _removeSet(index),
        ),
      ],
    );
  }

  List<Widget> _rows() {
    return tempSet.map((s) => _row(s.order, s.rep)).toList();
  }

  void _addSet() {
    if (tempSet.length == 0) {
      tempSet.add(TempSet(0, null, null));
    } else {
      final lastSet = tempSet.last;
      tempSet.add(TempSet(tempSet.indexOf(lastSet) + 1, null, null));
    }
  }

  void _removeSet(int index) {
    setState(() {
      tempSet.removeAt(index);
      _updateIndexes();
    });
  }

  void _updateIndexes() {
    tempSet.asMap().forEach((index, s) {
      s.order = index;
    });
  }

  @override
  void initState() {
    _addSet();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        ..._rows(),
        RaisedButton(
          onPressed: () {
            setState(() {
              _addSet();
            });
          },
          child: Text("Add set"),
        )
      ],
    );
  }
}
导入“包装:颤振/材料.省道”;
最终颜色暗蓝色=颜色。