Callbacks in Flutter
Maps in Flutter
Combining Callbacks and Maps
Creating and using a map to store and retrieve values
Converting a list of integers to a list of their squares
Quiz Implementation in Flutter using map
How to transform a list of JSON objects into a list of Dart objects using the map method
How to apply filter on list of Dart objects
How to convert each body in the list of Post objects to uppercase using the map
Callbacks in Flutter
Callbacks are functions passed as arguments to other functions or widgets. They are commonly used in Flutter to handle events like button presses, form submissions, or custom widget interactions.
Example: Callbacks in Flutter
In this example, we create a simple button that calls a callback function when pressed.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
// This is the callback function
void _handleButtonClick() {
print('Button pressed!');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Flutter Callbacks Example')),
body: Center(
child: CustomButton(
onPressed: _handleButtonClick,
),
),
);
}
}
class CustomButton extends StatelessWidget {
final VoidCallback onPressed;
CustomButton({required this.onPressed});
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: onPressed,
child: Text('Press me'),
);
}
}
In this example:
- HomePage has a method _handleButtonClick that prints a message.
- CustomButton takes a callback onPressed as an argument.
- When the button is pressed, the callback is invoked, and the message is printed
Maps in Flutter
A Map is a collection of key-value pairs, where each key is unique. Maps are often used to store data that can be accessed by a specific key.
Example: Using Maps in Flutter
In this example, we create a simple list of users, where each user is represented as a map.
Creating and using a map to store and retrieve values
void main() {
Map<String, int> fruitPrices = {
'Apple': 2,
'Banana': 1,
'Orange': 3,
};
print('Price of an Apple: \$${fruitPrices['Apple']}');
print('Price of a Banana: \$${fruitPrices['Banana']}');
print('Price of an Orange: \$${fruitPrices['Orange']}');
}
Converting a list of integers to a list of their squares
void main() {
List<int> numbers = [1, 2, 3, 4, 5];
List<int> squares = numbers.map((number) => number * number).toList();
print('Original list: $numbers');
print('Squared list: $squares');
}
void main() {
List<String> words = ['apple', 'banana', 'cherry'];
List<String> uppercaseWords = words.map((word) => word.toUpperCase()).toList();
print('Original list: $words');
print('Uppercase list: $uppercaseWords');
}
output
Original list: [apple, banana, cherry]
Uppercase list: [APPLE, BANANA, CHERRY]
Transforming a List of Objects
If you have a list of custom objects and want to transform a specific property, you can do so as follows:
class Person {
String name;
int age;
Person(this.name, this.age);
}
void main() {
List<Person> people = [
Person('John', 25),
Person('Jane', 30),
Person('Doe', 20),
];
List<String> names = people.map((person) => person.name).toList();
print('Original list: ${people.map((p) => p.name).toList()}');
print('Names list: $names');
}
output
Original list: [John, Jane, Doe]
Names list: [John, Jane, Doe]
Transforming a List of Maps
Suppose you have a list of maps representing people, and you want to extract their names.
void main() {
List<Map<String, dynamic>> people = [
{'name': 'John', 'age': 25},
{'name': 'Jane', 'age': 30},
{'name': 'Doe', 'age': 20},
];
List<String> names = people.map((person) => person['name'] as String).toList();
print('Original list: $people');
print('Names list: $names');
}
Original list: [{name: John, age: 25}, {name: Jane, age: 30}, {name: Doe, age: 20}]
Names list: [John, Jane, Doe]
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
// List of users where each user is represented as a map
final List<Map<String, String>> users = [
{'name': 'Alice', 'email': 'alice@example.com'},
{'name': 'Bob', 'email': 'bob@example.com'},
{'name': 'Charlie', 'email': 'charlie@example.com'},
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Flutter Maps Example')),
body: ListView.builder(
itemCount: users.length,
itemBuilder: (context, index) {
final user = users[index];
return ListTile(
title: Text(user['name']!),
subtitle: Text(user['email']!),
);
},
),
);
}
}
In this example:
- We have a list of maps, where each map represents a user with name and email keys.
- We use a ListView.builder to build a list of ListTile widgets, displaying the user information . Summary Callbacks
Purpose
: Handle events and pass functions as arguments.
Use Case
: Button presses, form submissions, custom widget interactions.
Example: Passing a function to a custom button widget.
Maps
Purpose
: Store key-value pairs.
Use Case
: Storing and accessing data by unique keys.
Example: List of users represented as maps with name and email keys.
Combining both concepts can help build dynamic and interactive applications in Flutter. Here’s a more complex example that combines callbacks and maps.
Combining Callbacks and Maps
In this example, we'll have a list of users and a button for each user. When the button is pressed, a callback function will be called, displaying the user's name.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
final List<Map<String, String>> users = [
{'name': 'Alice', 'email': 'alice@example.com'},
{'name': 'Bob', 'email': 'bob@example.com'},
{'name': 'Charlie', 'email': 'charlie@example.com'},
];
void _handleUserButtonPress(String name) {
print('User: $name');
// You can show a dialog or snackbar as well to display the user name
// For example, using a Snackbar:
// ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('User: $name')));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Flutter Callbacks and Maps Example')),
body: ListView.builder(
itemCount: users.length,
itemBuilder: (context, index) {
final user = users[index];
return ListTile(
title: Text(user['name']!),
subtitle: Text(user['email']!),
trailing: ElevatedButton(
onPressed: () => _handleUserButtonPress(user['name']!),
child: Text('Show Name'),
),
);
},
),
);
}
}
In this example:
- We have a list of users.
- For each user, there's a button that, when pressed, calls the _handleUserButtonPress method.
- The user's name is printed when the button is pressed . This demonstrates how callbacks and maps can be effectively used together in Flutter to create dynamic and interactive user interfaces.
Quiz Implementation in Flutter using map
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: QuizScreen(),
);
}
}
class QuizScreen extends StatefulWidget {
@override
_QuizScreenState createState() => _QuizScreenState();
}
class _QuizScreenState extends State<QuizScreen> {
int _questionIndex = 0;
List<String> _questions = [
'What is a callback in Flutter?',
'How do widgets use callbacks?',
'What is a map in Dart?',
'How can you transform a list using the map method?'
];
void _nextQuestion() {
setState(() {
_questionIndex = (_questionIndex + 1) % _questions.length;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Quiz Yourself"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
_questions[_questionIndex],
style: TextStyle(fontSize: 18),
textAlign: TextAlign.center,
),
SizedBox(height: 20),
ElevatedButton(
onPressed: _nextQuestion,
child: Text("Next Question"),
),
],
),
),
);
}
}
How to transform a list of JSON objects into a list of Dart objects using the map method
List<Post> _posts = jsonData.map((jsonItem) => Post.fromJson(jsonItem)).toList();
class _PostListScreenState extends State<PostListScreen> {
List<Post> _posts = [];
List<Post> _filteredPosts = [];
bool _loading = true;
String _filterKeyword = '';
@override
void initState() {
super.initState();
_fetchPosts();
}
Future<void> _fetchPosts() async {
final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'));
if (response.statusCode == 200) {
final List<dynamic> jsonData = json.decode(response.body);
setState(() {
_posts = jsonData.map((jsonItem) => Post.fromJson(jsonItem)).toList();
_filteredPosts = _posts; // Initialize the filtered posts list
_loading = false;
});
} else {
throw Exception('Failed to load posts');
}
}
Explanation
[
{"id": 1, "title": "Hello World", "body": "This is the body of the post"},
{"id": 2, "title": "Flutter Development", "body": "This is the body of the post"},
{"id": 3, "title": "Dart Programming", "body": "This is the body of the post"}
]
Here’s how the code works step by step:
jsonData:
It is a list of maps (JSON objects) received from the API.
List<dynamic> jsonData = [
{"id": 1, "title": "Hello World", "body": "This is the body of the post"},
{"id": 2, "title": "Flutter Development", "body": "This is the body of the post"},
{"id": 3, "title": "Dart Programming", "body": "This is the body of the post"}
];
Mapping JSON to Post Objects:
Each jsonItem in jsonData is passed to the Post.fromJson factory constructor, creating a Post object for each JSON object.
dart
Iterable<Post> postIterable = jsonData.map((jsonItem) => Post.fromJson(jsonItem));
Converting to List:
The Iterable is then converted to a List using .toList().
List<Post> postList = postIterable.toList();
Assigning to _posts:
The resulting list of Post objects is assigned to the _posts variable.
_posts = postList;
How to apply filter on list of Dart objects
_filteredPosts = _posts
.where((post) => post.title.contains("FLUTTER"))
.toList();
posts.map((post) {
return Post(id: post.id, title: post.title, body: post.body.toUpperCase());
}).toList();
Original List (_posts):
[
Post(id: 1, title: "HELLO WORLD", body: "This is the body of the post"),
Post(id: 2, title: "FLUTTER DEVELOPMENT", body: "This is the body of the post"),
Post(id: 3, title: "DART PROGRAMMING", body: "This is the body of the post"),
Post(id: 4, title: "WELCOME TO FLUTTER", body: "This is the body of the post")
]
Filtered List (_filteredPosts):
[
Post(id: 2, title: "FLUTTER DEVELOPMENT", body: "This is the body of the post"),
Post(id: 4, title: "WELCOME TO FLUTTER", body: "This is the body of the post")
]
How to convert each body in the list of Post objects to uppercase using the map
final List<Post> posts = [
Post(id: 1, title: "HELLO WORLD", body: "This is the body of the post"),
Post(id: 2, title: "FLUTTER DEVELOPMENT", body: "This is the body of the post"),
Post(id: 3, title: "DART PROGRAMMING", body: "This is the body of the post"),
Post(id: 4, title: "WELCOME TO FLUTTER", body: "This is the body of the post"),
];
List<Post> updatedPosts = posts.map((post) {
return Post(id: post.id, title: post.title, body: post.body.toUpperCase());
}).toList();
Top comments (0)