Flutter Tutorial:
Flutter Widgets:
Flutter Advance
Flutter REST API
Advanced Concepts
Wrap vs Builder vs OverBarFlow
Circular progress contain Icon
Flutter State management Comparison
Flutter Database
Flutter Token Expired Handling
Flutter Provider
Flutter GetX
Flutter with Native
Flutter Tips:
Interview Questions
Flutter 100 Interview Questions
In Flutter, there are several ways to pass values between Dart files. The most common methods include:
- Using a Constructor: You can pass values to another Dart file by creating a constructor and passing the values as parameters.
- Using Named Routes: You can pass values to another Dart file by using named routes and the Navigator.pushNamed method.
- Using Shared Preferences: You can store values in Shared Preferences and retrieve them in another Dart file.
- Using InheritedWidget: You can create an InheritedWidget to pass values down the widget tree.
- Using Static Variables: Another way is to define a static variable in the receiving Dart file and then set its value from the source Dart file before navigating to it
It’s important to choose the appropriate method depending on the requirements of your application. The methods you choose will impact the performance, code organization, and scalability of your application.
Constructor/Parameter Passing
//File1.dart
class File1 {
final String value;
File1(this.value);
}
//File2.dart
import 'file1.dart';
class File2 {
void someMethod() {
String myValue = 'Hello';
File1 file1 = File1(myValue);
// Accessing the value from File1
print(file1.value); // Output: Hello
}
}
In file1.dart, a class File1 is defined with a constructor that takes a value parameter. In file2.dart, the File2 class can create an instance of File1 and pass a value to it. The value can be accessed using the file1.value syntax in file2.dart
Named Routes:
//main.dart
import 'package:flutter/material.dart';
import 'file1.dart';
import 'file2.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => File1(),
'/file2': (context) => File2(),
},
);
}
}
//File1.dart
import 'package:flutter/material.dart';
class File1 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('File 1'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
String name = 'John Doe';
int age = 30;
Navigator.pushNamed(
context,
'/file2',
arguments: {'name': name, 'age': age},
);
},
child: Text('Go to File 2'),
),
),
);
}
}
//File2.dart
import 'package:flutter/material.dart';
class File2 extends StatelessWidget {
@override
Widget build(BuildContext context) {
Map<String, dynamic> data = ModalRoute.of(context).settings.arguments as Map<String, dynamic>;
String name = data['name'];
int age = data['age'];
return Scaffold(
appBar: AppBar(
title: Text('File 2'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Name: $name'),
Text('Age: $age'),
],
),
),
);
}
}
In file1.dart, we define the data we want to pass, such as a name (string) and age (integer). When the button is pressed in file1.dart, we use Navigator.pushNamed to navigate to the /file2 route and pass the data as a Map in the arguments parameter.
In file2.dart, we retrieve the passed arguments using ModalRoute.of(context).settings.arguments and cast it as a Map. Then we extract the name and age from the map. Finally, we display the name and age on the screen using the Text widget.
Shared Preferences
For Shared Preferences you check this flutter tutorial on SharedPreferences
Inheritance
class DataContainer extends InheritedWidget {
final String data;
DataContainer({required this.data, required Widget child}) : super(child: child);
static DataContainer? of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<DataContainer>();
}
@override
bool updateShouldNotify(covariant DataContainer oldWidget) {
return oldWidget.data != data;
}
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: DataContainer(
data: 'Hello, World!',
child: MyHomePage(),
),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Using InheritedWidget'),
),
body: Center(
child: Text(
DataContainer.of(context)?.data ?? '',
style: TextStyle(fontSize: 20),
),
),
);
}
}
Access the shared data using DataContainer.of(context). In this example, we retrieve the data property and display it within the Text widget. By using DataContainer as an InheritedWidget, the data provided in the DataContainer constructor will be accessible from any descendant widget that calls DataContainer.of(context).
Note: Whenever the shared data changes, you need to call setState on a widget that depends on the DataContainer. This triggers a rebuild and updates the widgets that rely on the shared data.
Remember to use InheritedWidget judiciously, as excessive use may lead to unnecessary rebuilds and impact performance.
Static Variable /Singleton
//File1.dart
class File1 {
static String value = 'Hello';
}
//File2.dart
import 'file1.dart';
class File2 {
void someMethod() {
// Accessing the value from File1
print(File1.value); // Output: Hello
}
}