// main.dart
// Importing the Flutter Material package for UI components
import 'package:flutter/material.dart';
// Importing a custom model class for Person data structure
import 'package:flutter_geeks/models/Person.dart';
// Entry point of the Flutter application
void main() {
runApp(const MyApp()); // Runs the app starting from MyApp widget
}
// Root widget of the application, which doesn't hold state
class MyApp extends StatelessWidget {
const MyApp({super.key}); // Constructor with optional key
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Geeks', // App title
theme: ThemeData(primarySwatch: Colors.green), // Global theme
home: const MainListScreen(), // Main screen widget
debugShowCheckedModeBanner: false, // Removes debug banner
);
}
}
// Main screen widget with mutable state
class MainListScreen extends StatefulWidget {
const MainListScreen({super.key}); // Constructor
@override
State<MainListScreen> createState() => _MainListScreenState(); // Creates state
}
// State class for MainListScreen
class _MainListScreenState extends State<MainListScreen> {
// Key to uniquely identify and control the AnimatedList
final GlobalKey<AnimatedListState> _listKey = GlobalKey<AnimatedListState>();
// List to hold Person objects
List<Person> people = [];
// Controllers for name and designation input fields
TextEditingController nameController = TextEditingController();
TextEditingController designationController = TextEditingController();
// Function to add a new Person to the list
void _addPerson(personName, personDesignation) {
people.add(Person(personName, personDesignation)); // Add to list
_listKey.currentState!.insertItem(
people.length - 1, // Insert at end
duration: const Duration(milliseconds: 1000), // Animation duration
);
}
// Function to remove a Person from the list by index
void _removePerson(int index) {
_listKey.currentState!.removeItem(
index, // Remove from list at index
(context, animation) => SizeTransition(
sizeFactor: animation, // Animate shrinking
child: const Card(
margin: EdgeInsets.all(10),
color: Colors.red,
child: ListTile(
title: Text(
"Deleted",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
),
),
duration: const Duration(milliseconds: 500), // Removal animation
);
people.removeAt(index); // Remove from data list
}
// Called when the widget is inserted into the widget tree
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback((_) {
// Pre-populating the list with dummy people
_addPerson('Ram', 'Web Developer');
_addPerson('Abhi', 'Software Engineer');
_addPerson('Anu', 'Software Engineer');
_addPerson('Sita', 'Data Scientist');
_addPerson('Raj', 'DevOps Engineer');
});
super.initState();
}
// Building the UI
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('GeeksForGeeks'), // AppBar title
backgroundColor: Colors.green, // AppBar background
foregroundColor: Colors.white, // AppBar text/icon color
),
body: AnimatedList(
key: _listKey, // Key for controlling the list
initialItemCount: 0, // Start with empty list
itemBuilder: (context, index, animation) {
return SizeTransition(
key: UniqueKey(), // Unique key for each item
sizeFactor: animation, // Animation for list item entry
child: Card(
margin: const EdgeInsets.all(8.0), // Card margin
child: ListTile(
tileColor: Colors.grey[200], // Background color
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10), // Rounded edges
),
title: Text(
people[index].name, // Display name
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.green,
),
),
subtitle: Text(
people[index].designation, // Display designation
style: const TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
color: Colors.grey,
),
),
trailing: IconButton(
style: ButtonStyle(
backgroundColor: WidgetStateProperty.all<Color>(
Colors.black12,
),
shape: WidgetStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
),
icon: const Icon(
Icons.delete,
color: Colors.red,
), // Delete icon
onPressed: () {
_removePerson(index); // Trigger remove
},
),
),
),
);
},
),
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.green, // FAB color
foregroundColor: Colors.white,
onPressed: () {
_showDialog(); // Show dialog on FAB press
},
child: const Icon(Icons.add), // FAB icon
),
);
}
// Function to show the add-person dialog
_showDialog() {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Add Person'), // Dialog title
content: Column(
children: <Widget>[
// Input for Name
TextField(
controller: nameController,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: "Enter Name",
),
),
SizedBox(height: 10),
// Input for Designation
TextField(
controller: designationController,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: "Enter Designation",
),
),
],
),
actionsAlignment:
MainAxisAlignment.spaceBetween, // Align buttons apart
actions: <Widget>[
// Cancel Button
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.grey,
foregroundColor: Colors.white,
),
onPressed: () {
Navigator.of(context).pop(); // Close dialog
},
child: Text('Cancel'),
),
// Add Button
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green,
foregroundColor: Colors.white,
),
onPressed: () {
_addPerson(
nameController.text,
designationController.text,
); // Add person
nameController.clear(); // Clear text field
designationController.clear();
Navigator.of(context).pop(); // Close dialog
},
child: Text('Add'),
),
],
);
},
);
}
}