Reputation: 187
I have a list of goal objects with two properties, description (what I want to display) and ID (used as a key to identify it). Ultimately I want a list of goal descriptions (ex. mow lawn, get groceries etc) but I'm confused how to specify a single property with the listview builder. The reason I'm using an object is because I want to use swipe to dismiss on the list. I'm using an object to give each goal a unique key, therefore when I swipe to dismiss I can safely undo the dismissal / reorder the list.
File Structure: lib folder contains functions, goals and main. A sub-folder in the lib folder called UI contains form and home.
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),
),
]
),
),
)
);
}
}
Upvotes: 0
Views: 1316
Reputation: 8073
I think the problem is when you creating the goal, you don't return created goal. Your createGoal() method should return the goal like below:
createGoal(String text){
var goal = new Goals();
goal.description = text;
goal.id = new DateTime.now().millisecondsSinceEpoch;
return goal; // Add this
}
Upvotes: 1
Reputation: 3832
The only issue I see is that you don't return the object you create in createGoal().
To display the description with the Dismissible, you would just set its child to child: Text(goals[index].description)
To optimize the code, you can initialize the Goal id directly in the class itself. You can set the constructor as Goals(this.description)
and the createGoal function will not be needed anymore.
PS: Keeping your class names singular is a better practice
Upvotes: 0