我有一个具有两个属性的目标对象列表,它们分别是描述(我要显示的内容)和ID(用作识别它的关键)。最终,我想要一个目标描述列表(例如,割草,买杂货等),但是我对如何使用listview构建器指定单个属性感到困惑。我使用对象的原因是因为我想使用滑动来关闭列表。我正在使用一个对象为每个目标赋予唯一的键,因此,当我滑动以关闭时,可以安全地撤消关闭/重新排序列表。
文件结构:lib文件夹包含功能,目标和主要内容。 lib文件夹中名为UI的子文件夹包含表单和主目录。
main.dart
import 'package:flutter/material.dart';
import 'package:aurelius/UI/home.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context){
return new MaterialApp(
debugShowCheckedModeBanner: false,
title: "ToDo",
home: myWidgets(),
);
}
}
Widget myWidgets(){
return GoalsList();
}
home.dart
import 'package:flutter/material.dart';
import 'package:aurelius/goals.dart';
import 'package:aurelius/functions.dart';
//Goals List Variables
var goals = List<Goals>();
final TextEditingController listCtrl = new TextEditingController();
class GoalsList extends StatefulWidget{
@override
_GoalsListState createState() => _GoalsListState();
}
class _GoalsListState extends State<GoalsList>{
final formKey = GlobalKey<FormState>(); //key for goal form
@override
Widget build(BuildContext context){
final listSize = MediaQuery.of(context).size.height * 1;
return Scaffold(
resizeToAvoidBottomPadding: false,
extendBody: true,
backgroundColor: Colors.black,
//Navigation Bar
floatingActionButton: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
decoration: BoxDecoration(
border: Border.all(
color: Colors.white,
),
borderRadius: BorderRadius.circular(25.0),
),
child: FloatingActionButton.extended(
elevation: 4.0,
icon: const Icon(Icons.add),
label: const Text('Add Goal'),
backgroundColor: Colors.black,
splashColor: Colors.white,
//Pop-up Dialogue
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context){
return AlertDialog(
title: Center(child: new Text("New Goal:",)),
content: Form(
key: formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
TextFormField(
decoration: InputDecoration(
border: OutlineInputBorder(borderRadius: BorderRadius.all(Radius.circular(12))),
),
controller: listCtrl,
),
RaisedButton(
child: Text("ADD"),
onPressed: (){
goals.add(createGoal(listCtrl.text));
listCtrl.clear();
Navigator.pop(context);
},
splashColor: Colors.blue,
elevation: 2,
)
]
),
)
);
}
);
},
),
),
),
floatingActionButtonLocation:FloatingActionButtonLocation.centerDocked,
//Bottom App Bar
bottomNavigationBar: BottomAppBar(
shape: CircularNotchedRectangle(),
notchMargin: -30.0,
color: Colors.black,
child: new Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(icon: Icon(Icons.person_outline),color: Colors.white,splashColor: Colors.white, onPressed: (){},),
IconButton(icon: Icon(Icons.settings),color: Colors.white,splashColor: Colors.white, onPressed: (){},),
],
),
),
//Goals List Box
body: Column(children: <Widget>[
SizedBox(height: listSize,
child: ListView.builder(
itemCount: goals.length,
itemBuilder: (context,index){
return Dismissible(
key: UniqueKey(),
//Green background and icon for left side swipe
background: Container(
color: Colors.green[300],
padding: EdgeInsets.symmetric(horizontal: 20),
alignment: AlignmentDirectional.centerStart,
child: Icon(
Icons.check_box,
color: Colors.white,
),
),
//Green background and icon for right side swipe
secondaryBackground: Container(
color: Colors.green[300],
padding: EdgeInsets.symmetric(horizontal: 20),
alignment: AlignmentDirectional.centerEnd,
child: Icon(
Icons.check_box,
color: Colors.white,
),
),
onDismissed:(direction){
if(goals.contains(index)){
setState((){
goals.removeAt(index);
});
}
},
child: Padding(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(goals[index].description),
],
),
),
);
},
),
),
//Potential more rows here
],
)
);
}
}
}
goals.dart
import 'package:flutter/material.dart';
import 'package:aurelius/UI/home.dart';
class Goals{
String description; //part visible to user
int id;
Goals({this.description,this.id});
}
functions.dart
import 'package:flutter/material.dart';
import 'package:aurelius/goals.dart';
import 'package:uuid/uuid.dart';
createGoal(String text){
var goal = new Goals();
goal.description = text;
goal.id = new DateTime.now().millisecondsSinceEpoch;
return goal;
}
form.dart
import 'package:flutter/material.dart';
class AddButton extends StatefulWidget {
@override
AddButtonState createState() => new AddButtonState();
}
class AddButtonState extends State<AddButton>{
Color addbuttoncolor = Colors.red;
IconData addIcon = Icons.add;
void onPressed(){
setState((){
if (addIcon == Icons.add) {
addIcon = Icons.clear;
}
else{
addIcon = Icons.add;
}
});
}
@override
Widget build(BuildContext context){
return Scaffold(
body: Container(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new RawMaterialButton(
onPressed: onPressed,
child: new Icon(
addIcon,
color: Colors.blue,
size: 35.0,
),
shape: new CircleBorder(),
elevation: 2.0,
fillColor: Colors.white,
padding: const EdgeInsets.all(15.0),
),
]
),
),
)
);
}
}
我认为问题在于创建目标时,您不会返回已创建的目标。您的createGoal()方法应返回如下目标:
createGoal(String text){
var goal = new Goals();
goal.description = text;
goal.id = new DateTime.now().millisecondsSinceEpoch;
return goal; // Add this
}
我看到的唯一问题是您不返回在createGoal()中创建的对象。
要显示带有Dismissible的描述,只需将其子项设置为child: Text(goals[index].description)
要优化代码,您可以直接在类本身中初始化目标ID。您可以将构造函数设置为Goals(this.description)
,并且不再需要createGoal函数。
PS:保持类名唯一是一种更好的做法