我为此苦苦挣扎了几天,但无法弄清楚。我有一个简单的小部件,我想在其中动态添加和删除输入(对于集/代表)。问题是,如果我要删除第一个项目,那么最后一个项目将从UI中删除。
我为该应用创建了一个飞镖板:dartpad
我的main.dart:
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"),
)
],
);
}
}
问题:
答案 0 :(得分:3)
您应该将这些TextField的状态保存在地图中。
解决方案
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"),
)
],
);
}
}
顺便you should avoid using widget functions。将它们声明为类。
答案 1 :(得分:2)
您的代码存在一系列问题。首先,您使用Column
作为可能会超出视图的项目列表,而使用Column
则无法滚动。这也意味着您的Add set
按钮最终会被隐藏。对于要构建的内容,使用ListView.builder
是最合适的方法,而对于FloatingActionButton
按钮,则使用Add set
。请检查我在下面编写的代码,以获取根据您的原始代码和目的建议的实现示例:
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,
});
}
Flutter和Dart可以为您提供一些帮助,使您的生活更轻松。如果您想了解更多有关如何构建这样的可管理列表的信息,可以查看此GitHub example。