Google search engine
Home Blog Page 67

Shallow & Deep Copy a Map In Dart

0

Dart supports Map information type. You can copy a Map into another one utilizing different strategies. There are two sorts of copy, shallow copy, and Deep copy. Understanding the distinction between those two is important before you pick how to copy a map.

This article will explore the Shallow & Deep Copy a Map In Dart. We will execute a demo program and I might want to tell you how to copy a Map in Dart and explain the difference between shallow copy and deep copy in your applications.

If you’re looking for the best Flutter app development company for your mobile application then feel free to contact us at — support@flutterdevs.com.

Table Of Contents::

Shallow Copy

Using Map.of

Using Map.from

Using Map.unmodifiable

Deep Copy

Conclusion



Shallow Copy:

A shallow copy means the main object which is the Map is copied, however, the internal objects (the components) are not. An object can be mutable or changeless.

If the component is immutable and you change the value, Dart can not adjust it and another object with an alternate memory area will be made.

Subsequently, utilizing shallow copy ought to be protected if the component sort of the Map is immutable, like Stringboolint, or bool. The following are instances of shallow copy utilizing Dart’s strategies.

Using Map.of:

The Map.of factory technique can be utilized to copy a Map into a another one.

factory Map.of(Map<K, V> other)

Demo:

var values = <int, String>{
1: 'red',
2: 'green',
3: 'blue',
};
var newValues = Map.of(values);

Using Map.from:

This technique is likeMap.of, however, you can utilize it to produce another Map whose key as well as component type is a subtype of the source key or component type.

  factory Map.from(Map other)

Making another Map with additional exact types is utilized. You need to ensure that all the keys and values have the more exact types.

Demo:

var values = <num, String>{
1: 'red',
2: 'green',
3: 'blue',
};
Map<int, String> newValues = Map.from(values);

Using Map.unmodifiable:

If you want to copy into a Map that cannot be modified, you can use Map.umodifiable factory method.

  factory Map.unmodifiable(Map<dynamic, dynamic> other)

Demo:

var types = Map.unmodifiable({
1: 'red',
2: 'green',
3: 'blue',
});

Deep Copy:

While shallow copy works for a Map with immutable components, you might have to involve a deep copy for a Map with mutable components. Utilizing the models above, assuming that the component is mutable, Dart will just copy the reference to the object.

The actual object isn’t copied. Consequently, assuming that you alter a component of the source, it additionally influences the element of the new Map. On the off chance that you don’t need that way of behaving, you need to clone every component by making another object.

For demo, we have a Map whose component type is Item. To make another Item object from a current one, we can make a factory technique clone.

class Item {
String name;

Item({
required this.name,
});

factory Item.clone(Item source) {
return Item(
name: source.name,
);
}
}

From that point forward, use map the technique to map every component. You want to return a MapEntry and utilize the cloning strategy above to copy the mutable object.

  var item1 = Item(name: 'red');
var item2 = Item(name: 'green');
Map<int, Item> source = {1: item1, 2: item2};
var clone = source.map((key, value) => MapEntry(key, Item.clone(value)));
item1.name = 'green';
print(source[1]?.name); // Green
print(clone[1]?.name); // Red

Conclusion:

In the article, I have explained the Shallow & Deep Copy a Map In Dart; you can modify this code according to your choice. This was a small introduction to the Shallow & Deep Copy a Map In Dart User Interaction from my side, and it’s working using Flutter.

That is how to copy a Map in Dart. If the Map just holds back immutable key and component values, shallow values ought to be sufficient. If either the key or value has mutable components, you might need to perform a deep copy.

I hope this blog will provide you with sufficient information on Trying the Shallow & Deep Copy a Map In Dart of your projects. So please try it.

❤ ❤ Thanks for reading this article ❤❤

If I got something wrong? Let me know in the comments. I would love to improve.

Clap 👏 If this article helps you.


From Our Parent Company Aeologic

Aeologic Technologies is a leading AI-driven digital transformation company in India, helping businesses unlock growth with AI automation, IoT solutions, and custom web & mobile app development. We also specialize in AIDC solutions and technical manpower augmentation, offering end-to-end support from strategy and design to deployment and optimization.

Trusted across industries like manufacturing, healthcare, logistics, BFSI, and smart cities, Aeologic combines innovation with deep industry expertise to deliver future-ready solutions.

Feel free to connect with us:
And read more articles from FlutterDevs.com.

FlutterDevs team of Flutter developers to build high-quality and functionally-rich apps. Hire a Flutter developer for your cross-platform Flutter mobile app project on an hourly or full-time basis as per your requirement! For any flutter-related queries, you can connect with us on FacebookGitHubTwitter, and LinkedIn.

We welcome feedback and hope that you share what you’re working on using #FlutterDevs. We truly enjoy seeing how you use Flutter to build beautiful, interactive web experiences.

Related: Metadata Annotations in Dart

Related: Sum Of a List Of Numbers In Dart

Need expert help building your Flutter app? Talk to FlutterExperts for architecture, development, and consulting support.


Explore Animated Loader In Flutter

0

The loader is utilized when the application is loading while information is coming from the Application programming interface or DataBase. The loader helps show loading when the application is in a loading state.

This article will Explore an Animated Loader In Flutter. We will perceive how to execute a demo program and we are going to learn about how we can create an animated loader using the loading_animation_widget package in your Flutter applications.

For Loading Animation:

loading_animation_widget | Flutter Package
Installation Add loading_animation_widget: to your pubspec.yaml dependencies then run flutter pub get dependencies…pub.dev

If you’re looking for the best Flutter app development company for your mobile application then feel free to contact us at — support@flutterdevs.com.


Table Of Contents::

Introduction

Implementation

Code Implement

Code File

Conclusion



Introduction:

This demo video shows how to create an animated loader in Flutter and how an animated loader will work using the loading_animation_widget package in your Flutter applications. We will show users different types of loaders. Users can choose one of the loaders for our projects. It will be shown on your device.

Demo Module::


Implementation:

Step 1: Add the dependencies

Add dependencies to pubspec — yaml file.

dependencies:
flutter:
sdk: flutter
loading_animation_widget: ^latest version

Step 2: Import

import 'package:loading_animation_widget/loading_animation_widget.dart';

Step 3: Run flutter packages get in the root directory of your app.

How to implement code in dart file :

You need to implement it in your code respectively:

Create a new dart file called main.dart inside the lib folder.

We should adjust our main. dart file. We want to new class AnimatedLoaderDemo(). In this class first, we will add a variable _pageController.

late PageController _pageController;

We will create an integer variable _pageNo is equal to zero.

int _pageNo = 0;

Now, we will add the initState() method. In this method, we will add a _pageController equal to the PageController(initialPage: _pageNo).

@override
void initState() {
super.initState();
_pageController = PageController(initialPage: _pageNo);
}

We will add the code to the build method. Below we will define _forPreviousPage_forNextPage, and animationList with the code.

@override
Widget build(BuildContext context) {
return PageView(
physics: const NeverScrollableScrollPhysics(),
controller: _pageController,
children: animationList
.map(
(appBody) => Scaffold(
backgroundColor: Colors.cyan.shade200,
appBar: (AppBar(
automaticallyImplyLeading: false,
title: const Text("Flutter Animated Loader Demo"),
centerTitle: true,
backgroundColor: Colors.cyan,
)),
body: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
height: MediaQuery.of(context).size.width / 6,
),
Text(
"Page : $_pageNo",
style: const TextStyle(fontSize: 20),
),
Expanded(
child: Center(
child: appBody.widget,
),
),
],
),
bottomNavigationBar: SafeArea(
top: false,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
icon: const Icon(
Icons.chevron_left_rounded,
),
onPressed: _forPreviousPage,
),
IconButton(
icon: const Icon(
Icons.chevron_right_rounded,
),
onPressed: _forNextPage,
),
],
),
),
),
),
)
.toList(),
);
}

Now we will add the _forNextPage() method. In this method, which is helpful to go to the next page.

void _forNextPage() {
if (_pageNo + 1 < animationList.length) {
_pageController.jumpToPage(_pageNo + 1);
setState(() {
_pageNo++;
});
} else {
_pageController.animateToPage(
0,
duration: const Duration(milliseconds: 800),
curve: Curves.ease,
);
setState(() {
_pageNo = 0;
});
}
}

Now we will add the _forPreviousPage() method. In this method, which is helpful to go to the previous page.

void _forPreviousPage() {
if (_pageNo == 0) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text(
'Not any Page form Previous',
),
),
);
} else {
_pageController.jumpToPage(_pageNo - 1);
setState(() {
_pageNo--;
});
}
}

Now, we will create a new class that was AppBody and the code is below.

class AppBody {
final String title;
final Widget widget;

AppBody(
this.title,
this.widget,
);
}

Now we will add the animationList. We need to create a List whose type name will be same as above class name.

final animationList = <AppBody>[
AppBody(
'Loader',
const Text(
'Total animations: 5',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18,
),
),
),
AppBody(
'inkDropLoader',
LoadingAnimationWidget.waveDots(
color: Colors.redAccent,
size: 70,
),
),
AppBody(
'twistingDotsLoader',
LoadingAnimationWidget.twistingDots(
leftDotColor: const Color(0xFF1A1A3F),
rightDotColor: const Color(0xFFEA3799),
size: 70,
),
),
AppBody(
'threeRotatingDotsLoader',
LoadingAnimationWidget.threeRotatingDots(
color: Colors.white,
size: 70,
),
),
AppBody(
'staggeredDotsWaveLoader',
LoadingAnimationWidget.staggeredDotsWave(
color: Colors.white,
size: 70,
),
),
AppBody(
'fourRotatingDotsLoader',
LoadingAnimationWidget.fourRotatingDots(
color: Colors.white,
size: 70,
),
),
];

When we run the application, we ought to get the screen’s output like the underneath screen capture.


Code File:

import 'package:flutter/material.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';

class AnimatedLoaderDemo extends StatefulWidget {
const AnimatedLoaderDemo({Key? key}) : super(key: key);

@override
State<AnimatedLoaderDemo> createState() => _AnimatedLoaderDemoState();
}

class _AnimatedLoaderDemoState extends State<AnimatedLoaderDemo> {
late PageController _pageController;
int _pageNo = 0;

@override
void initState() {
super.initState();
_pageController = PageController(initialPage: _pageNo);
}

@override
Widget build(BuildContext context) {
return PageView(
physics: const NeverScrollableScrollPhysics(),
controller: _pageController,
children: animationList
.map(
(appBody) => Scaffold(
backgroundColor: Colors.cyan.shade200,
appBar: (AppBar(
automaticallyImplyLeading: false,
title: const Text("Flutter Animated Loader Demo"),
centerTitle: true,
backgroundColor: Colors.cyan,
)),
body: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
height: MediaQuery.of(context).size.width / 6,
),
Text(
"Page : $_pageNo",
style: const TextStyle(fontSize: 20),
),
Expanded(
child: Center(
child: appBody.widget,
),
),
],
),
bottomNavigationBar: SafeArea(
top: false,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
icon: const Icon(
Icons.chevron_left_rounded,
),
onPressed: _forPreviousPage,
),
IconButton(
icon: const Icon(
Icons.chevron_right_rounded,
),
onPressed: _forNextPage,
),
],
),
),
),
),
)
.toList(),
);
}

void _forNextPage() {
if (_pageNo + 1 < animationList.length) {
_pageController.jumpToPage(_pageNo + 1);
setState(() {
_pageNo++;
});
} else {
_pageController.animateToPage(
0,
duration: const Duration(milliseconds: 800),
curve: Curves.ease,
);
setState(() {
_pageNo = 0;
});
}
}

void _forPreviousPage() {
if (_pageNo == 0) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text(
'Not any Page form Previous',
),
),
);
} else {
_pageController.jumpToPage(_pageNo - 1);
setState(() {
_pageNo--;
});
}
}
}

class AppBody {
final String title;
final Widget widget;

AppBody(
this.title,
this.widget,
);
}

final animationList = <AppBody>[
AppBody(
'Loader',
const Text(
'Total animations: 5',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18,
),
),
),
AppBody(
'inkDropLoader',
LoadingAnimationWidget.waveDots(
color: Colors.redAccent,
size: 70,
),
),
AppBody(
'twistingDotsLoader',
LoadingAnimationWidget.twistingDots(
leftDotColor: const Color(0xFF1A1A3F),
rightDotColor: const Color(0xFFEA3799),
size: 70,
),
),
AppBody(
'threeRotatingDotsLoader',
LoadingAnimationWidget.threeRotatingDots(
color: Colors.white,
size: 70,
),
),
AppBody(
'staggeredDotsWaveLoader',
LoadingAnimationWidget.staggeredDotsWave(
color: Colors.white,
size: 70,
),
),
AppBody(
'fourRotatingDotsLoader',
LoadingAnimationWidget.fourRotatingDots(
color: Colors.white,
size: 70,
),
),
];

Conclusion:

In the article, I have explained the Animated Loader in a flutter; you can modify this code according to your choice. This was a small introduction to Animated Loader On User Interaction from my side, and it’s working using Flutter.

I hope this blog will provide you with sufficient information on Trying the Animated Loader in your Flutter projectsWe will show you what the Introduction is. Make a demo program for working on Animated Loader Using the loading_animation_widget package in your Flutter applications. So please try it.

❤ ❤ Thanks for reading this article ❤❤

If I got something wrong? Let me know in the comments. I would love to improve.

Clap 👏 If this article helps you.


From Our Parent Company Aeologic

Aeologic Technologies is a leading AI-driven digital transformation company in India, helping businesses unlock growth with AI automation, IoT solutions, and custom web & mobile app development. We also specialize in AIDC solutions and technical manpower augmentation, offering end-to-end support from strategy and design to deployment and optimization.

Trusted across industries like manufacturing, healthcare, logistics, BFSI, and smart cities, Aeologic combines innovation with deep industry expertise to deliver future-ready solutions.

Feel free to connect with us:
And read more articles from FlutterDevs.com.

FlutterDevs team of Flutter developers to build high-quality and functionally-rich apps. Hire a Flutter developer for your cross-platform Flutter mobile app project on an hourly or full-time basis as per your requirement! For any flutter-related queries, you can connect with us on FacebookGitHubTwitter, and LinkedIn.

We welcome feedback and hope that you share what you’re working on using #FlutterDevs. We truly enjoy seeing how you use Flutter to build beautiful, interactive web experiences.

Related: Explore AnimatedSize In Flutter

Related: Explore AnimatedOpacity In Flutter

Need expert help building your Flutter app? Talk to FlutterExperts for architecture, development, and consulting support.


Sorting List of Objects/Maps By Date In Flutter

0

This article will explore the Sorting List of Objects/Maps By Date In Flutter. We will perceive how to execute a demo program and we are going to learn about how we can use it in your applications.

If you’re looking for the best Flutter app development company for your mobile application then feel free to contact us at — support@flutterdevs.com.


Table Of Contents::

Introduction

Sorting a List of Objects by Date

Sorting a List of Maps by Date

Conclusion



Introduction:

The point is to utilize the sort() technique for the List class and pass a custom correlation capability that utilizes the compareTo() strategy for the DateTime class:

myList.sort ((a, b) {
// for ascending order
return a.date.compareTo (b.date);

// for descending order
// return b.date.compareTo (a.date);
});

Sorting a List of Objects by Date:

Suppose you have a list of users. The data of every user is stored away in an object, and your supervisor requests that you reorder these users by their join date. The model underneath will show you to tackle this:

The code:

class User {
final String name;
final String email;
final DateTime joinDate;

User({required this.name, required this.email, required this.joinDate});

@override
String toString() {
return 'User{name: $name, email: $email, joinDate: $joinDate}';
}
}

void main() {
// list of users
List<User> users = [
User(
name: 'Rahul',
email: 'raul@gmail.com',
joinDate: DateTime(2022, 10, 3)),
User(
name: 'John',
email: 'john@gmail.com',
joinDate: DateTime(2019, 5, 19)),
User(
name: 'Sam',
email: 'sam@gmail.com',
joinDate: DateTime(2021, 5, 12)),
User(
name: 'RSorted users by ascending joinDate:
[{name: John, email: john@gmail.com, joinDate: 2019-05-19}, {name: Sam, email: sam@gmail.com, joinDate: 2021-05-12}, {name: Rahul, email: raul@gmail.com, joinDate: 2022-10-03}, {name: Ruchi, email: ruchi@gmail.com, joinDate: 2023-02-08}]
Sorted users by descending joinDate:
[{name: Ruchi, email: ruchi@gmail.com, joinDate: 2023-02-08}, {name: Rahul, email: raul@gmail.com, joinDate: 2022-10-03}, {name: Sam, email: sam@gmail.com, joinDate: 2021-05-12}, {name: John, email: john@gmail.com, joinDate: 2019-05-19}]

Process finished with exit code 0uchi',
email: 'ruchi@gmail.com',
joinDate: DateTime(2023, 2, 8))
];

// sort by joinDate: ascending
final sortedUsersAsc = users.map((user) => user).toList()
..sort((a, b) => a.joinDate.compareTo(b.joinDate));

// sort by joinDate: descending
final sortedUsersDesc = users.map((user) => user).toList()
..sort((a, b) => b.joinDate.compareTo(a.joinDate));

print('Sorted by joinDate: ascending');
sortedUsersAsc.forEach((user) => print(user.toString()));

print('Sorted by joinDate: descending');
sortedUsersDesc.forEach((user) => print(user.toString()));
}

When we run the application, we ought to get the screen’s output like the underneath screen Console Output.

Sorted by joinDate: ascending
User{name: John, email: john@gmail.com, joinDate: 2019-05-19 00:00:00.000}
User{name: Sam, email: sam@gmail.com, joinDate: 2021-05-12 00:00:00.000}
User{name: Rahul, email: raul@gmail.com, joinDate: 2022-10-03 00:00:00.000}
User{name: Ruchi, email: ruchi@gmail.com, joinDate: 2023-02-08 00:00:00.000}
Sorted by joinDate: descending
User{name: ruchi, email: ruchi@gmail.com, joinDate: 2023-02-08 00:00:00.000}
User{name: rahul, email: raul@gmail.com, joinDate: 2022-10-03 00:00:00.000}
User{name: Sam, email: sam@gmail.com, joinDate: 2021-05-12 00:00:00.000}
User{name: John, email: john@gmail.com, joinDate: 2019-05-19 00:00:00.000}

Process finished with exit code 0

Sorting a List of Maps by Date:

In this model, the data about a user is stored away on a map rather than an object. Other than that, the join date of a user is a string, not a DateTime object. Hence, we should parse it into a DateTime object first utilizing the DateTime.parse() or DateTime.tryParse() strategy before playing out the comparison.

The code:

void main() {
final List<Map<String, dynamic>> users = [
{
"name": "Rahul",
"email": "raul@gmail.com",
"joinDate": "2022-10-03",
},
{
"name": "John",
"email": "john@gmail.com",
"joinDate": "2019-05-19",
},
{
"name": "Sam",
"email": "sam@gmail.com",
"joinDate": "2021-05-12",
},
{
"name": "Ruchi",
"email": "ruchi@gmail.com",
"joinDate": "2023-02-08",
}
];

// sort users by joinDate: ascending
final sortedUsersAsc = users.map((user) => user).toList()
..sort((a, b) =>
DateTime.parse(a["joinDate"]).compareTo(DateTime.parse(b["joinDate"])));

// sort users by joinDate: descending
final sortedUsersDesc = users.map((user) => user).toList()
..sort((a, b) =>
DateTime.parse(b["joinDate"]).compareTo(DateTime.parse(a["joinDate"])));

print("Sorted users by ascending joinDate:");
print(sortedUsersAsc);

print("Sorted users by descending joinDate:");
print(sortedUsersDesc);
}

When we run the application, we ought to get the screen’s output like the underneath screen Console Output.

Sorted users by ascending joinDate:
[
{name: John, email: john@gmail.com, joinDate: 2019-05-19},
{name: Sam, email: sam@gmail.com, joinDate: 2021-05-12},
{name: Rahul, email: raul@gmail.com, joinDate: 2022-10-03},
{name: Ruchi, email: ruchi@gmail.com, joinDate: 2023-02-08}
]
Sorted users by descending joinDate:
[
{name: Ruchi, email: ruchi@gmail.com, joinDate: 2023-02-08},
{name: Rahul, email: raul@gmail.com, joinDate: 2022-10-03},
{name: Sam, email: sam@gmail.com, joinDate: 2021-05-12},
{name: John, email: john@gmail.com, joinDate: 2019-05-19}
]

Process finished with exit code 0

Conclusion:

In the article, I have explained the sorting list of Objects/Maps By Date In Flutter; you can modify this code according to your choice. This was a small introduction to Sorting a List of Objects/Maps By Date In Flutter User Interaction from my side, and it’s working using Flutter.

I hope this blog will provide you with sufficient information on how to try the Sorting List of Objects/Maps by the date of your flutter projects. So please try it.

❤ ❤ Thanks for reading this article ❤❤

If I got something wrong? Let me know in the comments. I would love to improve.

Clap 👏 If this article helps you.


From Our Parent Company Aeologic

Aeologic Technologies is a leading AI-driven digital transformation company in India, helping businesses unlock growth with AI automation, IoT solutions, and custom web & mobile app development. We also specialize in AIDC solutions and technical manpower augmentation, offering end-to-end support from strategy and design to deployment and optimization.

Trusted across industries like manufacturing, healthcare, logistics, BFSI, and smart cities, Aeologic combines innovation with deep industry expertise to deliver future-ready solutions.

Feel free to connect with us:
And read more articles from FlutterDevs.com.

FlutterDevs team of Flutter developers to build high-quality and functionally-rich apps. Hire a Flutter developer for your cross-platform Flutter mobile app project on an hourly or full-time basis as per your requirement! For any flutter-related queries, you can connect with us on FacebookGitHubTwitter, and LinkedIn.

We welcome feedback and hope that you share what you’re working on using #FlutterDevs. We truly enjoy seeing how you use Flutter to build beautiful, interactive web experiences.

Related: Moving Marker Using Polyline On Google Maps In Flutter

Need expert help building your Flutter app? Talk to FlutterExperts for architecture, development, and consulting support.


Explore Speed Dial In Flutter

0

In Flutter, Speed Dial is a well-known floating action button (FAB) variation generally used to give users admittance to different actions or choices from a single button. At the point when the FAB is tapped, it extends to rapidly uncover a list of extra more modest buttons or actions, empowering users to perform related errands.

This article will Explore Speed Dial In Flutter. We will implement a demo program and I would like to show how to use speed dial in Flutter using the flutter_speed_dial package in your Flutter applications.

If you’re looking for the best Flutter app development company for your mobile application then feel free to contact us at — support@flutterdevs.com.

For Flutter Speed Dial:

flutter_speed_dial | Flutter package
Flutter plugin to implement a beautiful and dynamic Material Design Speed Dial with labels, animated icons…pub.dev


Table Of Contents::

Introduction

Implementation

Code Implement

Code File

Conclusion



Introduction:

A Speed Dial in Flutter is a proficient and easy-to-use method for dealing with various actions in a single Floating Action Button. It works on UI/UX plan while further developing availability to key elements.

This demo video shows how to use speed dial in Flutter and how a speed dial will work using the flutter_speed_dial package in your Flutter applications. We will show a user a fab button on a screen when the user presses the button it expands to reveal a list of additional smaller buttons or actions by using the flutter_speed_dial package. It will be shown on your device.

Demo Module::


Implementation:

Step 1: Add the dependencies

Add dependencies to pubspec — yaml file.

dependencies:
  flutter:
    sdk: flutter
  flutter_lints: ^3.0.0

Step 2: Import

import 'package:flutter_speed_dial/flutter_speed_dial.dart';

Step 3: Run flutter packages get in the root directory of your app.

Code Implement:

You need to implement it in your code respectively:

Create a new dart file called main.dart inside the lib folder.

In the main.dart file, we will create a new class was SpeedDialDemo(). In this new class, we will add the body. In the body we will add the center widget. Inside the widget, we will add an Image with height and width and text is ‘PLease tap the FAB button’.

Center(
child: Column(
children: [
Image.asset(
"assets/logo.png",
height: MediaQuery.of(context).size.height * 0.45,
width: MediaQuery.of(context).size.width * 0.7,
),
const Text(
'PLease tap the FAB button',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600),
),
],
)),

Then, now we will add the floatingActionButton. In this button we will add SpeedDial() function. Inside this function, we will add animatedIcon, backgroundColor, foregroundColor, overlayColor, overlayOpacity, etc.

floatingActionButton: SpeedDial(
  animatedIcon: AnimatedIcons.menu_close,
  backgroundColor: Colors.teal.shade100,
  foregroundColor: Colors.black,
  overlayColor: Colors.white,
  overlayOpacity: 0.5,
  spacing: 12.0,
  spaceBetweenChildren: 9.0,
  direction: SpeedDialDirection.up,
  children: [
    SpeedDialChild(
      child: const Icon(Icons.message),
      label: 'Chat',
      onTap: () => print('Chat'),
    ),
    SpeedDialChild(
      child: const Icon(Icons.call),
      label: 'Call',
      onTap: () => print('Call'),
    ),
    SpeedDialChild(
      child: const Icon(Icons.camera_alt),
      label: 'Camera',
      onTap: () => print('Camera'),
    ),
  ],
),

Its children, we will add three SpeedDialChild() function. In this function, we will three icons on the child, label and onTap(). When user tap the the button is expands and show icons.

When we run the application, we ought to get the screen’s output like the underneath screen capture.

Code File:

import 'package:flutter/material.dart';
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
import 'package:flutter_speed_dial_demo/splash_screen.dart';

void main() {
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({super.key});

@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
debugShowCheckedModeBanner: false,
home: const Splash(),
);
}
}

class SpeedDialDemo extends StatefulWidget {
const SpeedDialDemo({super.key});

@override
State<SpeedDialDemo> createState() => _SpeedDialDemoState();
}

class _SpeedDialDemoState extends State<SpeedDialDemo> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
title: const Text('Flutter Speed Dial Demo'),
backgroundColor: Colors.teal.shade100,
),
body: Center(
child: Column(
children: [
Image.asset(
"assets/logo.png",
height: MediaQuery.of(context).size.height * 0.45,
width: MediaQuery.of(context).size.width * 0.7,
),
const Text(
'PLease tap the FAB button',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600),
),
],
)),
floatingActionButton: SpeedDial(
animatedIcon: AnimatedIcons.menu_close,
backgroundColor: Colors.teal.shade100,
foregroundColor: Colors.black,
overlayColor: Colors.white,
overlayOpacity: 0.5,
spacing: 12.0,
spaceBetweenChildren: 9.0,
direction: SpeedDialDirection.up,
children: [
SpeedDialChild(
child: const Icon(Icons.message),
label: 'Chat',
onTap: () => print('Chat'),
),
SpeedDialChild(
child: const Icon(Icons.call),
label: 'Call',
onTap: () => print('Call'),
),
SpeedDialChild(
child: const Icon(Icons.camera_alt),
label: 'Camera',
onTap: () => print('Camera'),
),
],
),
);
}
}

Conclusion:

In the article, I have explained the spead dial in a flutter; you can modify this code according to your choice. This was a small introduction to speed dial On User Interaction from my side, and it’s working using Flutter.

I hope this blog will provide you with sufficient information on Trying the Speed Dial in your flutter projectsWe will show you what the Introduction is. Make a demo program for working on speed dial Using the flutter_speed_dial package in your flutter applications. So please try it.

❤ ❤ Thanks for reading this article ❤❤

If I got something wrong? Let me know in the comments. I would love to improve.

Clap 👏 If this article helps you.


From Our Parent Company Aeologic

Aeologic Technologies is a leading AI-driven digital transformation company in India, helping businesses unlock growth with AI automation, IoT solutions, and custom web & mobile app development. We also specialize in AIDC solutions and technical manpower augmentation, offering end-to-end support from strategy and design to deployment and optimization.

Trusted across industries like manufacturing, healthcare, logistics, BFSI, and smart cities, Aeologic combines innovation with deep industry expertise to deliver future-ready solutions.

Feel free to connect with us:
And read more articles from FlutterDevs.com.

FlutterDevs team of Flutter developers to build high-quality and functionally-rich apps. Hire a flutter developer for your cross-platform Flutter mobile app project on an hourly or full-time basis as per your requirement! You can connect with us on FacebookGitHubTwitter, and LinkedIn for any flutter-related queries.

We welcome feedback and hope you share what you’re working on using #FlutterDevs. We truly enjoy seeing how you use Flutter to build beautiful, interactive web experiences.

Related: Explore Exception Handling In Flutter

Related: Explore Dart String Interpolation

Related: Explore Design Patterns in Flutter

Need expert help building your Flutter app? Talk to FlutterExperts for architecture, development, and consulting support.


Flutter’s Architecture: Understanding the Internals

0

If you’re looking for the best Flutter app development company for your mobile application then feel free to contact us at — support@flutterdevs.com.


Table of Contents

Overview of Flutter’s Architecture

Flutter Engine: The Heart of Rendering

The Flutter Rendering Pipeline: How the UI is Drawn

Layers

Skia: The Graphics Engine Behind Flutter

Dart and Skia: How They Communicate

Deep Dive into Flutter’s Rendering Pipeline

Layout Phase: Determining Size and Position

Paint Phase: Rendering Visuals to the Screen

Compositing: Combining Layers for Efficient Rendering

Conclusion

References


Introduction

Flutter has quickly become one of the most popular frameworks for building cross-platform mobile apps. With its rich widget ecosystem, beautiful UIs, and seamless performance across iOS and Android, Flutter is an attractive choice for developers. However, behind the scenes, Flutter’s architecture is based on a highly optimized and custom rendering pipeline that ensures it runs efficiently and provides developers with great flexibility.

In this post, we will examine Flutter’s internal architecture, focusing on its enginerendering pipeline, and widget drawing on the screen. We will also discuss how Dart interacts with Skia, Flutter’s graphics library, and the custom rendering system that powers its high performance.


Overview of Flutter’s Architecture

Flutter’s architecture comprises several layers that work together to provide an efficient, high-performance development experience. Let’s start with a quick overview of the key components:

  • Dart App: It composes widgets into the desired user interface (UI) and implements the business logic necessary for the application. This involves arranging the widgets in a way that meets the design requirements and ensuring the app’s functionality is driven by the appropriate business rules and processes.
  • Flutter Framework (Dart-based): This is the top layer of Flutter where developers work directly. It includes all the widgets, libraries, and tools to create the app’s UI and business logic. The framework itself is written in Dart, which provides an expressive, easy-to-learn programming environment.
  • Flutter Engine: This is the core engine written in C++ that powers Flutter’s rendering capabilities. It handles low-level operations such as rendering, input handling, text layout, and more. The engine communicates with the underlying platform (iOS/Android) through platform channels to access native features.
  • Platform Layer: This layer provides access to the device’s platform-specific features such as sensors, cameras, geolocation, etc. Flutter communicates with this layer using platform channels, which allow the Dart code to interact with native code (Java/Kotlin for Android and Swift/Objective-C for iOS).
  • Embedder: The system coordinates with the underlying operating system to gain access to essential services, such as rendering surfaces, accessibility, and input management. It also takes responsibility for managing the event loop, ensuring that events are processed efficiently. Additionally, the system exposes a platform-specific API that allows the Embedder to be integrated seamlessly into applications, enabling smooth interaction with the operating system’s services and resources.
  • Runner: It composes the components exposed by the platform-specific API of the Embedder into an app package that is runnable on the target platform. This process is an integral part of the app template generated by the flutter create command, ensuring that the necessary resources and configurations are in place for the app to function properly on the specified platform.

Flutter Engine: The Heart of Rendering

The Flutter Engine is the core of Flutter’s performance and rendering. It is written in C++ and is responsible for managing the entire lifecycle of a Flutter app. The engine provides several essential components, including:

  • Dart VM: Flutter runs Dart code using the Dart Virtual Machine (VM). This VM is highly optimized for Flutter and enables efficient execution of business logic. During development, Flutter uses Just-In-Time (JIT) compilation to speed up the development cycle. In production, Ahead-Of-Time (AOT) compilation is used for optimized performance.
  • Skia Graphics Library: Skia is a 2D graphics library used by Flutter to draw everything from simple shapes, text, and images to complex animations. Skia provides hardware-accelerated rendering, making it ideal for Flutter’s performance-oriented needs.
  • Text Layout: Flutter uses Skia’s text layout engine to render text across various fonts, languages, and styles. It includes features such as font rasterization and text shaping.
  • Platform Channels: Flutter’s engine also manages communication with native platform code through platform channels, allowing Flutter apps to access native features like camera, geolocation, and more.

The Flutter Rendering Pipeline: How the UI is Drawn

One of the most interesting aspects of Flutter’s architecture is its custom rendering pipeline. Unlike many mobile UI frameworks, Flutter does not rely on the native platform’s rendering system. Instead, it builds its UI using its own set of widgets, which it then renders via Skia. Let’s walk through the rendering pipeline step by step:

1. Widget Creation

In Flutter, everything is a widget. Widgets are the building blocks of the UI, and they describe what should appear on the screen. However, widgets themselves do not draw anything. They are immutable and declarative, meaning that when a widget is updated, it results in a new widget tree being created.

Text("Hello, Flutter!", style: TextStyle(fontSize: 24, color: Colors.blue));

This widget does not actually paint anything on the screen. It simply describes that there should be text with the specified style. Flutter uses a widget tree to manage the app’s UI, where each widget represents a part of the UI (like text, images, buttons, etc.).

2. Element Tree

Widgets are lightweight and immutable. When a widget changes, it doesn’t modify the existing widget directly; instead, it creates a new widget. The Flutter framework converts this widget tree into an Element tree.

An Element is a runtime representation of a widget and holds references to the widget’s state. This allows Flutter to keep track of the UI and the state of each widget efficiently.

3. RenderObject Tree

Once the element tree is established, Flutter transforms it into a RenderObject tree. RenderObjects are the low-level objects responsible for laying out and painting widgets on the screen. They handle the layout of widgets in terms of size and position.

The RenderObject tree can be thought of as a more detailed version of the widget tree, where each object has the responsibility for rendering itself. For instance, a Container widget might be represented as a RenderBox object.

Container(
padding: EdgeInsets.all(8.0),
child: Text("Hello, Flutter!"),
)

In this example, the Container widget would have a corresponding RenderBox that handles the layout and painting of the text and the padding inside.

4. Layout Phase

The layout phase is responsible for determining the size and position of every widget. It starts at the root of the RenderObject tree and moves downward, recursively calculating the layout of each widget.

In the layout phase, each RenderObject must decide its size (width and height) and its position relative to its parent and children. Flutter’s layout system is highly flexible, allowing widgets to behave in a variety of ways (e.g., wrapping, expanding, or aligning).

Here’s an example of a Column widget containing two children

Column(
children: [
Text("First Item"),
Text("Second Item"),
],
)

During the layout phase, the Column will calculate the size and position of the two Text widgets, aligning them vertically.

5. Paint Phase

Once the layout phase is completed, Flutter enters the paint phase. This is when the actual drawing happens. In this phase, each RenderObject will paint itself onto the screen using the Canvas API.

For example, the Text widget will use Skia’s text rendering capabilities to draw the text, while a Container might use a rectangle to render its background.

renderBox.paint(canvas, offset);

In this code, renderBox is the RenderObject associated with the widget, and paint() is responsible for drawing the widget onto the screen.

6. Compositing

Once the widgets are painted, Flutter may need to combine the rendered layers into a single image that can be displayed on the screen. This process is called compositing.

Flutter uses a layered compositing system to combine multiple layers of UI elements. This allows Flutter to optimize the rendering process, ensuring that only the parts of the screen that have changed need to be redrawn.

For example, if a Container widget changes, only that widget’s layer will be re-rendered, not the entire screen.


Layers

Layers are an important concept of the Flutter framework, which are grouped into multiple categories in terms of complexity and arranged in the top-down approach. The topmost layer is the UI of the application, which is specific to the Android and iOS platforms. The second topmost layer contains all the Flutter native widgets. The next layer is the rendering layer, which renders everything in the Flutter app. Then, the layers go down to Gestures, foundation library, engine, and finally, core platform-specific code. The following diagram specifies the layers in Flutter app development.


Skia: The Graphics Engine Behind Flutter

One of the central pillars of Flutter’s performance and rendering capabilities is Skia, an open-source 2D graphics library that powers much of Flutter’s graphical rendering. Skia provides an efficient and flexible framework for drawing complex visual elements such as text, images, shapes, and animations on the screen. It is a low-level graphics engine used by both Android and Chrome, but Flutter leverages it as its primary means of rendering UI content. Skia’s high-performance rendering system is one of the main reasons Flutter apps can run so smoothly across platforms.

Key Features of Skia in Flutter

Here are the most crucial features of Skia, which are leveraged by Flutter to render high-performance graphics:

  • Cross-Platform Rendering: Skia is platform-agnostic, meaning it can be used across various platforms, including Android, iOS, macOS, Linux, and Windows. Since Flutter relies on Skia for rendering, it can ensure consistent visual fidelity across all platforms.
  • Low-Level Graphics API: Skia provides a low-level API to interact with 2D drawing primitives like paths, text, and bitmaps. Flutter interacts with Skia using this API to render widgets and layouts to the screen efficiently.
  • GPU Acceleration: One of the most important aspects of Skia’s performance is its ability to leverage GPU acceleration for rendering tasks. Skia uses OpenGL, Vulkan, Metal, and other platform-specific graphics APIs to offload rendering to the GPU, which makes rendering smoother and more efficient, particularly when dealing with animations and complex visual effects.
  • Vector Graphics: Skia supports vector graphics, which means that the visual elements drawn on the screen can be scaled up or down without losing quality. This is particularly important for Flutter apps, as it ensures that the UI looks crisp on devices with varying screen sizes and resolutions.
  • High-Performance Text Rendering: Skia comes with a robust text rendering engine capable of high-performance text layout, including the ability to handle complex scripts, kerning, text alignment, and font rasterization. Flutter uses Skia’s text rendering capabilities for all its text-based widgets, ensuring that text is drawn accurately and efficiently.
  • Image Rendering: Skia is responsible for rendering images in Flutter as well. Whether it’s raster images (like PNGs, JPEGs) or vector images (like SVGs), Skia is used to efficiently display these images with high performance. It also supports hardware-accelerated image manipulation, which makes operations like image scaling and transformations fast and efficient.

Skia handles the low-level drawing operations, while Flutter’s engine controls the rendering pipeline, managing the communication between the Dart code and Skia.


Dart and Skia: How They Communicate

Flutter’s use of Dart for the business logic of the application and Skia for rendering might seem like a disconnect, but thanks to the Flutter engine, these two layers work together seamlessly. The engine acts as a bridge between the high-level Dart code and the low-level Skia rendering commands.

When you write your Flutter app using Dart, you’re primarily working with Widgets that describe the structure and behavior of your UI. However, once the widget tree is constructed, the Flutter engine translates these high-level descriptions into low-level rendering commands that Skia can process.

The Dart VM and Skia work together to make sure Flutter’s rendering pipeline runs smoothly. The Dart code, running in the Dart VM, is responsible for creating the widget tree and managing the app’s state. When a widget needs to be drawn, the Dart code interacts with the Flutter engine, which then communicates with Skia to render the widget to the screen.

Dart communicates with Skia through the Flutter engine, which acts as a bridge. The engine converts the high-level widget description in Dart into low-level drawing commands that Skia can understand. Skia, in turn, takes care of the actual drawing operations, using GPU resources when available to speed up rendering.

This separation allows Flutter to remain efficient while providing developers with a high-level declarative API to build UIs. By abstracting away the details of low-level rendering, Flutter enables developers to focus on building beautiful and performant apps without needing to worry about graphics rendering details.

How Dart and Skia Communicate:

  • Dart VM: When you write Dart code, it’s compiled by the Dart VM. During development, Just-In-Time (JIT) compilation is used, which makes hot-reloading possible. In production, Ahead-Of-Time (AOT) compilation ensures faster startup times and better performance.
  • Flutter Engine: The engine contains a C++ layer that acts as an intermediary between Dart and Skia. It translates the layout and painting instructions from Dart into commands that Skia can process.
  • Skia: Skia is where the actual drawing happens. It interacts with the hardware through GPU APIs (like OpenGL, Vulkan, and Metal) to render the graphics and text to the screen. The Canvas API in Flutter acts as a wrapper around Skia’s lower-level functions, allowing you to draw shapes, images, and text.

For instance, when you call a setState() method in your Flutter app, which causes the widget tree to rebuild, Flutter’s engine will rebuild the RenderObject tree, and any changes to the layout or appearance of the UI will be communicated to Skia to be redrawn.

For example, consider the following Flutter widget that draws a circle:

CustomPaint(
size: Size(200, 200),
painter: CirclePainter(),
)

The CirclePainter class would extend the CustomPainter class and override the paint method to draw the circle using Skia’s Canvas:

class CirclePainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.blue
..style = PaintingStyle.fill;
canvas.drawCircle(Offset(size.width / 2, size.height / 2), 50, paint);
}

@override
bool shouldRepaint(CustomPainter oldDelegate) {
return false;
}
}

Example: Flutter and Skia for Custom Drawing

Consider a scenario where you want to draw a custom shape (say, a custom circle) using Flutter’s CustomPainter class. The CustomPainter allows you to use Skia’s rendering API to draw shapes directly onto the screen. Here’s an example of how you might do this:

class CirclePainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.blue
..style = PaintingStyle.fill;

// Drawing a circle using Skia's Canvas API
canvas.drawCircle(Offset(size.width / 2, size.height / 2), 50, paint);
}

@override
bool shouldRepaint(CustomPainter oldDelegate) {
return false; // We don't need to repaint unless the custom painter logic changes
}
}

class MyCustomPaintWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CustomPaint(
painter: CirclePainter(),
size: Size(200, 200), // Size of the area to paint
);
}
}

In this example:

  • CustomPainter extends CustomPainter and overrides the paint() method, which is called to render the widget.
  • Canvas is used to draw the circle. Internally, the drawCircle method uses Skia’s API to paint the circle onto the screen.
  • The Paint object specifies the color and the style of the drawing.

Skia is at the heart of this process, enabling Flutter to draw the custom shapes using optimized, low-level rendering routines.


Deep Dive into Flutter’s Rendering Pipeline

Now, let’s go even deeper into understanding how Flutter’s rendering pipeline works and how it helps Flutter achieve its high performance. The rendering pipeline is the series of steps that take place after the widget tree is built and before the app’s UI is displayed on the screen. This process allows Flutter to efficiently transform widget descriptions into pixel-perfect visuals, and it involves key components like Widget Trees, Element Trees, RenderObject Trees, Layout, Painting, and Compositing.

Each of these steps plays a crucial role in ensuring that Flutter apps perform well, even when complex UIs and animations are involved.

Widget Tree to RenderObject Tree: The Transformative Process

The journey from a simple Text widget to a rendered element on the screen starts with the widget tree. Each widget defines part of the UI (e.g., a button, text field, etc.). When a widget is placed inside another widget, Flutter’s framework begins by converting the widget tree into an Element tree and then into a RenderObject tree.

Widget Tree

The widget tree is a hierarchy of Flutter widgets that are declarative descriptions of the UI. Widgets are lightweight and immutable, meaning that when a widget changes, it creates a new widget. For example, if the text in a Text widget changes, the widget tree is recreated with the new text value.

Element Tree

The Element tree is a more efficient representation of the widget tree that exists at runtime. Each Element corresponds to a widget in the widget tree and stores references to its state. Unlike widgets, which are immutable, elements can have state, making them ideal for managing the UI’s changes during execution.

RenderObject Tree

The RenderObject tree is the most crucial part of the rendering pipeline. The RenderObject represents the visual elements that Flutter needs to draw on the screen. Every RenderObject has properties such as size, position, paint, and layout constraints that help it define how the widget should appear and behave. The RenderObject tree is responsible for rendering the app’s UI and handles tasks such as layout and painting.


Layout Phase: Determining Size and Position

The layout phase of the Flutter rendering pipeline determines the size and position of each widget on the screen. During this phase, each RenderObject must figure out its size based on its parent’s constraints and the available space in the layout.

The layout phase is hierarchical. It starts from the root of the tree and recursively processes each child. Here’s how the layout process works:

  1. Parent Constraints: The parent widget gives constraints to its child. For example, if you have a Row widget with two Text widgets inside, the Row widget determines how much space the child widgets can occupy.
  2. Size Determination: Each child widget (RenderObject) will calculate its size based on these constraints. For example, if the parent widget is a Column, it might impose constraints that tell its children to expand vertically, or if the parent is a Row, the children might be constrained to expand horizontally.
  3. Positioning: After each child widget determines its size, Flutter positions the widgets in the layout tree by calculating their offsets (x and y positions). This ensures that each widget is placed correctly on the screen relative to its parent.

In a typical Column widget, for example, each child is positioned vertically, with padding and spacing taken into account during the layout phase.

Column(
children: [
Padding(
padding: EdgeInsets.all(10),
child: Text("Hello, Flutter!"),
),
RaisedButton(
onPressed: () {},
child: Text("Press Me"),
),
],
)

Here, during the layout phase, the Column widget will position each child vertically, taking into account the padding for the first Text widget and the space needed for the RaisedButton.


Paint Phase: Rendering Visuals to the Screen

The paint phase is when the actual drawing happens. After the layout phase has calculated where each widget should be positioned, it’s time to paint the widgets. This phase utilizes the Canvas API, which is where Skia comes into play.

The Canvas is a central component of Flutter’s rendering system, and it provides methods to draw shapes, text, images, and more. Each RenderObject can paint itself on the canvas by calling specific methods.

For example, a simple Container widget might use a RenderBox to draw a rectangle, while a Text widget might use a text drawing method.

Example: Custom Painter for Drawing Shapes

Let’s look at a basic example where we use a CustomPainter to draw a shape (circle) on the screen.

class CirclePainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.blue
..style = PaintingStyle.fill;
canvas.drawCircle(Offset(size.width / 2, size.height / 2), 50, paint);
}

@override
bool shouldRepaint(CustomPainter oldDelegate) {
return false;
}
}

In this example, the CirclePainter class extends CustomPainter. The paint method is where the actual drawing happens. Here, we are using Skia’s canvas.drawCircle method to draw a blue circle at the center of the given size. This is an example of how Flutter uses the Canvas API to interact with Skia to render graphics on the screen.


Compositing: Combining Layers for Efficient Rendering

Once the widgets are painted, Flutter enters the compositing phase, where it combines different layers of the UI into a single image to be displayed on the screen. Flutter’s compositing system ensures that only the parts of the screen that need to be updated are redrawn.

In this phase, Flutter uses a layered compositing model, where each widget’s painted output is stored in a layer. These layers are then composited into a single image that will be displayed on the screen. The advantage of this approach is that Flutter only re-renders the portions of the screen that have changed, rather than redrawing the entire screen.

For instance, if a button changes color on tap, only the button’s layer needs to be updated, not the entire screen. This results in significant performance gains, especially in complex applications with many UI elements.

Here’s an example of how layers can be used for custom painting with CustomPaint:

CustomPaint(
painter: CirclePainter(),
)

When Flutter draws the CirclePainter, the painted content is stored in a layer. If this layer needs to be updated (for instance, if the circle’s position or color changes), only this layer is recomposited. This makes Flutter apps extremely efficient when updating the UI.


Conclusion

Understanding the internals of Flutter’s architecture, its custom rendering pipeline, and the relationship between Dart and Skia is crucial for developers aiming to fully leverage Flutter’s capabilities. Flutter’s approach to UI rendering, with a custom pipeline based on Skia, enables it to deliver high performance and consistent results across platforms. This architecture not only makes Flutter fast and flexible but also empowers developers to create sophisticated UIs with full control over rendering.

By learning about the engine, the rendering process, and how Flutter draws widgets on screen, you can optimize your Flutter apps further, troubleshoot performance issues, and even build custom rendering solutions when needed.


At What the Flutter, we love working with Flutter apps to make them high-performing that delight users. Contact us today to discuss how we can optimize your Flutter app performance.

❤ ❤ Thanks for reading this article ❤❤

If I got something wrong? Let me know in the comments. I would love to improve.

Clap 👏 If this article helps you.


References:

https://www.javatpoint.com/flutter-architecture#:~:text=In%20Flutter%2C%20the%20application%20is,complex%20user%20interface%20very%20easily.

Flutter architectural overview
A high-level overview of the architecture of Flutter, including the core principles and concepts that form its design.docs.flutter.dev

Flutter’s Architecture Explained
We explore the intricacies of Flutter’s architecture, divided into three primary layers: the Framework, the Engine, and…somniosoftware.com


From Our Parent Company Aeologic

Aeologic Technologies is a leading AI-driven digital transformation company in India, helping businesses unlock growth with AI automation, IoT solutions, and custom web & mobile app development. We also specialize in AIDC solutions and technical manpower augmentation, offering end-to-end support from strategy and design to deployment and optimization.

Trusted across industries like manufacturing, healthcare, logistics, BFSI, and smart cities, Aeologic combines innovation with deep industry expertise to deliver future-ready solutions.

Feel free to connect with us:
 And read more articles from FlutterDevs.com.

FlutterDevs team of Flutter developers to build high-quality and functionally-rich apps. Hire a Flutter developer for your cross-platform Flutter mobile app project hourly or full-time as per your requirement! For any flutter-related queries, you can connect with us on Facebook, GitHub, Twitter, and LinkedIn.

We welcome feedback and hope that you share what you’re working on using #FlutterDevs. We truly enjoy seeing how you use Flutter to build beautiful, interactive web experiences.

Related: Flutter V.I.P.E.R Pattern Architecture

Related: SMS Using Twilio In Flutter

Related: Using SharedPreferences in Flutter

Need expert help building your Flutter app? Talk to FlutterExperts for architecture, development, and consulting support.

How to use Riverpod for password visibility in Flutter 2026

0

This article will explore the Show/Hide Password Using Riverpod In Flutter. We will implement a demo program and I would like to show how to show/hide password in TextFormField by using the Riverpod state management in your flutter applications.

If you’re looking for the best Flutter app development company for your mobile application then feel free to contact us at — support@flutterdevs.com.

For Hooks Riverpod:

hooks_riverpod | Flutter Package
Run this command: With Flutter: $ flutter pub add hooks_riverpod This will add a line like this to your package’s…pub.dev

Table Of Contents::

Introduction

Implementation

Code Implement

Code File

Conclusion



Introduction:

This demo video shows how to show/hide passwords in textformfield in flutter and how a show/hide password will work using the hooks_riverpod package in your flutter applications. We will show a user show/hide password on a textformfield by using riverpod and also use will once we click outside of the TextFormField keyboard will close. It will be shown on your device.

Demo Module ::


Implementation:

Step 1: Add the dependencies

Add dependencies to pubspec — yaml file.

dependencies:
flutter:
sdk: flutter
hooks_riverpod: ^latest version

Step 2: Add the assets

Add assets to pubspec — yaml file.

assets:
- assets/

Step 3: Import

import 'package:hooks_riverpod/hooks_riverpod.dart';

Step 4: Run flutter packages get in the root directory of your app.

How to implement code in dart file :

You need to implement it in your code respectively:

Create a new dart file called main.dart inside the lib folder.

We should adjust our main. dart file. We want to add ProviderScope to the root of our application that stores the state of the Providers.

void main() {
runApp(
const ProviderScope(child: MyApp()),
);
}

Then, we need to change StatelessWidget to ConsumerWidget. Once we do that, we must add WidgetRef inside of the build.

class MyApp extends ConsumerWidget {
const MyApp({Key? key}) : super(key: key);

@override
Widget build(BuildContext context, WidgetRef ref) {
final bool showPassState = ref.watch(showPassProvider);
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.cyan,
),
debugShowCheckedModeBanner: false,
home: const Splash(),
);
}
}

Now time to create our StateProvider.

This is the provider we will use for show and hide.

final showPassProvider = StateProvider<bool>((ref) => true);

Now we will create a new class HomeScreen with extended ConsumerWidget. We will return the GestureDetector widget. In this widget, we will add a Column widget. And ad two textformfield.

class HomeScreen extends ConsumerWidget {
const HomeScreen({Key? key}) : super(key: key);

@override
Widget build(BuildContext context, WidgetRef ref) {
final bool showPassState = ref.watch(showPassProvider);
return GestureDetector(
onTap: FocusManager.instance.primaryFocus?.unfocus,
child: Scaffold(
appBar: AppBar(
title: const Text(
"Flutter Show/Hide Password Riverpod Demo",
style: TextStyle(fontSize: 18,color: Colors.white),
),
backgroundColor: Colors.cyanAccent.withOpacity(.4),
automaticallyImplyLeading: false,
centerTitle: true,
),
body: Column(
children: [
Image.asset("assets/logo.png",height: 240,width: 280,),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
decoration: const InputDecoration(
prefixIcon: Icon(Icons.person),
labelText: "Username",
hintText: "Username",
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(20),
),
),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
obscureText: showPassState,
decoration: InputDecoration(
suffixIcon: IconButton(
icon: showPassState
? const Icon(Icons.visibility_off)
: const Icon(Icons.visibility),
onPressed: () => ref
.read(showPassProvider.notifier)
.update((state) => !state),
),
prefixIcon: const Icon(Icons.lock),
labelText: "Password",
hintText: "Password",
border: const OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(20),
),
),
),
),
),
],
),
),
);
}
}

Since obscureText is true in the beginning. We will set showPassState in obscureText.

TextFormField(
// hide the password. when it is true.
obscureText: showPassState,
...

Then, at that point, we ought to update our state for symbol click. To do that We involved IconButton in our suffixIcon. That’s what to do, we ought to read and afterward call the update function on the notifier, and we need to change our Icon concerning our state.

IconButton(
icon: showPassState
? const Icon(Icons.visibility_off)
: const Icon(Icons.visibility),
onPressed: () => ref
.read(showPassProvider.notifier)
.update((state) => !state),
),

When we run the application, we ought to get the screen’s output like the underneath screen capture.

Final Output

Code File:

import 'package:flutter/material.dart';
import 'package:flutter_show_hide_password_riverpod_demo/splash_screen.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

final showPassProvider = StateProvider<bool>((ref) => true);

void main() {
runApp(
const ProviderScope(child: MyApp()),
);
}

class MyApp extends ConsumerWidget {
const MyApp({Key? key}) : super(key: key);

@override
Widget build(BuildContext context, WidgetRef ref) {
final bool showPassState = ref.watch(showPassProvider);
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.cyan,
),
debugShowCheckedModeBanner: false,
home: const Splash(),
);
}
}

class HomeScreen extends ConsumerWidget {
const HomeScreen({Key? key}) : super(key: key);

@override
Widget build(BuildContext context, WidgetRef ref) {
final bool showPassState = ref.watch(showPassProvider);
return GestureDetector(
onTap: FocusManager.instance.primaryFocus?.unfocus,
child: Scaffold(
appBar: AppBar(
title: const Text(
"Flutter Show/Hide Password Riverpod Demo",
style: TextStyle(fontSize: 18,color: Colors.white),
),
backgroundColor: Colors.cyanAccent.withOpacity(.4),
automaticallyImplyLeading: false,
centerTitle: true,
),
body: Column(
children: [
Image.asset("assets/logo.png",height: 240,width: 280,),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
decoration: const InputDecoration(
prefixIcon: Icon(Icons.person),
labelText: "Username",
hintText: "Username",
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(20),
),
),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
obscureText: showPassState,
decoration: InputDecoration(
suffixIcon: IconButton(
icon: showPassState
? const Icon(Icons.visibility_off)
: const Icon(Icons.visibility),
onPressed: () => ref
.read(showPassProvider.notifier)
.update((state) => !state),
),
prefixIcon: const Icon(Icons.lock),
labelText: "Password",
hintText: "Password",
border: const OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(20),
),
),
),
),
),
],
),
),
);
}
}

Conclusion:

In the article, I have explained the Show/Hide Password Using Riverpod in a flutter; you can modify this code according to your choice. This was a small introduction to Show/Hide Password Using Riverpod On User Interaction from my side, and it’s working using Flutter.

I hope this blog will provide you with sufficient information on Trying the Show/Hide Password Using Riverpod in your flutter projectsWe will show you what the Introduction is. Make a demo program for working on show/hide password in TextFormField Using the hooks_riverpod package in your flutter applications. So please try it.

❤ ❤ Thanks for reading this article ❤❤

If I got something wrong? Let me know in the comments. I would love to improve.

Clap 👏 If this article helps you.


From Our Parent Company Aeologic

Aeologic Technologies is a leading AI-driven digital transformation company in India, helping businesses unlock growth with AI automation, IoT solutions, and custom web & mobile app development. We also specialize in AIDC solutions and technical manpower augmentation, offering end-to-end support from strategy and design to deployment and optimization.

Trusted across industries like manufacturing, healthcare, logistics, BFSI, and smart cities, Aeologic combines innovation with deep industry expertise to deliver future-ready solutions.

Feel free to connect with us:
And read more articles from FlutterDevs.com.

FlutterDevs team of Flutter developers to build high-quality and functionally-rich apps. Hire a flutter developer for your cross-platform Flutter mobile app project on an hourly or full-time basis as per your requirement! You can connect with us on FacebookGitHubTwitter, and LinkedIn for any flutter-related queries.

We welcome feedback and hope you share what you’re working on using #FlutterDevs. We truly enjoy seeing how you use Flutter to build beautiful, interactive web experiences.

Related: Basics of Riverpod | Flutter

Related: Dialog Using GetX in Flutter

Need expert help building your Flutter app? Talk to FlutterExperts for architecture, development, and consulting support.


Explore Memory Leaks In Flutter

0

In this article, we will Explore Memory Leaks In Flutter. We perceive how to execute a demo program. We will show you what is the reason, detect, and prevent memory leaks in your Flutter applications.

If you’re looking for the best Flutter app development company for your mobile application then feel free to contact us at — support@flutterdevs.com.


Table Of Contents::

What Is a Memory Leaks?

What Reasons For Memory Leaks In Flutter?

How To Detect Memory Leak In Flutter?

How To Prevent Memory Leaks In Flutter?

Conclusion



What Is a Memory Leaks?

Memory leaks in Flutter applications can happen when a program holds memory that is not generally required, making the application consume more memory than needed. One common reason is the presence of unused objects that stay in memory due to caching, improper disposal, or failure to remove listeners. This can prompt slower execution, crashes, and eventually, an unsuitable user experience.

Abusing streams, which are utilized to deal with asynchronous events in Flutter, can likewise prompt memory leaks on the off chance that stream subscriptions are not as expected dropped, making the stream keep running behind the background and consuming memory. Besides, stacking enormous pictures and videos without delivering them properly can add to memory leaks in Flutter applications.

What Reasons For Memory Leaks In Flutter?

Memory Leaks might happen for some reasons. Here are the absolute most normal reasons.

  • > Unused Objects — For this reason, unused objects that are unclosed streams are the circumstances when we make the stream yet neglect to close it. Streams can keep references to objects in memory even after they are not generally utilized causing memory leaks.
import 'dart:async';
void main() {
StreamController<String> _streamSub = StreamController<String>();
  _streamSub.add("Flutter, Devs!");
  _streamSub.stream.listen((data) {
print("stream data: $data");
});
}

Other, unused objects that are not taken out from memory can cause memory leaks. This is because the items consume space in memory, even though they are not generally needed. Unused objects can be made for different reasons, for example, caching, not appropriately disposing of objects, and not eliminating listeners when they are not generally required.

  • > Improper Use of Streams — For this reason, streams are utilized in Flutter to deal with asynchronous events, and improper utilization of streams can cause memory leaks. For instance, not appropriately canceling a stream subscription can make the stream keep running behind the background, consuming memory.
  • > Global Variables — For this reason, the garbage collector doesn’t work while putting away references to objects or widgets as global variables. So we need to deallocate that memory as it can likewise cause memory leaks.
  • > Large Images and Videos — For this reason, loading enormous images and videos can likewise cause memory leaks in Flutter. At the point when huge files are stacked, they take up a lot of memory, and on the off chance that they are not as expected delivered when they are not generally required, they can cause memory leaks.
  • >Widget Trees — For this reason, mistakenly putting the widgets on the widget tree, particularly while utilizing the stateful widget can likewise cause memory leaks in Flutter.

How To Detect Memory Leak In Flutter?

Recognizing memory leaks in your Flutter application can be a bit challenging yet it is conceivable. The following are a few strategies and tools that can distinguish and fix memory leaks in the Flutter Application.

  • > Flutter DevTools — Flutter DevTools is a performance and debugging tool for Dart programs and Flutter Applications. You can utilize Flutter DevTools to look at your application’s memory usage. You can get to the Flutter DevTools by running the following command:
flutter pub global run devtools
  • > Heap Snapshots — You can likewise take heap snapshots to look at the memory utilization and breaks at a particular point in time. Heap Snapshots can assist you with recognizing objects that are not being garbage collected as expected.
  • > Analyze Your Code — You should review your code and give close consideration to objects. Now check assuming that the objects are appropriately disposed of when they are not generally required. You should likewise check for the controller as they are one of the most well-known reasons for memory leaks in Flutter.

How To Prevent Memory Leaks In Flutter?

  • > Dispose of Objects — One of the best ways of forestalling memory spills in Ripple is to discard objects when they are not generally required. Discarding objects eliminates them from memory and opens up assets for different pieces of the application. To discard objects, utilize the arrange technique in the Stateful Gadget.
  • > Use Streams Properly — To prevent memory leaks caused by streams, consistently cancel the subscription when it is not generally required. This guarantees that the stream is done running behind the background, consuming memory.
  • > Use Images and Videos Efficiently — To prevent memory leaks influenced by enormous images and videos, utilize efficient techniques to load them. One such strategy is to utilize the flutter_cache_manager package, which assists with caching images and videos, reducing the amount of memory they consume.
  • Use Profiling Tools — Profiling tools, like the Flutter DevTools, can assist with recognizing memory leaks in your application. By analyzing the memory utilization of your application, you can pinpoint the areas that are causing memory leaks and do whatever it takes to fix them.
  • > Avoid Saving Flutter Object References in Background Threads — To prevent memory leaks, refrain from putting Flutter object references in background threads. All things being equal, utilize weak references or isolate communication mechanisms like message passing. Weak references enable objects to be garbage collected when they are no longer strongly referenced, preventing memory leaks. Isolate communication ensures that Flutter objects can be safely passed between isolates without retaining strong references, further guarding against memory leaks.

Conclusion:

In the article, I have explained the Memory Leaks In Flutter; you can modify this code according to your choice. This was a small introduction to the Memory Leaks In Flutter User Interaction from my side, and it’s working using Flutter.

I hope this blog will provide you with sufficient information on Trying the Memory Leaks In Flutter in your Flutter projectsMemory leaks are a typical issue in Flutter, however, they can be prevented by following best practices and utilizing the appropriate tools. By disposing of objects, utilizing streams appropriately, and efficiently loading images and videos, developers can prevent memory leaks and make high-performing applications that provide an ideal user experience.

Remember to use profiling tools to recognize memory leaks in your application, and do whatever it may take to fix them. With these tips, you can build Flutter applications that are quick, efficient, and reliable.

❤ ❤ Thanks for reading this article ❤❤

If I need to correct something? Let me know in the comments. I would love to improve.

Clap 👏 If this article helps you.


From Our Parent Company Aeologic

Aeologic Technologies is a leading AI-driven digital transformation company in India, helping businesses unlock growth with AI automation, IoT solutions, and custom web & mobile app development. We also specialize in AIDC solutions and technical manpower augmentation, offering end-to-end support from strategy and design to deployment and optimization.

Trusted across industries like manufacturing, healthcare, logistics, BFSI, and smart cities, Aeologic combines innovation with deep industry expertise to deliver future-ready solutions.

Feel free to connect with us:
And read more articles from FlutterDevs.com.

FlutterDevs team of Flutter developers to build high-quality and functionally-rich apps. Hire a Flutter developer for your cross-platform Flutter mobile app project on an hourly or full-time basis as per your requirement! For any flutter-related queries, you can connect with us on FacebookGitHubTwitter, and LinkedIn.

We welcome feedback and hope that you share what you’re working on using #FlutterDevs. We truly enjoy seeing how you use Flutter to build beautiful, interactive web experiences.

Related: Explore Exception Handling In Flutter

Need expert help building your Flutter app? Talk to FlutterExperts for architecture, development, and consulting support.


How to Implement Theming with Riverpod in Flutter 2026

0

Themes are a subject group frequently discussed while making applications. The most usually utilized term in regards to this point would be ‘dark theme’. You can frequently see individuals requesting how to deal with a dark theme in your application or any event, similar to requesting how to oversee various symbols for various themes.

Flutter has, however, greatly eased the process of customizing themes and their components. In this article, we will explore how to implement theming using Riverpod state management in your Flutter applications.

In this tutorial, I only show you how to change the theme according to system mode using the Switch button.

For Hooks Riverpod:

hooks_riverpod | Flutter Package
Run this command: With Flutter: $ flutter pub add hooks_riverpod This will add a line like this to your package’s…pub.dev

If you’re looking for the best Flutter app development company for your mobile application then feel free to contact us at — support@flutterdevs.com.


Table Of Contents::

Introduction

Implementation

Code Implement

Conclusion



Introduction:

This demo video shows how to implement theming theme in Flutter and shows how a theming will work using the hooks_riverpod package in your Flutter applications. We will show a user switches the button then the theme will be changed from light mode to dark mode/vice versa. It will be shown on your device.

Demo Module::


Implementation:

Step 1: Add the dependencies

Add dependencies to pubspec — yaml file.

dependencies:
flutter:
sdk: flutter
hooks_riverpod: ^latest version

Step 2: Add the assets

Add assets to pubspec — yaml file.

assets:
- assets/

Step 3: Import

import 'package:hooks_riverpod/hooks_riverpod.dart';

Step 4: Run flutter packages get in the root directory of your app.

How to implement code in dart file :

You need to implement it in your code respectively:

Create a new dart file called themes.dart inside the lib folder.

First, let’s create our darkTheme and Light Theme. To do that, we can create a new class called themes. dart.

import 'package:flutter/material.dart';

class Themes {
static final lightTheme = ThemeData(
brightness: Brightness.light, // For light theming
scaffoldBackgroundColor: Colors.grey.shade100,
appBarTheme: AppBarTheme(
backgroundColor: Colors.grey.shade100,
titleTextStyle: const TextStyle(color: Colors.black, fontSize: 12),
centerTitle: false),
// you can add more
);

static final darkTheme = ThemeData(
brightness: Brightness.dark, // For dark theming
scaffoldBackgroundColor: Colors.grey.shade900,
appBarTheme: const AppBarTheme(
backgroundColor: Color(0x00049fb6),
titleTextStyle: TextStyle(color: Colors.white, fontSize: 18),
centerTitle: false),
// you can add more
);

}

Create a new dart file called themes_provider.dart inside the lib folder.

Let’s create our provider file to do that we can create themes_provider.dart. In this example, we will use StateNotifier.

import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

final themesProvider = StateNotifierProvider<ThemesProvider, ThemeMode?>((_) {
return ThemesProvider();
});

class ThemesProvider extends StateNotifier<ThemeMode?> {
ThemesProvider() : super(ThemeMode.system);
void changeTheme(bool isOn) {
state = isOn ? ThemeMode.dark : ThemeMode.light;
}
}

Create a new dart file called main.dart inside the lib folder.

Now, time to create our main. dart file. We should extend ConsumerWidget instead of StatelessWidget to use WidgetRef. Also, ensure you add the root of our app ProviderScope as shown below. Otherwise, you are not going to be able to use providers.

Presently, time to make our main. dart file. We ought to extend ConsumerWidget rather than StatelessWidget to utilize WidgetRef. Likewise, ensure you add the root of our application ProviderScope as displayed underneath. If not, you won’t have the option to utilize providers.

import 'package:flutter/material.dart';
import 'package:flutter_theming_riverpord_demo/splash_screen.dart';
import 'package:flutter_theming_riverpord_demo/themes.dart';
import 'package:flutter_theming_riverpord_demo/themes_provider.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

void main() {
runApp(
const ProviderScope(child: MyApp()),
);
}


class MyApp extends ConsumerWidget {
const MyApp({
super.key,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
final themeModeState = ref.watch(themesProvider);
return MaterialApp(
theme: Themes.lightTheme,
darkTheme: Themes.darkTheme,
themeMode:themeModeState,
debugShowCheckedModeBanner: false,
home: const Splash(),
);
}
}

Create a new dart file called home_screen.dart inside the lib folder.

Lastly, we need to create our HomeScreen(). To do that we create a home_screen.dart file. And as I said before you can create everything into maindart. We use Switch Widget to change

import 'package:flutter/material.dart';
import 'package:flutter_theming_riverpord_demo/themes_provider.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

class HomeScreen extends ConsumerWidget {
const HomeScreen({
Key? key,
}) : super(key: key);

@override
Widget build(BuildContext context, WidgetRef ref) {
final themeModeState = ref.watch(themesProvider);
return Scaffold(
appBar: AppBar(
title: const Text(
"Flutter Theming Riverpod Demo",
style: TextStyle(fontSize: 18),
),
centerTitle: true,
automaticallyImplyLeading: false,
backgroundColor: Colors.teal,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
"assets/logo.png",
height: 200,
width: 300,
),
Text(
"Change Theme $themeModeState",
style: const TextStyle(fontSize: 18),
),
Consumer(
builder: (context, ref, child) {
return Switch(
value: themeModeState == ThemeMode.dark, //false or true
onChanged: (value) {
ref.read(themesProvider.notifier).changeTheme(value);
});
},
),
],
),
),
);
}
}

When we run the application, we ought to get the screen’s output like the underneath screen capture.

Final Output

Conclusion:

In the article, I have explained the Implement Theming Using Riverpod in a flutter; you can modify this code according to your choice. This was a small introduction to Implementing Theming Using Riverpord On User Interaction from my side, and it’s working using Flutter.

I hope this blog will provide you with sufficient information on Trying the Implement Theming Using Riverpod in your Flutter projectsWe will show you what the Introduction is. Make a demo program for working on implementing Theming Using the hooks_riverpod package in your Flutter applications. So please try it.

❤ ❤ Thanks for reading this article ❤❤

If I got something wrong? Let me know in the comments. I would love to improve.

Clap 👏 If this article helps you.


From Our Parent Company Aeologic

Aeologic Technologies is a leading AI-driven digital transformation company in India, helping businesses unlock growth with AI automation, IoT solutions, and custom web & mobile app development. We also specialize in AIDC solutions and technical manpower augmentation, offering end-to-end support from strategy and design to deployment and optimization.

Trusted across industries like manufacturing, healthcare, logistics, BFSI, and smart cities, Aeologic combines innovation with deep industry expertise to deliver future-ready solutions.

Feel free to connect with us:
And read more articles from FlutterDevs.com.

FlutterDevs team of Flutter developers to build high-quality and functionally-rich apps. Hire a Flutter developer for your cross-platform Flutter mobile app project on an hourly or full-time basis as per your requirement! You can connect with us on FacebookGitHubTwitter, and LinkedIn for any flutter-related queries.

We welcome feedback and hope you share what you’re working on using #FlutterDevs. We truly enjoy seeing how you use Flutter to build beautiful, interactive web experiences.

Related: Show/Hide Password Using Riverpod In Flutter

Related: Basics of Riverpod | Flutter

Related: Dialog Using GetX in Flutter

Need expert help building your Flutter app? Talk to FlutterExperts for architecture, development, and consulting support.


Routing With Fluro In Flutter

Routing or navigating starting with one page and then onto the next page is fundamental for any application. All things considered, when it came to Flutter’s in-constructed routing system, it was quite simple to get a handle on, after a long tutorial and numerous uses in projects.

Then, I utilized Fluro at that point, and I was astounded. If you come from a front-end web development background, you would feel comfortable with how Fluro handles its routes.

This blog will explore the Routing With Fluro In Flutter. We perceive how to execute a demo program. We will learn how to route from one page to another page using the fluro package in your Flutter applications.

If you’re looking for the best flutter app development company for your mobile application then feel free to contact us at — support@flutterdevs.com.

fluro | Flutter Package
English | Português The brightest, hippest, coolest router for Flutter. Simple route navigation Function handlers (map…pub.dev

Table Of Contents::

Introduction

Implementation

Code Implement

Conclusion



Introduction:

The below demo video shows a two-page Home page and a Second page. On the Home page, we will add an elevated button and on the Second page, we will add Floating Action Buttons to navigate to the other page. It will be shown on your devices.

When moving from Home to Second, we require some extra information, such as data, so we pass that as part of the route parameters. So we’ll be learning how to do that through Fluro.

While moving from Home to Second, we require some additional information, like data, so we pass that as a component of the route parameters. So we’ll figure out how to do that through Fluro.

Demo Module::


Implementation:

Step 1: Add the dependencies

Add dependencies to pubspec — yaml file.

dependencies:
flutter:
sdk: flutter
fluro: ^2.0.4

Step 2: Import

import 'package:fluro/fluro.dart';

Step 3: Run flutter packages get in the root directory of your app.

How to implement code in dart file :

You need to implement it in your code respectively:

Create a new dart file called router.dart inside the lib folder.

import 'package:flutter/material.dart';
import 'package:fluro/fluro.dart';
import 'package:flutter_fluro_routing_demo/second_page.dart';
import 'package:flutter_fluro_routing_demo/home_page.dart';

class Routes {
static final router = FluroRouter();

static var firstScreen = Handler(
handlerFunc: (BuildContext? context, Map<String, dynamic> params) {
return const HomePage();
});

static var placeHandler = Handler(
handlerFunc: (BuildContext? context, Map<String, dynamic> params) {
return SecondPage(data: params["data"][0]);
});

static dynamic defineRoutes() {
router.define("home", handler: firstScreen,transitionType: TransitionType.fadeIn);
router.define("second/:data", handler: placeHandler,transitionType: TransitionType.inFromLeft);
}
}

The first line inside the Routes class initializes a static instance of FluroRouter() from the Fluro library.

static final router = FluroRouter();

Then, we have a handler where we deal with highlighting which widget/part must be loaded while visiting a route. You can consider them controllers on the off chance that you are accompanying information from a past framework.

// Handler for Home Page
static var firstScreen = Handler(
handlerFunc: (BuildContext? context, Map<String, dynamic> params) {
return const HomePage();
});
// Handler for Second Page
static var placeHandler = Handler(
handlerFunc: (BuildContext? context, Map<String, dynamic> params) {
return SecondPage(data: params["data"][0]);
});

params[‘data’][0] will return the data sent by the route path and will be sent to the SecondPage as an attribute.

Next, we have a defineRoutes() function, where we will define individual routes and their paths. This is also where we will define any parameters if any. Let’s take a close look at the router.define() function.

static dynamic defineRoutes() {
router.define("home", handler: firstScreen,transitionType: TransitionType.fadeIn);
router.define("second/:data", handler: placeHandler,transitionType: TransitionType.inFromLeft);
}

Create a new dart file called main.dart inside the lib folder.

Now, just pass this function in the initState and you’re good to go.

import 'package:flutter/material.dart';
import 'package:flutter_fluro_routing_demo/router.dart';

void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(const MyApp());
}

class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);

@override
State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

@override
void initState() {
super.initState();
Routes.defineRoutes();
}

@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
initialRoute: 'home',
onGenerateRoute: Routes.router.generator,
);
}
}

Create a new dart file called home_page.dart inside the lib folder.

Navigator.pushReplacementNamed() is a capability that replaces the stack with anything that route you pass to it, so the user can’t return to the past screen by just squeezing the back button.

On the off chance that you would need such usefulness of returning a screen, you can utilize Navigator.pushNamed() with similar attributes.

import 'package:flutter/material.dart';

class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter Fluro Routing Demo'),
centerTitle: true,
backgroundColor: Colors.teal,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Home Page',style: TextStyle(fontSize: 20),),
const SizedBox(height: 20,),
ElevatedButton(
onPressed: () {
var data = "FlutterDevs";
Navigator.pushReplacementNamed(context, 'second/$data');
},
style: ElevatedButton.styleFrom(
onPrimary: Colors.white,
primary: Colors.teal[300],
minimumSize: const Size(88, 36),
padding: const EdgeInsets.symmetric(horizontal: 16),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(2)),
),
),
child: const Text('Press Button'),
),
],
),
),
);
}
}

Create a new dart file called second_page.dart inside the lib folder.

On the Second Page, it’s genuinely straightforward as we need to pass no parameters accordingly, so we simply need to call pushReplacementNamed() once more.

import 'package:flutter/material.dart';
class SecondPage extends StatelessWidget {
const SecondPage({Key? key, required this.data}) : super(key: key);

final String data;


@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Second page'),
centerTitle: true,
backgroundColor: Colors.teal,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset("assets/logo.png",width: 300,height: 250,),
Text('Welcome, $data',style: const TextStyle(fontSize: 20,fontWeight: FontWeight.w700),),
],
),
),
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.teal,
child: const Icon(Icons.settings_backup_restore),
onPressed: () {
Navigator.pushReplacementNamed(context, 'home');
},
),
);
}
}

When we run the application, we ought to get the screen’s output like the underneath screen capture.


Conclusion:

In the article, I have explained Routing With Fluro’s basic structure in a flutter; you can modify this code according to your choice. This was a small introduction to Routing With Fluro On User Interaction from my side, and it’s working using Flutter.

I hope this blog will provide you with sufficient information on Trying the Routing With Fluro in your Flutter projectsWe will show you what the Introduction is. Make a demo program for working Routing With Fluro and you’ve learned how to route from one page to another page using the fluro package in your Flutter applications. So please try it.

❤ ❤ Thanks for reading this article ❤❤

If I got something wrong? Let me know in the comments. I would love to improve.

Clap 👏 If this article helps you.


From Our Parent Company Aeologic

Aeologic Technologies is a leading AI-driven digital transformation company in India, helping businesses unlock growth with AI automation, IoT solutions, and custom web & mobile app development. We also specialize in AIDC solutions and technical manpower augmentation, offering end-to-end support from strategy and design to deployment and optimization.

Trusted across industries like manufacturing, healthcare, logistics, BFSI, and smart cities, Aeologic combines innovation with deep industry expertise to deliver future-ready solutions.

Feel free to connect with us:
And read more articles from FlutterDevs.com.

FlutterDevs team of Flutter developers to build high-quality and functionally-rich apps. Hire a flutter developer for your cross-platform Flutter mobile app project on an hourly or full-time basis as per your requirement! For any flutter-related queries, you can connect with us on FacebookGitHubTwitter, and LinkedIn.

We welcome feedback and hope that you share what you’re working on using #FlutterDevs. We truly enjoy seeing how you use Flutter to build beautiful, interactive web experiences.

Related: Handling Navigation Stacks

Related: Bottom Navigation Bar using Provider | Flutter

Related: Flutter Deep Links – A unique way!

Need expert help building your Flutter app? Talk to FlutterExperts for architecture, development, and consulting support.


Upload, Download, and Delete Images in AWS Amplify Storage with S3 Bucket in Flutter 2024

0

If you’re looking for the best Flutter app development company for your mobile application then feel free to contact us at — support@flutterdevs.com.


Table Of Contents::

Introduction

What is AWS Amplify Storage?

S3 Core Concepts

Prerequisites

Configuration

Best Practices

Conclusion

References


Introduction

Flutter has become one of the most popular frameworks for building cross-platform applications, while AWS Amplify provides an easy and powerful way to add cloud capabilities to your applications. Among Amplify’s many features, Storage with S3 bucket is crucial for managing files like images, videos, and documents.

AWS Amplify storage module provides a simple mechanism for managing user content for your app in public, protected or private storage buckets. The storage category comes with built-in support for Amazon S3 (Simple Storage Service). In this blog, we’ll cover everything you need to integrate AWS Amplify Storage with S3 buckets into your Flutter app, step by step.


What is AWS Amplify Storage?

AWS Amplify is a cloud-based development framework by Amazon Web Services that simplifies building scalable, full-stack applications. The Amplify Storage category integrates with Amazon S3, allowing you to store and retrieve objects like images, audio, videos, and documents securely.


S3 Core Concepts

Amazon S3 stores data as objects within container buckets. An object consists of a file and optionally any metadata that describes that file. To store an object in Amazon S3, you upload the file you want to store to a bucket. When you upload a file, you can set permissions on the object and any metadata.

Buckets are the containers for objects. You can have one or more buckets. For each bucket, you can control access to it (who can create, delete, and list objects in the bucket), view access logs for it and its objects, and choose the geographical region where Amazon S3 will store the bucket and its contents.


Prerequisites

Before diving in, ensure you have the following ready:

  1. AWS Account: Sign up and Setup your AWS account
  2. Node.js: Required to install the Amplify CLI.
  3. Flutter Setup: Ensure Flutter and Dart are installed on your machine.
  4. Amplify CLI: Install globally using npm install -g @aws-amplify/cli.

Configuration

Step 1: Initialize AWS Amplify

Install the Amplify CLI

Run the following command in your terminal:

npm install -g @aws-amplify/cli

This installs the Amplify Command Line Interface (CLI) globally.

Initialize the Amplify Project

Navigate to your Flutter project directory and run:

amplify init
  • Choose Flutter as the framework.
  • Configure your environment and backend details (e.g., name, environment, region, etc.).
  • When prompted, provide the details of your application.

This command sets up Amplify for your project and generates the necessary files.

Step 2: Add the Storage Category

Run the following command to add storage:

amplify add storage
  • Choose “Content (Images, audio, video, etc.)”.
  • Define the resource name (or accept the default).
? Please select from one of the below mentioned services:
> Content (Images, audio, video, etc.)
NoSQL Database
? Please provide a friendly name for your resource that will be used to label this category in the project:
> mystorage
? Please provide bucket name:
> mybucket
  • Set permissions for authenticated and unauthenticated users.
? Restrict access by?
> Auth/Guest Users
Individual Groups
Both
  • Enable Auth/Guest access only if necessary (e.g., public-facing apps).
? Who should have access:
❯ Auth users only
Auth and guest users

Then you’ll be prompted to set the access scopes for your authenticated and (if selected prior) unauthenticated users.

? What kind of access do you want for Authenticated users?
> ◉ create/update
◯ read
◯ delete
? What kind of access do you want for Guest users?
◯ create/update
> ◉ read
◯ delete
  • Push the changes to AWS:
amplify push

This command provisions an S3 bucket and configures it with the necessary policies.

Step 3: Add Dependencies to Your Flutter Project

In your Flutter app’s pubspec.yaml file, add the following dependencies:

dependencies:
amplify_flutter: ^latest
amplify_storage_s3: ^latest

Run flutter pub get to install the packages.

Step 4: Configure Amplify in Your App

To initialize the Amplify Auth and Storage categories, call Amplify.addPlugin() for each plugin or pass all the plugins in Amplify.addPlugins(). To complete initialization, call Amplify.configure().

Your code should look like this:

import 'package:flutter/material.dart';
import 'package:amplify_flutter/amplify_flutter.dart';
import 'package:amplify_storage_s3/amplify_storage_s3.dart';
import 'amplifyconfiguration.dart';

Future<void> _configureAmplify() async {
try {
final auth = AmplifyAuthCognito();
final storage = AmplifyStorageS3();
await Amplify.addPlugins([auth, storage]);

// call Amplify.configure to use the initialized categories in your app
await Amplify.configure(amplifyconfig);
} on Exception catch (e) {
safePrint('An error occurred configuring Amplify: $e');
}
}
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await _configureAmplify();
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('AWS Amplify Storage with S3')),
body: Center(child: Text('Ready to upload files!')),
),
);
}
}

Step 5: Using StoragePath

You can use StoragePath to access, upload to, or download from to any path in your S3 bucket. The Amplify Gen 1 CLI automatically creates the following directories:

  • public/: Accessible by all users of your application
  • protected/<identityId>/: Readable by all users (you need to specify the identityID of the user who uploaded the file). Writable only by the creating user
  • private/<identityId>/: Readable and writable only by the creating user

If you are using Amplify Gen2 or an S3 bucket not created by Amplify, you can use StoragePath to access, upload to, or download from any directory in your bucket.

You can specify the path to your S3 resource by creating a StoragePath directly from a String, or by constructing the path with the user’s Cognito IdentityId.

A StoragePath must:

  1. Not start with a ‘/’ (leading slash)
  2. Not be empty

Create a StoragePath from String

When constructing a StoragePath from a String, the provided string will be the path.

// Resolves to "public/exampleFile.txt"
const StoragePath.fromString('public/exampleFile.txt');

Create a StoragePath with user’s IdentityId

You may want to construct a StoragePath that contains the Amplify Auth user’s IdentityId. We’ve created a helper function that injects the user’s IdentityId when a Storage API is called, since fetching an IdentityId from the Auth plugin is not synchronous.

// If the user's identityId was "123", 
// the StoragePath would resolve to "private/123/exampleFile.txt"
StoragePath.fromIdentityId(
(String identityId) => 'private/$identityId/exampleFile.txt',
};

Step 6: Implement Storage Functions

Upload a File to S3

To upload a Imagefile to S3 bucket, specify the file path and s3 bucket path where you want to store.

You can upload imageFile to a local directory using Amplify.Storage.uploadFile

To upload Image:

From Local File Path (All Platforms)

Future<void> uploadImage(File imageFile) async {
try {
final result = await Amplify.Storage.uploadFile(
localFile: AWSFile.fromPath('imageFile.path'),
path: StoragePath.fromString('public/'+'your-s3-bucket-imagefile-path'),
);
print('Upload successful: ${result.key}');
} catch (e) {
print('Upload failed: $e');
}
}

From File (Mobile & Desktop)

import 'dart:io' show File;

Future<void> uploadImage(File imageFile) async {
try {
final result = await Amplify.Storage.uploadFile(
localFile: AWSFilePlatform.fromFile(imageFile),
path: const StoragePath.fromString('public/imagefile.png'),
).result;
safePrint('Uploaded imagefile: ${result.uploadedItem.path}');
} on StorageException catch (e) {
safePrint(e.message);
}
}

You can call this method with a selected file from your device.

Download a File from S3

You can download file to a local directory using Amplify.Storage.downloadFile

To download a file:

Future<void> downloadImage(String key, String downloadPath) async {
try {
final result = await Amplify.Storage.downloadFile(
path: StoragePath.fromString('public/'+'your-s3-bucket-imagefile-path'),
localFile: AWSFile.fromPath(downloadPath),
).result;
AWSFile awsFile = result.localFile;
path = awsFile.path!; //use this path to show your imagefile in your UI

print('Download successful: ${result.file.path}');
} catch (e) {
print('Download failed: $e');
}
}

This method saves the image file locally to the specified path.

Generate a download URL

You can get a downloadable URL for the image file in storage by its path.

When creating a downloadable URL, you can choose to check if the image file exists by setting validateObjectExistence to true in S3GetUrlPluginOptions. If the file is inaccessible or does not exist, a StorageException is thrown. This allows you to check if an object exists during generating the presigned URL, which you can then use to download that object.

Future<void> getDownloadUrl() async {
try {
final result = await Amplify.Storage.getUrl(
path: const StoragePath.fromString('public/example.txt'),
options: const StorageGetUrlOptions(
pluginOptions: S3GetUrlPluginOptions(
validateObjectExistence: true,
expiresIn: Duration(days: 1),
),
),
).result;
safePrint('url: ${result.url}');
} on StorageException catch (e) {
safePrint(e.message);
}
}

List Files in the S3 Bucket

You can list all files uploaded under a given path.

  1. This will list all public image files(i.e. those with guest access level):
Future<void> listAllImageFiles() async {
try {
final result = await Amplify.Storage.list(
path: const StoragePath.fromString('public/'),
options: const StorageListOptions(
pluginOptions: S3ListPluginOptions.listAll(),
),
).result;
safePrint('Listed items: ${result.items}');
} on StorageException catch (e) {
safePrint(e.message);
}
}

2. This will list all image files located under path album that:

  • have private access level
  • are in the root of album/ (the result doesn’t include files under any sub path)

excludeSubPaths can be used to exclude nested paths. / is used by as the delimiter for nested paths. This can be customized with the delimiter option.

Future<void> listAlbum() async {
try {
String? nextToken;
bool hasNextPage;
do {
final result = await Amplify.Storage.list(
path: const StoragePath.fromString('public/album/'),
options: StorageListOptions(
pageSize: 50,
nextToken: nextToken,
pluginOptions: const S3ListPluginOptions(
excludeSubPaths: true,
delimiter: '/',
),
),
).result;
safePrint('Listed items: ${result.items}');
nextToken = result.nextToken;
hasNextPage = result.hasNextPage;
} while (hasNextPage);
} on StorageException catch (e) {
safePrint(e.message);
}
}

Delete a File from S3

To delete a file:

Future<void> deleteImage(String path) async {
try {
await Amplify.Storage.remove(path: StoragePath.fromString(path));
print('Image deleted successfully: $key');
} catch (e) {
print('Delete failed: $e');
}
}

Best Practices

  1. Secure Access: Use Cognito for managing user access.
  2. Optimize File Handling:
  • Use unique file keys to avoid overwrites.
  • Compress images or videos before uploading.

3. Error Handling: Always handle exceptions to improve user experience.

4. Monitor Costs: Keep track of your S3 bucket usage to avoid unexpected costs.


Conclusion

Integrating AWS Amplify Storage with S3 buckets into your Flutter app is straightforward and highly beneficial for managing files. By following this guide, you can upload, download, list, and delete files seamlessly. Amplify also provides robust security and scalability, making it an excellent choice for modern applications.

Explore further to customize storage configurations, add advanced features like presigned URLs, or integrate other Amplify categories to build a comprehensive cloud-enabled app.


At What the Flutter, we love working with Flutter apps to make them high-performing and delight users. Contact us today to discuss how we can optimize your Flutter app performance.

❤ ❤ Thanks for reading this article ❤❤

If I got something wrong? Let me know in the comments. I would love to improve.

Clap 👏 If this article helps you.


References:

Storage – Flutter – AWS Amplify Gen 1 Documentation
Learn more about how you can manage user content for your app in public, protected or private storage buckets using…docs.amplify.aws

Storage – AWS Amplify Gen 2 Documentation
Set up and connect to storage. AWS Amplify Documentationdocs.amplify.aws


From Our Parent Company Aeologic

Aeologic Technologies is a leading AI-driven digital transformation company in India, helping businesses unlock growth with AI automation, IoT solutions, and custom web & mobile app development. We also specialize in AIDC solutions and technical manpower augmentation, offering end-to-end support from strategy and design to deployment and optimization.

Trusted across industries like manufacturing, healthcare, logistics, BFSI, and smart cities, Aeologic combines innovation with deep industry expertise to deliver future-ready solutions.

Feel free to connect with us:
And read more articles from FlutterDevs.com.

FlutterDevs team of Flutter developers to build high-quality and functionally-rich apps. Hire a flutter developer for your cross-platform Flutter mobile app project on an hourly or full-time basis as per your requirement! For any flutter-related queries, you can connect with us on FacebookGitHubTwitter, and LinkedIn.

We welcome feedback and hope that you share what you’re working on using #FlutterDevs. We truly enjoy seeing how you use Flutter to build beautiful, interactive web experiences.

Related: Dark Mode Implementation

Need expert help building your Flutter app? Talk to FlutterExperts for architecture, development, and consulting support.