SlideShare a Scribd company logo
To-Do App With Flutter: Step By Step
Guide
Flutter is easy to learn and implement compared to other
programming languages. Due to its features like single
code-base, support for multiple platforms, etc., Flutter stands
out. Going further, let’s see how to build a step by step guide
to develop a ToDo App using Flutter and why you should hire
Flutter app developer.
Pre-requisites:
Have knowledge of object oriented programming languages
like Dart, Flutter, Java, etc.
Let’s get started:
Things Needed:
Here, we have used Flutter SDK and Android Studio for an
editor. Refer this guide for Flutter installation and Android
Studio setup.
Create an Application:
Create a New Project:
Step 1: In the IDE, click on the welcome window or File → New
→ Project → New Project from the main IDE window.
Step 2: Select Flutter in the menu, and click Next.
Step 3: Enter your Project name and Project location.
Step 4: If you are going to publish this app, set the company
domain.
Step 5: Click Finish.
Your newly created project will be the flutter default app.
Data Structure:
Now the first step is to create the data structure as we will
define which data structure is going to be used to store the
TODO list tasks.
Here, we will develop a class to hold the information about the
task to do so, create a file named task.dart in /lib and write the
following code:
class Task {
/
/ Class properties
Int _id;
String _name;
bool _completed;
/
/ Default constructor
Task(this._name);
/
/ Getter and setter for id getId() => this._id;
setId(id) => this._id = id;
/
/ Getter and setter for name
getName() => this._name;
setName(name) => this._name = name;
/
/ Getter and setter for completed
isCompleted() => this._completed;
setCompleted(completed) => this._completed = completed;
}
Display Tasks:
Now to display the tasks delete all the existing code from
main.dart file and replace it with the following:
The first step is to create a list of tasks. To do so write the
following code:
class TODOApp extends StatelessWidget {
/
/ Creating a list of tasks with some dummy values
final List< Task > tasks = [
Task('Do homework'),
Task('Laundry'),
Task('Finish this draft document’)
];
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'TODO app',
home: Scaffold(
appBar: AppBar(
title: Text('TODO app'),
),
/
/ Using ListView.builder to render a list of tasks
body: ListView.builder(
/
/ How many items to render
itemCount: tasks.length,
/
/ Functions that accepts an index and renders a task
itemBuilder: (context, index) {
return ListTile(
title: Text(tasks[index].getName()), );})));}}
With the above code we have one screen which will help you
to display tasks. Our next step is to develop a screen which
allows users to create tasks. Write the following code in
main.dart file:
void main() => runApp(TODOApp());
class TODOApp extends StatelessWidget {
final List< Task > tasks = [
Task('Do homework'),
Task('Laundry'),
Task('Finish this tutorial')
];
@override
Widget build(BuildContext context) {
/
/ Instead of rendering content, we define routes for different
screens
/
/ in our app
return MaterialApp(
title: 'TODO app',
initialRoute: '/',
routes: {
/
/ Screen to view tasks
'/': (context) => TODOList(tasks: tasks),
/
/ Screen to create tasks
'/create': (context) => TODOCreate(),
},
);
}
}
/
/ A new widget that will render the screen to view tasks
class TODOList extends StatelessWidget {
final List< Task > tasks;
/
/ Receiving tasks from parent widget
TODOList({@required this.tasks});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('TODO app'),
),
body: ListView.builder(
itemCount: tasks.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(tasks[index].getName()),
);
}),
/
/ Add a button to open the screen to create a new task
floatingActionButton: FloatingActionButton(
onPressed: () => Navigator.pushNamed(context, '/create'),
child: Icon(Icons.add)
),
);
}
}
/
/ A new widget to render new task creation screen
class TODOCreate extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Create a task')),
/
/ We will finish it later
body: Center(child: Text('Not yet')));
}
}
The TODOCreate class will hold the form to create tasks.
Whereas, in TODOApp class we defined routes and initialRoute
which will handle navigation logic.
Protip: Use Navigator class to navigate between routes.
To create new tasks we will create a button in the TODOList
class. Next up, on its onPressed event we will call
Navigator.pushNamed to navigate via TODOCreate. Now your
application will look like this:
Stateful Components:
To create and edit new tasks we will use stateful components.
Stateful components hold the tasks and notifies the widgets
when it updates. Rewrite the TODO class code as follows:
class TODOApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return TODO();
}}
/
/ Here we are defining a StatefulWidget
class TODO extends StatefulWidget {
/
/ Every stateful widget must override createState
@override
State< StatefulWidget > createState() {
return TODOState();
}}
/
/ This is the state for then TODO widget
class TODOState extends State< TODO > {
/
/ We define the properties for the widget in its state
final List< Task > tasks = [
Task('Do homework'),
Task('Laundry'),
Task('Finish this tutorial')
];
/
/ Now state is responsible for building the widget
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'TODO app',
initialRoute: '/',
routes: {
'/': (context) => TODOList(tasks: tasks),
'/create': (context) => TODOCreate(),
}, );}}
Next step is to create a tasks:
Creating Tasks:
Herein, TODOState will provide a callback which you will use
in TODOCreate to create a new task. Callback function passes
into another function so you can execute it later. Rewrite the
code in main.dart:
class TODO extends StatefulWidget {
@override
State< StatefulWidget > createState() {
return TODOState();
}}
class TODOState extends State< TODO > {
/
/ At this point we can remove the dummy data
final List< Task > tasks = [];
/
/ Function that modifies the state when a new task is created
void onTaskCreated(String name) {
/
/ All state modifications have to be wrapped in setState
/
/ This way Flutter knows that something has changed
setState(() {
tasks.add(Task(name));
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'TODO app',
initialRoute: '/',
routes: {
'/': (context) => TODOList(tasks: tasks),
/
/ Passing our function as a callback
'/create': (context) => TODOCreate(onCreate: onTaskCreated,),
},);}}
class TODOList extends StatelessWidget {
final List< Task > tasks;
TODOList({@required this.tasks});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('TODO app'),
),
body: ListView.builder(
itemCount: tasks.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(tasks[index].getName()),
);
}),
floatingActionButton: FloatingActionButton(
onPressed: () => Navigator.pushNamed(context, '/create'),
child: Icon(Icons.add)),);}}
class TODOCreate extends StatefulWidget {
TODOCreate({@required this.onCreate});
@override
State< StatefulWidget > createState() {
return TODOCreateState();
}}
class TODOCreateState extends State< TODOCreate > {
final TextEditingController controller = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Create a task')),
body: Center(
child: Padding(
padding: EdgeInsets.all(16),
child: TextField(
autofocus: true,
controller: controller,
decoration: InputDecoration(
labelText: 'Enter name for your task'
) ))),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.done),
onPressed: () {
widget.onCreate(controller.text);
Navigator.pop(context);
},), );}}
Compete Tasks:
Make some changes to the TODOState and TODOList classes.
Write the following code:
class TODOState extends State< TODO > {
final List< Task > tasks = [];
void onTaskCreated(String name) {
setState(() {
tasks.add(Task(name));
});
}
void onTaskToggled(Task task) {
setState(() {
task.setCompleted(!task.isCompleted());
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'TODO app',
initialRoute: '/',
routes: {
/
/ Passing the function as a callback
'/': (context) => TODOList(tasks: tasks, onToggle:
onTaskToggled),
'/create': (context) => TODOCreate(onCreate: onTaskCreated,),
},
);
}
}
class TODOList extends StatelessWidget {
final List< Task > tasks;
final onToggle;
TODOList({@required this.tasks, @required this.onToggle});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('TODO app'),
),
body: ListView.builder(
itemCount: tasks.length,
itemBuilder: (context, index) {
return CheckboxListTile(
title: Text(tasks[index].getName()),
value: tasks[index].isCompleted(),
onChanged: (_) => onToggle(tasks[index]),
);
}),
floatingActionButton: FloatingActionButton(
onPressed: () => Navigator.pushNamed(context, '/create'),
child: Icon(Icons.add)
),
);
}
}
Now your app should look like this:
Adding Firebase:
Create a new project on the Firebase console. Read the
detailed guide here to know how to develop a project. Now
configure your app using Firebase. Follow the following steps
to do so:
1) Open file < project folder >/android/build.gradle
Add the following line in dependencies:
classpath 'com.google.gms:google-services:4.3.3'
Make sure that you have google() in all the projects like
allprojects → repositories. Next step is open the file < project
folder >/android/app/build.gradle and add this line to the
bottom of the file:
apply plugin: 'com.google.gms.google-services'
Next up you need to add Firebase plugins in the Flutter, to do
so, < project folder >/pubspec.yaml and edit the folder in the
following way:
Dependencies:
Flutter:
sdk: flutter
# Add these lines:
firebase_core: ^1.4.0
firebase_auth: ^3.0.1
cloud_firestore: ^2.4.0
Install Flutter packages using command line or press Packages
in the Android Studio:
Splitting Screen in Separate File:
Currently we have all the screens and widgets in the same file
i.e. main.dart. So, we we will split it into two files; list.dart and
create.dart and add the following code respective files:
class TODOList extends StatelessWidget {
final List< Task > tasks;
final onToggle;
TODOList({@required this.tasks, @required this.onToggle});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('TODO app'),
),
body: ListView.builder(
itemCount: tasks.length,
itemBuilder: (context, index) {
return CheckboxListTile(
title: Text(tasks[index].getName()),
value: tasks[index].isCompleted(),
onChanged: (_) => onToggle(tasks[index]),
);
}),
floatingActionButton: FloatingActionButton(
onPressed: () => Navigator.pushNamed(context, '/create'),
child: Icon(Icons.add)
),
);
}
}
class TODOList extends StatelessWidget {
final List< Task> tasks;
final onToggle;
TODOList({@required this.tasks, @required this.onToggle});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('TODO app'),
),
body: ListView.builder(
itemCount: tasks.length,
itemBuilder: (context, index) {
return CheckboxListTile(
title: Text(tasks[index].getName()),
value: tasks[index].isCompleted(),
onChanged: (_) => onToggle(tasks[index]),
);
}),
floatingActionButton: FloatingActionButton(
onPressed: () => Navigator.pushNamed(context, '/create'),
child: Icon(Icons.add)
),
);
}
}
Now, the main.dart file will look like this:
void main() => runApp(TODOApp());
class TODOApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return TODO();
}
}
class TODO extends StatefulWidget {
@override
State< StatefulWidget > createState() {
return TODOState();
}
}
class TODOState extends State< TODO > {
final List< Task > tasks = [];
void onTaskCreated(String name) {
setState(() {
tasks.add(Task(name));
});
}
void onTaskToggled(Task task) {
setState(() {
task.setCompleted(!task.isCompleted());
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'TODO app',
initialRoute: '/',
routes: {
'/': (context) => TODOList(tasks: tasks, onToggle: onTaskToggled),
'/create': (context) => TODOCreate(onCreate: onTaskCreated,),
},
);
}
}
Add a Login Screen
To develop a Login screen there are three things we need to
follow:
● Add login screen
● Setup authentication of Firebase console
● Integrate login screen and Firebase API
Start with creating a login.dart file and define the TODOLogin
widget and add it into the routes in main.dart.
Now, add the following code in login.dart file:
class TODOLogin extends StatefulWidget {
/
/ Callback function that will be called on pressing the login
button
final onLogin;
TODOLogin({@required this.onLogin});
@override
State< StatefulWidget > createState() {
return LoginState();
}
}
class LoginState extends State< TODOLogin > {
final TextEditingController emailController =
TextEditingController();
final TextEditingController passwordController =
TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Please log in')
),
body: Padding(
padding: EdgeInsets.all(16),
child: Column(
children: < Widget >[
Padding(
padding: EdgeInsets.only(bottom: 16),
child: TextField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Email'
),
)
),
Padding(
padding: EdgeInsets.only(bottom: 16),
child: TextField(
obscureText: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Password'
),
)
),
RaisedButton(
onPressed: () =>
widget.onLogin(emailController.text, passwordController.text),
child: Text('LOGIN'),
color: ThemeData().primaryColor,
)
],
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
) ));}}
Main.dart file
void main() => runApp(TODOApp());
class TODOApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return TODO();
}}
class TODO extends StatefulWidget {
@override
State< StatefulWidget > createState() {
return TODOState();
}}
class TODOState extends State< TODO > {
final List< Task > tasks = [];
void onTaskCreated(String name) {
setState(() {
tasks.add(Task(name)); });}
void onTaskToggled(Task task) {
setState(() {
task.setCompleted(!task.isCompleted());
}); }
void onLogin(String email, String password) {
/
/ We will finish it later
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'TODO app',
initialRoute: '/',
routes: {
'/': (context) => TODOLogin(onLogin: onLogin),
'/list': (context) => TODOList(tasks: tasks, onToggle:
onTaskToggled),
'/create': (context) => TODOCreate(onCreate: onTaskCreated,),
}, ); }}
Now when a user logins it will send email and password to
root widget via callback. Your login screen will look something
like this:
Authenticate with Firebase:
To authenticate we will create a new class of Authentication in
auth.dart it will communicate with Firebase. TODOLogin will
call it on the login button, pass the user to TODOState and
move to the next page.
Write the following code in auth.dart file:
class Authentication {
final _firebaseAuth = FirebaseAuth.instance;
Future< FirebaseUser > login(String email, String password)
async {
try {
AuthResult result = await
_firebaseAuth.signInWithEmailAndPassword(
email: email,
password: password
);
return result.user;
} catch (e) {
return null; } }}
void main() => runApp(TODOApp());
class TODOApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return TODO();
}}
class TODO extends StatefulWidget {
@override
State< StatefulWidget > createState() {
return TODOState();
}}
class TODOState extends State< TODO > {
final List< Task > tasks = [];
final Authentication auth = new Authentication();
FirebaseUser user;
void onTaskCreated(String name) {
setState(() {
tasks.add(Task(name));
}); }
void onTaskToggled(Task task) {
setState(() {
task.setCompleted(!task.isCompleted());
}); }
void onLogin(FirebaseUser user) {
setState(() {
this.user = user;
}); }
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'TODO app',
initialRoute: '/',
routes: {
'/': (context) => TODOLogin(onLogin: onLogin),
'/list': (context) => TODOList(tasks: tasks, onToggle:
onTaskToggled),
'/create': (context) => TODOCreate(onCreate: onTaskCreated,),
},); }}
class TODOLogin extends StatefulWidget {
final onLogin;
TODOLogin({@required this.onLogin});
@override
State< StatefulWidget > createState() {
return LoginState();
}}
class LoginState extends State< TODOLogin > {
final TextEditingController emailController =
TextEditingController();
final TextEditingController passwordController =
TextEditingController();
final auth = Authentication();
void doLogin() async {
final user = await auth.login(emailController.text,
passwordController.text);
if (user != null) {
widget.onLogin(user);
Navigator.pushReplacementNamed(context, '/list');
} else {
_showAuthFailedDialog();
} }
void _showAuthFailedDialog() {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: new Text('Could not log in'),
content: new Text('Double check your credentials and try
again'),
actions: < Widget >[
new FlatButton(
child: new Text('Close'),
onPressed: () {
Navigator.of(context).pop();
}, ), ], ); }, );}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Please log in')
),
body: Padding(
padding: EdgeInsets.all(16),
child: Column(
children: < Widget >[
Padding(
padding: EdgeInsets.only(bottom: 16),
child: TextField(
controller: emailController,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Email'
),
)
),
Padding(
padding: EdgeInsets.only(bottom: 16),
child: TextField(
controller: passwordController,
obscureText: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Password'
), ) ),
RaisedButton(
/
/ Calling the doLogin function on press
onPressed: doLogin,
child: Text('LOGIN'),
color: ThemeData().primaryColor,
) ],
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
) ) ); }}
void main() => runApp(TODOApp());
class TODOApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return TODO();
}}
class TODO extends StatefulWidget {
@override
State< StatefulWidget > createState() {
return TODOState();
}}
class TODOState extends State< TODO > {
final List< Task > tasks = [];
final Authentication auth = new Authentication();
FirebaseUser user;
void onTaskCreated(String name) {
setState(() {
tasks.add(Task(name));
}); }
void onTaskToggled(Task task) {
setState(() {
task.setCompleted(!task.isCompleted());
}); }
void onLogin(FirebaseUser user) {
setState(() {
this.user = user;
}); }
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'TODO app',
initialRoute: '/',
routes: {
'/': (context) => TODOLogin(onLogin: onLogin),
'/list': (context) => TODOList(tasks: tasks, onToggle:
onTaskToggled),
'/create': (context) => TODOCreate(onCreate: onTaskCreated,),
}, ); }}
void main() => runApp(TODOApp());
class TODOApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return TODO();
}}
class TODO extends StatefulWidget {
@override
State< StatefulWidget > createState() {
return TODOState();
}}
class TODOState extends State< TODO > {
final List< Task > tasks = [];
final Authentication auth = new Authentication();
FirebaseUser user;
void onTaskCreated(String name) {
setState(() {
tasks.add(Task(name));
}); }
void onTaskToggled(Task task) {
setState(() {
task.setCompleted(!task.isCompleted());
}); }
void onLogin(FirebaseUser user) {
setState(() {
this.user = user;
});}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'TODO app',
initialRoute: '/',
routes: {
'/': (context) => TODOLogin(onLogin: onLogin),
'/list': (context) => TODOList(tasks: tasks, onToggle:
onTaskToggled),
'/create': (context) => TODOCreate(onCreate: onTaskCreated,),
}, ); }}
Setup with Authentication in Firebase Console:
To enable authentication of your application:
● Go to Firebase console → select your project → open
Authentication → click on Setup sign-in method.
● In the next screen, select email/ password and enable it.
Save Tasks to Firebase Firestore:
Turn on Firestore in the Firebase Console. Open it→ go to
database tab → create database → select start in testing mode.
We need to change TODOList to fetch data from Firestore and
update it if user completes the task:
class TODOList extends StatelessWidget {
final collection = Firestore.instance.collection('tasks');
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('TODO app'),
),
body: StreamBuilder< QuerySnapshot >(
stream: collection.snapshots(),
builder: (BuildContext context, AsyncSnapshot< QuerySnapshot
> snapshot) {
if (snapshot.hasError)
return Text('Error: ${snapshot.error}');
switch (snapshot.connectionState) {
case ConnectionState.waiting: return Text('Loading...');
default:
return ListView(
children: snapshot.data.documents.map((DocumentSnapshot
document) {
return CheckboxListTile(
title: Text(document['name']),
value: document['completed'],
onChanged: (newValue) =>
collection.document(document.documentID).updateData({'compl
eted': newValue})
);
}).toList(),
); } }, ),
floatingActionButton: FloatingActionButton(
onPressed: () => Navigator.pushNamed(context, '/create'),
child: Icon(Icons.add)
), ); }}
Next up, we will integrate TODOCreate to the Firestore:
class TODOCreate extends StatefulWidget {
@override
State< StatefulWidget > createState() {
return TODOCreateState();
}}
class TODOCreateState extends State< TODOCreate > {
final collection = Firestore.instance.collection('tasks');
final TextEditingController controller =
TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Create a task')),
body: Center(
child: Padding(
padding: EdgeInsets.all(16),
child: TextField(
autofocus: true,
controller: controller,
decoration: InputDecoration(
labelText: 'Enter name for your task'
) ) ) ),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.done),
onPressed: () async {
await collection.add({'name': controller.text, 'completed':
false});
Navigator.pop(context);
}, ), ); }}
void main() => runApp(TODOApp());
class TODOApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return TODO();
}}
class TODO extends StatefulWidget {
@override
State< StatefulWidget > createState() {
return TODOState();
}}
class TODOState extends State< TODO > {
final Authentication auth = new Authentication();
FirebaseUser user;
void onLogin(FirebaseUser user) {
setState(() {
this.user = user;
}); }
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'TODO app',
initialRoute: '/',
routes: {
'/': (context) => TODOLogin(onLogin: onLogin),
'/list': (context) => TODOList(),
'/create': (context) => TODOCreate(),
}, ); }}
Voila! Our TODO app is ready. Follow these steps to build your
first TODO app using Flutter. Apart from this, if you have an
application idea using Flutter, reach out to us. Hire flutter app
developers from us and our team will help you with turning
your ideas into a reality.
Source:
https:/
/www.biztechcs.com/blog/todo-app-flutter-step-by-
step-guide/

More Related Content

What's hot

Introduction to react native
Introduction to react nativeIntroduction to react native
Introduction to react native
Dani Akash
 
Clean backends with NestJs
Clean backends with NestJsClean backends with NestJs
Clean backends with NestJs
Aymene Bennour
 
Angular 8
Angular 8 Angular 8
Angular 8
Sunil OS
 
JavaScript & Dom Manipulation
JavaScript & Dom ManipulationJavaScript & Dom Manipulation
JavaScript & Dom Manipulation
Mohammed Arif
 
CSS
CSSCSS
Retrofit
RetrofitRetrofit
Retrofit
Amin Cheloh
 
Javascript
JavascriptJavascript
Javascript
Mayank Bhatt
 
RxJS Operators - Real World Use Cases (FULL VERSION)
RxJS Operators - Real World Use Cases (FULL VERSION)RxJS Operators - Real World Use Cases (FULL VERSION)
RxJS Operators - Real World Use Cases (FULL VERSION)
Tracy Lee
 
Jquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript BasicsJquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript Basics
EPAM Systems
 
CSS3 2D/3D transform
CSS3 2D/3D transformCSS3 2D/3D transform
CSS3 2D/3D transformKenny Lee
 
Nodejs functions & modules
Nodejs functions & modulesNodejs functions & modules
Nodejs functions & modules
monikadeshmane
 
Understanding react hooks
Understanding react hooksUnderstanding react hooks
Understanding react hooks
Samundra khatri
 
Cascading Style Sheets (CSS) help
Cascading Style Sheets (CSS) helpCascading Style Sheets (CSS) help
Cascading Style Sheets (CSS) help
casestudyhelp
 
소프트웨어 개선 그룹(Sig) 개발 원칙
소프트웨어 개선 그룹(Sig) 개발 원칙소프트웨어 개선 그룹(Sig) 개발 원칙
소프트웨어 개선 그룹(Sig) 개발 원칙
Hong Hyo Sang
 
React Hooks
React HooksReact Hooks
React Hooks
Erez Cohen
 
React native
React nativeReact native
React Native Workshop
React Native WorkshopReact Native Workshop
React Native Workshop
Amazon Web Services
 
Declarative UIs with Jetpack Compose
Declarative UIs with Jetpack ComposeDeclarative UIs with Jetpack Compose
Declarative UIs with Jetpack Compose
Ramon Ribeiro Rabello
 
Angular tutorial
Angular tutorialAngular tutorial
Angular tutorial
Rohit Gupta
 
Introduction to Cascading Style Sheets (CSS)
Introduction to Cascading Style Sheets (CSS)Introduction to Cascading Style Sheets (CSS)
Introduction to Cascading Style Sheets (CSS)
Chris Poteet
 

What's hot (20)

Introduction to react native
Introduction to react nativeIntroduction to react native
Introduction to react native
 
Clean backends with NestJs
Clean backends with NestJsClean backends with NestJs
Clean backends with NestJs
 
Angular 8
Angular 8 Angular 8
Angular 8
 
JavaScript & Dom Manipulation
JavaScript & Dom ManipulationJavaScript & Dom Manipulation
JavaScript & Dom Manipulation
 
CSS
CSSCSS
CSS
 
Retrofit
RetrofitRetrofit
Retrofit
 
Javascript
JavascriptJavascript
Javascript
 
RxJS Operators - Real World Use Cases (FULL VERSION)
RxJS Operators - Real World Use Cases (FULL VERSION)RxJS Operators - Real World Use Cases (FULL VERSION)
RxJS Operators - Real World Use Cases (FULL VERSION)
 
Jquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript BasicsJquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript Basics
 
CSS3 2D/3D transform
CSS3 2D/3D transformCSS3 2D/3D transform
CSS3 2D/3D transform
 
Nodejs functions & modules
Nodejs functions & modulesNodejs functions & modules
Nodejs functions & modules
 
Understanding react hooks
Understanding react hooksUnderstanding react hooks
Understanding react hooks
 
Cascading Style Sheets (CSS) help
Cascading Style Sheets (CSS) helpCascading Style Sheets (CSS) help
Cascading Style Sheets (CSS) help
 
소프트웨어 개선 그룹(Sig) 개발 원칙
소프트웨어 개선 그룹(Sig) 개발 원칙소프트웨어 개선 그룹(Sig) 개발 원칙
소프트웨어 개선 그룹(Sig) 개발 원칙
 
React Hooks
React HooksReact Hooks
React Hooks
 
React native
React nativeReact native
React native
 
React Native Workshop
React Native WorkshopReact Native Workshop
React Native Workshop
 
Declarative UIs with Jetpack Compose
Declarative UIs with Jetpack ComposeDeclarative UIs with Jetpack Compose
Declarative UIs with Jetpack Compose
 
Angular tutorial
Angular tutorialAngular tutorial
Angular tutorial
 
Introduction to Cascading Style Sheets (CSS)
Introduction to Cascading Style Sheets (CSS)Introduction to Cascading Style Sheets (CSS)
Introduction to Cascading Style Sheets (CSS)
 

Similar to To-Do App With Flutter: Step By Step Guide

How to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescriptHow to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescript
Katy Slemon
 
Reactive.architecture.with.Angular
Reactive.architecture.with.AngularReactive.architecture.with.Angular
Reactive.architecture.with.AngularEvan Schultz
 
Introduction To Google Android (Ft Rohan Bomle)
Introduction To Google Android (Ft Rohan Bomle)Introduction To Google Android (Ft Rohan Bomle)
Introduction To Google Android (Ft Rohan Bomle)
Fafadia Tech
 
React outbox
React outboxReact outbox
React outbox
Angela Lehru
 
Gwt and Xtend
Gwt and XtendGwt and Xtend
Gwt and Xtend
Sven Efftinge
 
React redux
React reduxReact redux
React redux
Michel Perez
 
Play!ng with scala
Play!ng with scalaPlay!ng with scala
Play!ng with scala
Siarzh Miadzvedzeu
 
Building user interface with react
Building user interface with reactBuilding user interface with react
Building user interface with react
Amit Thakkar
 
Simple React Todo List
Simple React Todo ListSimple React Todo List
Simple React Todo List
Ritesh Chaudhari
 
SharePoint Conference 2018 - APIs, APIs everywhere!
SharePoint Conference 2018 - APIs, APIs everywhere!SharePoint Conference 2018 - APIs, APIs everywhere!
SharePoint Conference 2018 - APIs, APIs everywhere!
Sébastien Levert
 
Task scheduling in laravel 8 tutorial
Task scheduling in laravel 8 tutorialTask scheduling in laravel 8 tutorial
Task scheduling in laravel 8 tutorial
Katy Slemon
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScript
Andrew Dupont
 
React lecture
React lectureReact lecture
React lecture
Christoffer Noring
 
Using prime[31] to connect your unity game to azure mobile services
Using prime[31] to connect your unity game to azure mobile servicesUsing prime[31] to connect your unity game to azure mobile services
Using prime[31] to connect your unity game to azure mobile services
David Voyles
 
The evolution of redux action creators
The evolution of redux action creatorsThe evolution of redux action creators
The evolution of redux action creators
George Bukhanov
 
Dojo and Adobe AIR
Dojo and Adobe AIRDojo and Adobe AIR
Dojo and Adobe AIR
Nikolai Onken
 
Android classes in mumbai
Android classes in mumbaiAndroid classes in mumbai
Android classes in mumbai
Vibrant Technologies & Computers
 
Intro to React | DreamLab Academy
Intro to React | DreamLab AcademyIntro to React | DreamLab Academy
Intro to React | DreamLab Academy
DreamLab
 

Similar to To-Do App With Flutter: Step By Step Guide (20)

How to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescriptHow to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescript
 
Reactive.architecture.with.Angular
Reactive.architecture.with.AngularReactive.architecture.with.Angular
Reactive.architecture.with.Angular
 
Introduction To Google Android (Ft Rohan Bomle)
Introduction To Google Android (Ft Rohan Bomle)Introduction To Google Android (Ft Rohan Bomle)
Introduction To Google Android (Ft Rohan Bomle)
 
React outbox
React outboxReact outbox
React outbox
 
Gwt and Xtend
Gwt and XtendGwt and Xtend
Gwt and Xtend
 
Extend sdk
Extend sdkExtend sdk
Extend sdk
 
React redux
React reduxReact redux
React redux
 
Play!ng with scala
Play!ng with scalaPlay!ng with scala
Play!ng with scala
 
Building user interface with react
Building user interface with reactBuilding user interface with react
Building user interface with react
 
Simple React Todo List
Simple React Todo ListSimple React Todo List
Simple React Todo List
 
SharePoint Conference 2018 - APIs, APIs everywhere!
SharePoint Conference 2018 - APIs, APIs everywhere!SharePoint Conference 2018 - APIs, APIs everywhere!
SharePoint Conference 2018 - APIs, APIs everywhere!
 
Task scheduling in laravel 8 tutorial
Task scheduling in laravel 8 tutorialTask scheduling in laravel 8 tutorial
Task scheduling in laravel 8 tutorial
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScript
 
React lecture
React lectureReact lecture
React lecture
 
Dartprogramming
DartprogrammingDartprogramming
Dartprogramming
 
Using prime[31] to connect your unity game to azure mobile services
Using prime[31] to connect your unity game to azure mobile servicesUsing prime[31] to connect your unity game to azure mobile services
Using prime[31] to connect your unity game to azure mobile services
 
The evolution of redux action creators
The evolution of redux action creatorsThe evolution of redux action creators
The evolution of redux action creators
 
Dojo and Adobe AIR
Dojo and Adobe AIRDojo and Adobe AIR
Dojo and Adobe AIR
 
Android classes in mumbai
Android classes in mumbaiAndroid classes in mumbai
Android classes in mumbai
 
Intro to React | DreamLab Academy
Intro to React | DreamLab AcademyIntro to React | DreamLab Academy
Intro to React | DreamLab Academy
 

More from Biztech Consulting & Solutions

Best Web Development Frameworks.pptx
Best Web Development Frameworks.pptxBest Web Development Frameworks.pptx
Best Web Development Frameworks.pptx
Biztech Consulting & Solutions
 
Why Use Salesforce for Insurance Companies.pdf
Why Use Salesforce for Insurance Companies.pdfWhy Use Salesforce for Insurance Companies.pdf
Why Use Salesforce for Insurance Companies.pdf
Biztech Consulting & Solutions
 
Laravel Forge: An Easy Way Out for App Deployment.pdf
Laravel Forge: An Easy Way Out for App Deployment.pdfLaravel Forge: An Easy Way Out for App Deployment.pdf
Laravel Forge: An Easy Way Out for App Deployment.pdf
Biztech Consulting & Solutions
 
WhatsApp Salesforce Partnership How Businesses Can Benefit from This.pptx
WhatsApp Salesforce Partnership How Businesses Can Benefit from This.pptxWhatsApp Salesforce Partnership How Businesses Can Benefit from This.pptx
WhatsApp Salesforce Partnership How Businesses Can Benefit from This.pptx
Biztech Consulting & Solutions
 
Python 3.9 Everything you Need to Know.pptx
Python 3.9 Everything you Need to Know.pptxPython 3.9 Everything you Need to Know.pptx
Python 3.9 Everything you Need to Know.pptx
Biztech Consulting & Solutions
 
Salesforce for Real Estate: How it is Transforming the Industry for Good.pdf
Salesforce for Real Estate: How it is Transforming the Industry for Good.pdfSalesforce for Real Estate: How it is Transforming the Industry for Good.pdf
Salesforce for Real Estate: How it is Transforming the Industry for Good.pdf
Biztech Consulting & Solutions
 
Odoo 16 Update : A Guide To know All Features of Odoo Upgrade.pptx
Odoo 16 Update : A Guide To know All Features of Odoo Upgrade.pptxOdoo 16 Update : A Guide To know All Features of Odoo Upgrade.pptx
Odoo 16 Update : A Guide To know All Features of Odoo Upgrade.pptx
Biztech Consulting & Solutions
 
Microservices: Detailed Guide
Microservices: Detailed GuideMicroservices: Detailed Guide
Microservices: Detailed Guide
Biztech Consulting & Solutions
 
12 best programming languages for web &amp; app development
12 best programming languages for web &amp; app development12 best programming languages for web &amp; app development
12 best programming languages for web &amp; app development
Biztech Consulting & Solutions
 
Cross platform app development a complete guide
Cross platform app development a complete guideCross platform app development a complete guide
Cross platform app development a complete guide
Biztech Consulting & Solutions
 
Complete guide on mobile app maintenance
Complete guide on mobile app maintenanceComplete guide on mobile app maintenance
Complete guide on mobile app maintenance
Biztech Consulting & Solutions
 
Everything you need to know about flutter 2.2
Everything you need to know about flutter 2.2Everything you need to know about flutter 2.2
Everything you need to know about flutter 2.2
Biztech Consulting & Solutions
 
11 reasons why flutter is better for app development
11 reasons why flutter is better for app development11 reasons why flutter is better for app development
11 reasons why flutter is better for app development
Biztech Consulting & Solutions
 
Augmented reality in retail beginning of an immersive era
Augmented reality in retail beginning of an immersive eraAugmented reality in retail beginning of an immersive era
Augmented reality in retail beginning of an immersive era
Biztech Consulting & Solutions
 
Challenges of adopting ar in education
Challenges of adopting ar in educationChallenges of adopting ar in education
Challenges of adopting ar in education
Biztech Consulting & Solutions
 
Why you should choose a custom app over a clone app
Why you should choose a custom app over a clone app Why you should choose a custom app over a clone app
Why you should choose a custom app over a clone app
Biztech Consulting & Solutions
 
Magento e commerce development trends for 2020
Magento e commerce development trends for 2020Magento e commerce development trends for 2020
Magento e commerce development trends for 2020
Biztech Consulting & Solutions
 
9 reasons why angular js web development should be your choice in 2020
9 reasons why angular js web development should be your choice in 20209 reasons why angular js web development should be your choice in 2020
9 reasons why angular js web development should be your choice in 2020
Biztech Consulting & Solutions
 
SugarCRM Brochure - Biztech Consultancy
SugarCRM Brochure - Biztech ConsultancySugarCRM Brochure - Biztech Consultancy
SugarCRM Brochure - Biztech Consultancy
Biztech Consulting & Solutions
 
CakePHP Brochure - Biztech Consultancy
CakePHP Brochure - Biztech ConsultancyCakePHP Brochure - Biztech Consultancy
CakePHP Brochure - Biztech Consultancy
Biztech Consulting & Solutions
 

More from Biztech Consulting & Solutions (20)

Best Web Development Frameworks.pptx
Best Web Development Frameworks.pptxBest Web Development Frameworks.pptx
Best Web Development Frameworks.pptx
 
Why Use Salesforce for Insurance Companies.pdf
Why Use Salesforce for Insurance Companies.pdfWhy Use Salesforce for Insurance Companies.pdf
Why Use Salesforce for Insurance Companies.pdf
 
Laravel Forge: An Easy Way Out for App Deployment.pdf
Laravel Forge: An Easy Way Out for App Deployment.pdfLaravel Forge: An Easy Way Out for App Deployment.pdf
Laravel Forge: An Easy Way Out for App Deployment.pdf
 
WhatsApp Salesforce Partnership How Businesses Can Benefit from This.pptx
WhatsApp Salesforce Partnership How Businesses Can Benefit from This.pptxWhatsApp Salesforce Partnership How Businesses Can Benefit from This.pptx
WhatsApp Salesforce Partnership How Businesses Can Benefit from This.pptx
 
Python 3.9 Everything you Need to Know.pptx
Python 3.9 Everything you Need to Know.pptxPython 3.9 Everything you Need to Know.pptx
Python 3.9 Everything you Need to Know.pptx
 
Salesforce for Real Estate: How it is Transforming the Industry for Good.pdf
Salesforce for Real Estate: How it is Transforming the Industry for Good.pdfSalesforce for Real Estate: How it is Transforming the Industry for Good.pdf
Salesforce for Real Estate: How it is Transforming the Industry for Good.pdf
 
Odoo 16 Update : A Guide To know All Features of Odoo Upgrade.pptx
Odoo 16 Update : A Guide To know All Features of Odoo Upgrade.pptxOdoo 16 Update : A Guide To know All Features of Odoo Upgrade.pptx
Odoo 16 Update : A Guide To know All Features of Odoo Upgrade.pptx
 
Microservices: Detailed Guide
Microservices: Detailed GuideMicroservices: Detailed Guide
Microservices: Detailed Guide
 
12 best programming languages for web &amp; app development
12 best programming languages for web &amp; app development12 best programming languages for web &amp; app development
12 best programming languages for web &amp; app development
 
Cross platform app development a complete guide
Cross platform app development a complete guideCross platform app development a complete guide
Cross platform app development a complete guide
 
Complete guide on mobile app maintenance
Complete guide on mobile app maintenanceComplete guide on mobile app maintenance
Complete guide on mobile app maintenance
 
Everything you need to know about flutter 2.2
Everything you need to know about flutter 2.2Everything you need to know about flutter 2.2
Everything you need to know about flutter 2.2
 
11 reasons why flutter is better for app development
11 reasons why flutter is better for app development11 reasons why flutter is better for app development
11 reasons why flutter is better for app development
 
Augmented reality in retail beginning of an immersive era
Augmented reality in retail beginning of an immersive eraAugmented reality in retail beginning of an immersive era
Augmented reality in retail beginning of an immersive era
 
Challenges of adopting ar in education
Challenges of adopting ar in educationChallenges of adopting ar in education
Challenges of adopting ar in education
 
Why you should choose a custom app over a clone app
Why you should choose a custom app over a clone app Why you should choose a custom app over a clone app
Why you should choose a custom app over a clone app
 
Magento e commerce development trends for 2020
Magento e commerce development trends for 2020Magento e commerce development trends for 2020
Magento e commerce development trends for 2020
 
9 reasons why angular js web development should be your choice in 2020
9 reasons why angular js web development should be your choice in 20209 reasons why angular js web development should be your choice in 2020
9 reasons why angular js web development should be your choice in 2020
 
SugarCRM Brochure - Biztech Consultancy
SugarCRM Brochure - Biztech ConsultancySugarCRM Brochure - Biztech Consultancy
SugarCRM Brochure - Biztech Consultancy
 
CakePHP Brochure - Biztech Consultancy
CakePHP Brochure - Biztech ConsultancyCakePHP Brochure - Biztech Consultancy
CakePHP Brochure - Biztech Consultancy
 

Recently uploaded

Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
Fermin Galan
 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
Tier1 app
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
Philip Schwarz
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
Globus
 
How Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptxHow Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptx
wottaspaceseo
 
Graphic Design Crash Course for beginners
Graphic Design Crash Course for beginnersGraphic Design Crash Course for beginners
Graphic Design Crash Course for beginners
e20449
 
2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx
Georgi Kodinov
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
NYGGS Automation Suite
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
rickgrimesss22
 
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdfDominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
AMB-Review
 
Accelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessAccelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with Platformless
WSO2
 
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Shahin Sheidaei
 
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Mind IT Systems
 
A Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdfA Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdf
kalichargn70th171
 
Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus
 
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns
 
Into the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfInto the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdf
Ortus Solutions, Corp
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
Juraj Vysvader
 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdf
Cyanic lab
 
RISE with SAP and Journey to the Intelligent Enterprise
RISE with SAP and Journey to the Intelligent EnterpriseRISE with SAP and Journey to the Intelligent Enterprise
RISE with SAP and Journey to the Intelligent Enterprise
Srikant77
 

Recently uploaded (20)

Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
 
How Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptxHow Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptx
 
Graphic Design Crash Course for beginners
Graphic Design Crash Course for beginnersGraphic Design Crash Course for beginners
Graphic Design Crash Course for beginners
 
2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
 
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdfDominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
 
Accelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessAccelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with Platformless
 
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
 
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
 
A Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdfA Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdf
 
Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024
 
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology Solutions
 
Into the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfInto the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdf
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdf
 
RISE with SAP and Journey to the Intelligent Enterprise
RISE with SAP and Journey to the Intelligent EnterpriseRISE with SAP and Journey to the Intelligent Enterprise
RISE with SAP and Journey to the Intelligent Enterprise
 

To-Do App With Flutter: Step By Step Guide

  • 1. To-Do App With Flutter: Step By Step Guide Flutter is easy to learn and implement compared to other programming languages. Due to its features like single code-base, support for multiple platforms, etc., Flutter stands out. Going further, let’s see how to build a step by step guide to develop a ToDo App using Flutter and why you should hire Flutter app developer. Pre-requisites: Have knowledge of object oriented programming languages like Dart, Flutter, Java, etc. Let’s get started: Things Needed: Here, we have used Flutter SDK and Android Studio for an editor. Refer this guide for Flutter installation and Android Studio setup. Create an Application: Create a New Project:
  • 2. Step 1: In the IDE, click on the welcome window or File → New → Project → New Project from the main IDE window. Step 2: Select Flutter in the menu, and click Next. Step 3: Enter your Project name and Project location. Step 4: If you are going to publish this app, set the company domain. Step 5: Click Finish. Your newly created project will be the flutter default app. Data Structure: Now the first step is to create the data structure as we will define which data structure is going to be used to store the TODO list tasks. Here, we will develop a class to hold the information about the task to do so, create a file named task.dart in /lib and write the following code: class Task {
  • 3. / / Class properties Int _id; String _name; bool _completed; / / Default constructor Task(this._name); / / Getter and setter for id getId() => this._id; setId(id) => this._id = id; / / Getter and setter for name getName() => this._name; setName(name) => this._name = name; / / Getter and setter for completed isCompleted() => this._completed; setCompleted(completed) => this._completed = completed; }
  • 4. Display Tasks: Now to display the tasks delete all the existing code from main.dart file and replace it with the following: The first step is to create a list of tasks. To do so write the following code: class TODOApp extends StatelessWidget { / / Creating a list of tasks with some dummy values final List< Task > tasks = [ Task('Do homework'), Task('Laundry'), Task('Finish this draft document’) ]; @override Widget build(BuildContext context) { return MaterialApp( title: 'TODO app',
  • 5. home: Scaffold( appBar: AppBar( title: Text('TODO app'), ), / / Using ListView.builder to render a list of tasks body: ListView.builder( / / How many items to render itemCount: tasks.length, / / Functions that accepts an index and renders a task itemBuilder: (context, index) { return ListTile( title: Text(tasks[index].getName()), );})));}} With the above code we have one screen which will help you to display tasks. Our next step is to develop a screen which allows users to create tasks. Write the following code in main.dart file:
  • 6. void main() => runApp(TODOApp()); class TODOApp extends StatelessWidget { final List< Task > tasks = [ Task('Do homework'), Task('Laundry'), Task('Finish this tutorial') ]; @override Widget build(BuildContext context) { / / Instead of rendering content, we define routes for different screens / / in our app return MaterialApp( title: 'TODO app', initialRoute: '/', routes: {
  • 7. / / Screen to view tasks '/': (context) => TODOList(tasks: tasks), / / Screen to create tasks '/create': (context) => TODOCreate(), }, ); } } / / A new widget that will render the screen to view tasks class TODOList extends StatelessWidget { final List< Task > tasks; / / Receiving tasks from parent widget TODOList({@required this.tasks}); @override Widget build(BuildContext context) {
  • 8. return Scaffold( appBar: AppBar( title: Text('TODO app'), ), body: ListView.builder( itemCount: tasks.length, itemBuilder: (context, index) { return ListTile( title: Text(tasks[index].getName()), ); }), / / Add a button to open the screen to create a new task floatingActionButton: FloatingActionButton( onPressed: () => Navigator.pushNamed(context, '/create'), child: Icon(Icons.add)
  • 9. ), ); } } / / A new widget to render new task creation screen class TODOCreate extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Create a task')), / / We will finish it later body: Center(child: Text('Not yet'))); } }
  • 10. The TODOCreate class will hold the form to create tasks. Whereas, in TODOApp class we defined routes and initialRoute which will handle navigation logic. Protip: Use Navigator class to navigate between routes. To create new tasks we will create a button in the TODOList class. Next up, on its onPressed event we will call Navigator.pushNamed to navigate via TODOCreate. Now your application will look like this:
  • 11. Stateful Components: To create and edit new tasks we will use stateful components. Stateful components hold the tasks and notifies the widgets when it updates. Rewrite the TODO class code as follows: class TODOApp extends StatelessWidget { @override Widget build(BuildContext context) { return TODO(); }} / / Here we are defining a StatefulWidget class TODO extends StatefulWidget { / / Every stateful widget must override createState @override State< StatefulWidget > createState() { return TODOState(); }}
  • 12. / / This is the state for then TODO widget class TODOState extends State< TODO > { / / We define the properties for the widget in its state final List< Task > tasks = [ Task('Do homework'), Task('Laundry'), Task('Finish this tutorial') ]; / / Now state is responsible for building the widget @override Widget build(BuildContext context) { return MaterialApp( title: 'TODO app', initialRoute: '/', routes: {
  • 13. '/': (context) => TODOList(tasks: tasks), '/create': (context) => TODOCreate(), }, );}} Next step is to create a tasks: Creating Tasks: Herein, TODOState will provide a callback which you will use in TODOCreate to create a new task. Callback function passes into another function so you can execute it later. Rewrite the code in main.dart: class TODO extends StatefulWidget { @override State< StatefulWidget > createState() { return TODOState(); }} class TODOState extends State< TODO > { / / At this point we can remove the dummy data
  • 14. final List< Task > tasks = []; / / Function that modifies the state when a new task is created void onTaskCreated(String name) { / / All state modifications have to be wrapped in setState / / This way Flutter knows that something has changed setState(() { tasks.add(Task(name)); }); } @override Widget build(BuildContext context) { return MaterialApp( title: 'TODO app', initialRoute: '/', routes: {
  • 15. '/': (context) => TODOList(tasks: tasks), / / Passing our function as a callback '/create': (context) => TODOCreate(onCreate: onTaskCreated,), },);}} class TODOList extends StatelessWidget { final List< Task > tasks; TODOList({@required this.tasks}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('TODO app'), ), body: ListView.builder( itemCount: tasks.length,
  • 16. itemBuilder: (context, index) { return ListTile( title: Text(tasks[index].getName()), ); }), floatingActionButton: FloatingActionButton( onPressed: () => Navigator.pushNamed(context, '/create'), child: Icon(Icons.add)),);}} class TODOCreate extends StatefulWidget { TODOCreate({@required this.onCreate}); @override State< StatefulWidget > createState() { return TODOCreateState(); }} class TODOCreateState extends State< TODOCreate > {
  • 17. final TextEditingController controller = TextEditingController(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Create a task')), body: Center( child: Padding( padding: EdgeInsets.all(16), child: TextField( autofocus: true, controller: controller, decoration: InputDecoration( labelText: 'Enter name for your task' ) ))), floatingActionButton: FloatingActionButton(
  • 18. child: Icon(Icons.done), onPressed: () { widget.onCreate(controller.text); Navigator.pop(context); },), );}} Compete Tasks: Make some changes to the TODOState and TODOList classes. Write the following code: class TODOState extends State< TODO > { final List< Task > tasks = []; void onTaskCreated(String name) { setState(() { tasks.add(Task(name)); }); }
  • 19. void onTaskToggled(Task task) { setState(() { task.setCompleted(!task.isCompleted()); }); } @override Widget build(BuildContext context) { return MaterialApp( title: 'TODO app', initialRoute: '/', routes: { / / Passing the function as a callback '/': (context) => TODOList(tasks: tasks, onToggle: onTaskToggled), '/create': (context) => TODOCreate(onCreate: onTaskCreated,), },
  • 20. ); } } class TODOList extends StatelessWidget { final List< Task > tasks; final onToggle; TODOList({@required this.tasks, @required this.onToggle}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('TODO app'), ), body: ListView.builder( itemCount: tasks.length,
  • 21. itemBuilder: (context, index) { return CheckboxListTile( title: Text(tasks[index].getName()), value: tasks[index].isCompleted(), onChanged: (_) => onToggle(tasks[index]), ); }), floatingActionButton: FloatingActionButton( onPressed: () => Navigator.pushNamed(context, '/create'), child: Icon(Icons.add) ), ); } } Now your app should look like this:
  • 22. Adding Firebase: Create a new project on the Firebase console. Read the detailed guide here to know how to develop a project. Now configure your app using Firebase. Follow the following steps to do so: 1) Open file < project folder >/android/build.gradle Add the following line in dependencies: classpath 'com.google.gms:google-services:4.3.3'
  • 23. Make sure that you have google() in all the projects like allprojects → repositories. Next step is open the file < project folder >/android/app/build.gradle and add this line to the bottom of the file: apply plugin: 'com.google.gms.google-services' Next up you need to add Firebase plugins in the Flutter, to do so, < project folder >/pubspec.yaml and edit the folder in the following way: Dependencies: Flutter: sdk: flutter # Add these lines: firebase_core: ^1.4.0 firebase_auth: ^3.0.1 cloud_firestore: ^2.4.0 Install Flutter packages using command line or press Packages in the Android Studio:
  • 24. Splitting Screen in Separate File: Currently we have all the screens and widgets in the same file i.e. main.dart. So, we we will split it into two files; list.dart and create.dart and add the following code respective files: class TODOList extends StatelessWidget { final List< Task > tasks; final onToggle; TODOList({@required this.tasks, @required this.onToggle}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('TODO app'), ), body: ListView.builder( itemCount: tasks.length,
  • 25. itemBuilder: (context, index) { return CheckboxListTile( title: Text(tasks[index].getName()), value: tasks[index].isCompleted(), onChanged: (_) => onToggle(tasks[index]), ); }), floatingActionButton: FloatingActionButton( onPressed: () => Navigator.pushNamed(context, '/create'), child: Icon(Icons.add) ), ); } } class TODOList extends StatelessWidget {
  • 26. final List< Task> tasks; final onToggle; TODOList({@required this.tasks, @required this.onToggle}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('TODO app'), ), body: ListView.builder( itemCount: tasks.length, itemBuilder: (context, index) { return CheckboxListTile( title: Text(tasks[index].getName()), value: tasks[index].isCompleted(),
  • 27. onChanged: (_) => onToggle(tasks[index]), ); }), floatingActionButton: FloatingActionButton( onPressed: () => Navigator.pushNamed(context, '/create'), child: Icon(Icons.add) ), ); } } Now, the main.dart file will look like this: void main() => runApp(TODOApp()); class TODOApp extends StatelessWidget { @override Widget build(BuildContext context) {
  • 28. return TODO(); } } class TODO extends StatefulWidget { @override State< StatefulWidget > createState() { return TODOState(); } } class TODOState extends State< TODO > { final List< Task > tasks = []; void onTaskCreated(String name) { setState(() { tasks.add(Task(name)); });
  • 29. } void onTaskToggled(Task task) { setState(() { task.setCompleted(!task.isCompleted()); }); } @override Widget build(BuildContext context) { return MaterialApp( title: 'TODO app', initialRoute: '/', routes: { '/': (context) => TODOList(tasks: tasks, onToggle: onTaskToggled), '/create': (context) => TODOCreate(onCreate: onTaskCreated,), },
  • 30. ); } } Add a Login Screen To develop a Login screen there are three things we need to follow: ● Add login screen ● Setup authentication of Firebase console ● Integrate login screen and Firebase API Start with creating a login.dart file and define the TODOLogin widget and add it into the routes in main.dart. Now, add the following code in login.dart file: class TODOLogin extends StatefulWidget { / / Callback function that will be called on pressing the login button final onLogin;
  • 31. TODOLogin({@required this.onLogin}); @override State< StatefulWidget > createState() { return LoginState(); } } class LoginState extends State< TODOLogin > { final TextEditingController emailController = TextEditingController(); final TextEditingController passwordController = TextEditingController(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Please log in')
  • 32. ), body: Padding( padding: EdgeInsets.all(16), child: Column( children: < Widget >[ Padding( padding: EdgeInsets.only(bottom: 16), child: TextField( decoration: InputDecoration( border: OutlineInputBorder(), labelText: 'Email' ), ) ), Padding(
  • 33. padding: EdgeInsets.only(bottom: 16), child: TextField( obscureText: true, decoration: InputDecoration( border: OutlineInputBorder(), labelText: 'Password' ), ) ), RaisedButton( onPressed: () => widget.onLogin(emailController.text, passwordController.text), child: Text('LOGIN'), color: ThemeData().primaryColor, )
  • 34. ], mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.end, ) ));}} Main.dart file void main() => runApp(TODOApp()); class TODOApp extends StatelessWidget { @override Widget build(BuildContext context) { return TODO(); }} class TODO extends StatefulWidget { @override State< StatefulWidget > createState() { return TODOState();
  • 35. }} class TODOState extends State< TODO > { final List< Task > tasks = []; void onTaskCreated(String name) { setState(() { tasks.add(Task(name)); });} void onTaskToggled(Task task) { setState(() { task.setCompleted(!task.isCompleted()); }); } void onLogin(String email, String password) { / / We will finish it later } @override Widget build(BuildContext context) {
  • 36. return MaterialApp( title: 'TODO app', initialRoute: '/', routes: { '/': (context) => TODOLogin(onLogin: onLogin), '/list': (context) => TODOList(tasks: tasks, onToggle: onTaskToggled), '/create': (context) => TODOCreate(onCreate: onTaskCreated,), }, ); }} Now when a user logins it will send email and password to root widget via callback. Your login screen will look something like this: Authenticate with Firebase: To authenticate we will create a new class of Authentication in auth.dart it will communicate with Firebase. TODOLogin will call it on the login button, pass the user to TODOState and move to the next page.
  • 37. Write the following code in auth.dart file: class Authentication { final _firebaseAuth = FirebaseAuth.instance; Future< FirebaseUser > login(String email, String password) async { try { AuthResult result = await _firebaseAuth.signInWithEmailAndPassword( email: email, password: password ); return result.user; } catch (e) { return null; } }} void main() => runApp(TODOApp()); class TODOApp extends StatelessWidget {
  • 38. @override Widget build(BuildContext context) { return TODO(); }} class TODO extends StatefulWidget { @override State< StatefulWidget > createState() { return TODOState(); }} class TODOState extends State< TODO > { final List< Task > tasks = []; final Authentication auth = new Authentication(); FirebaseUser user; void onTaskCreated(String name) { setState(() {
  • 39. tasks.add(Task(name)); }); } void onTaskToggled(Task task) { setState(() { task.setCompleted(!task.isCompleted()); }); } void onLogin(FirebaseUser user) { setState(() { this.user = user; }); } @override Widget build(BuildContext context) { return MaterialApp( title: 'TODO app', initialRoute: '/',
  • 40. routes: { '/': (context) => TODOLogin(onLogin: onLogin), '/list': (context) => TODOList(tasks: tasks, onToggle: onTaskToggled), '/create': (context) => TODOCreate(onCreate: onTaskCreated,), },); }} class TODOLogin extends StatefulWidget { final onLogin; TODOLogin({@required this.onLogin}); @override State< StatefulWidget > createState() { return LoginState(); }} class LoginState extends State< TODOLogin > { final TextEditingController emailController = TextEditingController();
  • 41. final TextEditingController passwordController = TextEditingController(); final auth = Authentication(); void doLogin() async { final user = await auth.login(emailController.text, passwordController.text); if (user != null) { widget.onLogin(user); Navigator.pushReplacementNamed(context, '/list'); } else { _showAuthFailedDialog(); } } void _showAuthFailedDialog() { showDialog( context: context, builder: (BuildContext context) {
  • 42. return AlertDialog( title: new Text('Could not log in'), content: new Text('Double check your credentials and try again'), actions: < Widget >[ new FlatButton( child: new Text('Close'), onPressed: () { Navigator.of(context).pop(); }, ), ], ); }, );} @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Please log in') ),
  • 43. body: Padding( padding: EdgeInsets.all(16), child: Column( children: < Widget >[ Padding( padding: EdgeInsets.only(bottom: 16), child: TextField( controller: emailController, decoration: InputDecoration( border: OutlineInputBorder(), labelText: 'Email' ), ) ), Padding(
  • 44. padding: EdgeInsets.only(bottom: 16), child: TextField( controller: passwordController, obscureText: true, decoration: InputDecoration( border: OutlineInputBorder(), labelText: 'Password' ), ) ), RaisedButton( / / Calling the doLogin function on press onPressed: doLogin, child: Text('LOGIN'), color: ThemeData().primaryColor, ) ], mainAxisAlignment: MainAxisAlignment.center,
  • 45. crossAxisAlignment: CrossAxisAlignment.end, ) ) ); }} void main() => runApp(TODOApp()); class TODOApp extends StatelessWidget { @override Widget build(BuildContext context) { return TODO(); }} class TODO extends StatefulWidget { @override State< StatefulWidget > createState() { return TODOState(); }} class TODOState extends State< TODO > { final List< Task > tasks = [];
  • 46. final Authentication auth = new Authentication(); FirebaseUser user; void onTaskCreated(String name) { setState(() { tasks.add(Task(name)); }); } void onTaskToggled(Task task) { setState(() { task.setCompleted(!task.isCompleted()); }); } void onLogin(FirebaseUser user) { setState(() { this.user = user; }); } @override
  • 47. Widget build(BuildContext context) { return MaterialApp( title: 'TODO app', initialRoute: '/', routes: { '/': (context) => TODOLogin(onLogin: onLogin), '/list': (context) => TODOList(tasks: tasks, onToggle: onTaskToggled), '/create': (context) => TODOCreate(onCreate: onTaskCreated,), }, ); }} void main() => runApp(TODOApp()); class TODOApp extends StatelessWidget { @override Widget build(BuildContext context) { return TODO(); }}
  • 48. class TODO extends StatefulWidget { @override State< StatefulWidget > createState() { return TODOState(); }} class TODOState extends State< TODO > { final List< Task > tasks = []; final Authentication auth = new Authentication(); FirebaseUser user; void onTaskCreated(String name) { setState(() { tasks.add(Task(name)); }); } void onTaskToggled(Task task) { setState(() {
  • 49. task.setCompleted(!task.isCompleted()); }); } void onLogin(FirebaseUser user) { setState(() { this.user = user; });} @override Widget build(BuildContext context) { return MaterialApp( title: 'TODO app', initialRoute: '/', routes: { '/': (context) => TODOLogin(onLogin: onLogin), '/list': (context) => TODOList(tasks: tasks, onToggle: onTaskToggled), '/create': (context) => TODOCreate(onCreate: onTaskCreated,),
  • 50. }, ); }} Setup with Authentication in Firebase Console: To enable authentication of your application: ● Go to Firebase console → select your project → open Authentication → click on Setup sign-in method. ● In the next screen, select email/ password and enable it. Save Tasks to Firebase Firestore: Turn on Firestore in the Firebase Console. Open it→ go to database tab → create database → select start in testing mode. We need to change TODOList to fetch data from Firestore and update it if user completes the task: class TODOList extends StatelessWidget { final collection = Firestore.instance.collection('tasks'); @override Widget build(BuildContext context) { return Scaffold(
  • 51. appBar: AppBar( title: Text('TODO app'), ), body: StreamBuilder< QuerySnapshot >( stream: collection.snapshots(), builder: (BuildContext context, AsyncSnapshot< QuerySnapshot > snapshot) { if (snapshot.hasError) return Text('Error: ${snapshot.error}'); switch (snapshot.connectionState) { case ConnectionState.waiting: return Text('Loading...'); default: return ListView( children: snapshot.data.documents.map((DocumentSnapshot document) { return CheckboxListTile(
  • 52. title: Text(document['name']), value: document['completed'], onChanged: (newValue) => collection.document(document.documentID).updateData({'compl eted': newValue}) ); }).toList(), ); } }, ), floatingActionButton: FloatingActionButton( onPressed: () => Navigator.pushNamed(context, '/create'), child: Icon(Icons.add) ), ); }} Next up, we will integrate TODOCreate to the Firestore: class TODOCreate extends StatefulWidget { @override State< StatefulWidget > createState() {
  • 53. return TODOCreateState(); }} class TODOCreateState extends State< TODOCreate > { final collection = Firestore.instance.collection('tasks'); final TextEditingController controller = TextEditingController(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Create a task')), body: Center( child: Padding( padding: EdgeInsets.all(16), child: TextField( autofocus: true, controller: controller,
  • 54. decoration: InputDecoration( labelText: 'Enter name for your task' ) ) ) ), floatingActionButton: FloatingActionButton( child: Icon(Icons.done), onPressed: () async { await collection.add({'name': controller.text, 'completed': false}); Navigator.pop(context); }, ), ); }} void main() => runApp(TODOApp()); class TODOApp extends StatelessWidget { @override Widget build(BuildContext context) { return TODO(); }}
  • 55. class TODO extends StatefulWidget { @override State< StatefulWidget > createState() { return TODOState(); }} class TODOState extends State< TODO > { final Authentication auth = new Authentication(); FirebaseUser user; void onLogin(FirebaseUser user) { setState(() { this.user = user; }); } @override Widget build(BuildContext context) { return MaterialApp(
  • 56. title: 'TODO app', initialRoute: '/', routes: { '/': (context) => TODOLogin(onLogin: onLogin), '/list': (context) => TODOList(), '/create': (context) => TODOCreate(), }, ); }} Voila! Our TODO app is ready. Follow these steps to build your first TODO app using Flutter. Apart from this, if you have an application idea using Flutter, reach out to us. Hire flutter app developers from us and our team will help you with turning your ideas into a reality.