In this tutorial, you can be understanding app state-managed in the flutter framework. When We wanted to send data from one screen to another screen that time we are used to state management process in our application. Here I have created an e-commerce application project prototype sample given in the video.
For the state management, we need a package for installation in our flutter project, for that, go to pub.dev website then search about provider package. Also, you can get package information by link.
Package installation command is
flutter pub add provider
After then we start to code for state management.
import 'package:appstate/models/user_model.dart';
import 'package:appstate/pages/home.dart';
import 'package:appstate/pages/login.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => ProductNotier()),
ChangeNotifierProvider(create: (_) => UserNotifier())
],
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
bool isLogin = context.watch<UserNotifier>().isLogin;
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.yellow,
),
home: isLogin ? HomePage() : LoginPage(),
);
}
}
import 'package:flutter/material.dart';
class UserNotifier with ChangeNotifier {
String username = 'admin';
String password = 'password';
bool _check = false;
bool auth(String user, String pass) {
if (username == user && password == pass) {
_check = true;
}
notifyListeners();
return _check;
}
void logout() {
_check = false;
notifyListeners();
}
bool get isLogin => _check;
}
import 'package:appstate/classes/item.dart';
import 'package:flutter/foundation.dart';
class ProductNotier with ChangeNotifier {
List<Item> _items = [];
int _counter = 0;
List<Item> get items => _items;
int get counter => _counter;
double get totalAmt {
double total = 0;
_items.forEach((item) {
total += item.amount!;
});
return total;
}
add(Item item) {
_items.add(item);
_counter = _items.length;
notifyListeners();
}
remove(int index) {
_items.removeAt(index);
_counter = _items.length;
notifyListeners();
}
removeAll() {
_items.clear();
_counter = _items.length;
notifyListeners();
}
}
class Item {
String? details;
double? amount;
Item(this.details, this.amount);
}
class User {
String? username;
String? password;
User(this.username, this.password);
}
Now Create Multiple Items. So now create-service directory for dummy data.
import 'package:appstate/classes/item.dart';
List<Item> products = [
Item('Shirt', 50),
Item('Shree', 400),
Item('T-Shirt', 100),
Item('Watch', 800),
Item('Mobile', 1000),
Item('Wallet', 200),
Item('Bag', 500),
Item('Shoe', 1500),
Item('Pant', 500),
Item('Designer Pant', 1500),
];
Now we need to be created Pages or Screens
import 'package:appstate/models/user_model.dart';
import 'package:appstate/pages/home.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class LoginPage extends StatefulWidget {
@override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
String? username;
String? password;
GlobalKey<FormState> _key = GlobalKey<FormState>();
bool recheck = false;
@override
Widget build(BuildContext context) {
UserNotifier un = Provider.of<UserNotifier>(context);
return Scaffold(
body: Container(
padding: EdgeInsets.all(8.0),
child: Form(
key: _key,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Login Page',
style: TextStyle(fontSize: 24),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
decoration: InputDecoration(
labelText: 'Input Username',
prefixIcon: Icon(
Icons.face_unlock_sharp,
color: Colors.blueAccent,
),
labelStyle: TextStyle(color: Colors.blueAccent),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(color: Colors.teal),
),
),
initialValue: null,
validator: (value) {
if (value!.isEmpty) {
return 'Please input username';
}
return null;
},
onSaved: (value) {
username = value;
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
decoration: InputDecoration(
labelText: 'Input Password',
prefixIcon: Icon(
Icons.lock,
color: Colors.blueAccent,
),
labelStyle: TextStyle(color: Colors.blueAccent),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
),
),
initialValue: null,
validator: (value) {
if (value!.isEmpty) {
return 'Please input password';
}
return null;
},
onSaved: (value) {
password = value;
},
),
),
SizedBox(
height: 8.0,
),
RaisedButton(
child: Text('Login'),
color: Colors.yellow,
onPressed: () {
if (!_key.currentState!.validate()) return;
_key.currentState!.save();
setState(() {
recheck = un.auth(username!, password!);
});
// Show Message
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
(!recheck)
? 'Username and Password do not match with our records'
: 'Welcome to my app',
),
),
);
// User Auth Check
if (!recheck) return;
// Navigate to Home page
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) =>
un.isLogin ? HomePage() : LoginPage(),
),
);
},
)
],
),
),
),
);
}
}
import 'package:appstate/models/product_model.dart';
import 'package:appstate/models/user_model.dart';
import 'package:appstate/pages/cart.dart';
import 'package:appstate/pages/login.dart';
import 'package:appstate/services/data_link.dart';
import 'package:badges/badges.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
UserNotifier un = Provider.of<UserNotifier>(context);
ProductNotier pn = Provider.of<ProductNotier>(context);
return Scaffold(
appBar: AppBar(
leading: Icon(Icons.integration_instructions),
title: Text('My App'),
actions: [
Padding(
padding: const EdgeInsets.all(8.0),
child: IconButton(
icon: Badge(
badgeContent: Text(pn.counter.toString()),
child: Icon(Icons.shopping_cart),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CartPage('Cart Page'),
),
);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: IconButton(
icon: Icon(Icons.logout),
onPressed: () {
un.logout();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => LoginPage(),
),
);
},
),
)
],
),
body: Container(
height: double.infinity,
child: ListView(
children: [
for (var item in products)
ListTile(
leading: Icon(Icons.supervised_user_circle_outlined),
title: Text(
item.details!,
),
subtitle: Text(
'Price: ₹' + item.amount.toString(),
),
trailing: ElevatedButton(
onPressed: () {
pn.add(item);
},
child: Text('Add'),
),
),
],
),
),
);
}
}
import 'package:appstate/models/product_model.dart';
import 'package:appstate/models/user_model.dart';
import 'package:appstate/pages/login.dart';
import "package:flutter/material.dart";
import 'package:provider/provider.dart';
class CartPage extends StatefulWidget {
String title;
CartPage(this.title);
@override
_CartPageState createState() => _CartPageState();
}
class _CartPageState extends State<CartPage> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
UserNotifier un = Provider.of<UserNotifier>(context);
ProductNotier pn = Provider.of<ProductNotier>(context);
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
actions: [
Center(
widthFactor: 1.2,
child: IconButton(
icon: Icon(Icons.remove_shopping_cart),
onPressed: () => {
pn.removeAll(),
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: IconButton(
icon: Icon(Icons.logout),
onPressed: () {
un.logout();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => LoginPage(),
),
);
},
),
)
],
),
body: Container(
child: ListView(
children: [
Padding(
padding: const EdgeInsets.only(top: 8, left: 8),
child: Text(
'Products Details',
style: TextStyle(fontSize: 20),
),
),
MyTable(
children: [
tebleHeader(title: 'Product Details'),
for (var i = 0; i < pn.items.length; i++)
tableBody(
pn.items[i].details!,
pn.items[i].amount!,
index: i,
),
tableBody('Total', pn.totalAmt)
],
),
tableFooter(context)
],
),
),
);
}
ButtonBar tableFooter(BuildContext context) {
return ButtonBar(
children: [
RaisedButton(
color: Theme.of(context).primaryColor,
onPressed: () {
context.read<ProductNotier>().removeAll();
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Clear Cart'),
),
),
RaisedButton(
color: Theme.of(context).primaryColor,
onPressed: () {},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Check Out'),
),
),
],
);
}
TableRow tableBody(String details, double amount, {int? index}) {
return TableRow(children: [
TableCell(
child: Padding(
padding: const EdgeInsets.all(5.0),
child: Text(details),
)),
// TableCell(child: Center(child: Text(unit.toString()))),
TableCell(child: Center(child: Text('₹$amount'))),
TableCell(
child: Center(
child: (index != null)
? RaisedButton(
color: Theme.of(context).primaryColor,
child: Text('X'),
onPressed: () {
context.read<ProductNotier>().remove(index);
},
)
: null,
)),
]);
}
TableRow tebleHeader({String? title, String? units, String? price}) {
return TableRow(children: [
TableCell(
verticalAlignment: TableCellVerticalAlignment.middle,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(title ?? 'Product Title'),
),
),
TableCell(
child: Center(child: Text(price ?? 'Price')),
),
TableCell(
child: Center(child: Text(units ?? 'Delete?')),
),
]);
}
}
class MyTable extends StatelessWidget {
final List<TableRow>? children;
const MyTable({
Key? key,
@required this.children,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Table(
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
defaultColumnWidth: FlexColumnWidth(1.0),
border: TableBorder.all(
color: Colors.black,
style: BorderStyle.solid,
width: 1,
),
columnWidths: {
0: FlexColumnWidth(3),
1: FlexColumnWidth(1),
},
children: children!,
),
);
}
}
This is all codes. I hope you will understand the whole concept of app state management. If you wanted to learn more step by step then you purchase a complete course on flutter mobile application development. You may understand every flutter application concept with full source code.
Thank you for learning. You can express yourself with like shares and comments.
© Copyright By Larnr Education. 2023.