Sachu
Sachu

Reputation: 187

How to display a single property of an object in listview

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

Answers (2)

Phuc Tran
Phuc Tran

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

MickaelHrndz
MickaelHrndz

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

Related Questions