One of the most exciting features of Flutter is its ability to create visually stunning applications with the help of a wide range of customizable widgets, which include the ability to add flavors. In this article, we’ll explore flavors in flutter and how they can be used to customize the application for different environments.
Why Flavors in Flutter?
Flavors in Flutter refer to the practice of creating multiple versions of the same application with different configurations. These configurations can include different assets, API endpoints, app icons, and other resources specific to a particular environment. For example, an application that is intended for release on both iOS and Android platforms may need different API endpoints for each platform, and each platform may have different requirements for app icons.
Flavors in Flutter are particularly useful for development teams that need to create multiple versions of the same application for different environments. For example, a team may need to create a production version of an application with different configurations and resources than a development or testing version. With build flavors, developers can easily switch between these different versions and ensure that each version is customized to meet the specific requirements of the target environment.
Suppose you are working on a SAAS product. Let’s assume School System where every school shares almost the same functionality but with different app icons, endpoints, and resources. And you need to upload them to the Play Store. In this case, also flavors in Flutter come in to use. Flavors allow us to create and build apps with different application IDs with their respective data and features.
Final Output:
Step 1: Add dependencies
dependencies:
flutter_riverpod: ^2.3.2
flutter_launcher_icons: ^0.12.0
Step 2: Create Flavors Config
Create a new file named config_flavor.dart
. In this file, we configure, what things to pass in the flavors. So for School A, we want different app titles, icons, images, endpoints e.t.c. and the same for School B.
import 'package:flutter/material.dart';
enum Endpoints { items, details }
class FlavorConfig {
String appTitle;
Map<Endpoints, String>? apiEndpoint;
String imageLocation;
ThemeData? theme;
FlavorConfig({
this.appTitle = "Flavor Tutorial",
this.imageLocation = "assets/images/default_image.jpg",
}) {
this.theme = ThemeData.light();
}
}
Step 3: Configure the existing main.dart
Here we change the main
function to mainCommon
. As the main
is the entry point of the application we configure the flavors here. Also, we are going to use Riverpod
and wrap MyApp
with ProviderScope
.
var flavorConfigProvider;
void mainCommon(FlavorConfig config) {
flavorConfigProvider = StateProvider((ref) => config);
runApp(
ProviderScope(child: MyApp()),
);
}
After that, we extend MyApp
with ConsumerWidget
as we are using Riverpod for state management. Inside the build method of MyApp, we read the flavorConfigProvider. And then give the title from the value coming from flavorConfigProvider.
class MyApp extends ConsumerWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context, ref) {
final config = ref.read(flavorConfigProvider);
return MaterialApp(
title: config.appTitle,
theme: config.theme,
home: MyHomePage(),
debugShowCheckedModeBanner: false,
);
}
}
Similarly, MyApp
we now extend MyHomePage
with ConsumerWidget and get the data from the state.
class MyHomePage extends ConsumerWidget {
@override
Widget build(BuildContext context, ref) {
print(ref.read(flavorConfigProvider.notifier).state.appTitle);
return Scaffold(
appBar: AppBar(
title: Text(ref.read(flavorConfigProvider).appTitle),
),
body: Image.asset(
ref.read(flavorConfigProvider).imageLocation!,
fit: BoxFit.fill,
height: MediaQuery.of(context).size.height,
),
);
}
}
Step 3: Adding assets/images to the project
Create the assets
folder in the root directory of the project. Inside the assets
folder create two directories first is, app_icons
inside where place the logos for different flavors. The second one is, images
inside which we place the images used in the project.
Step 4: Create the different main files for different flavors
The Main is the entry point of the application. So we need to have different entry points with respect to each flavor in Flutter. In our case, we will have two flavors i.e School A and School B. So inside the lib folder, we create two files first is for School A and the second is for School B.
main_school1.dart
void main() {
// Inject our own configurations
// School One
mainCommon(
FlavorConfig()
..appTitle = "School 1"
..apiEndpoint = {
Endpoints.items: "flutterjunction.api.dev/items",
Endpoints.details: "flutterjunction.api.dev/item"
}
..imageLocation = "assets/images/one.png"
..theme = ThemeData.light().copyWith(
primaryColor:const Color(0xFF123456),
appBarTheme: ThemeData.light().appBarTheme.copyWith(
backgroundColor:const Color(0xFF654321),
),
),
);
}
main_school2.dart
void main() {
// Inject our own configurations
// School 2
mainCommon(
FlavorConfig()
..appTitle = "School 2"
..imageLocation = "assets/images/two.png"
..apiEndpoint = {
Endpoints.items: "api.flutterjunction.dev/items",
Endpoints.details: "api.flutterjunction.dev/items"
}
..theme = ThemeData.dark(),
);
}
Step 5: Editing Configurations for flavors in Android Studio
Now we have two main
methods for flavors to run them in different we need to configure the entry points. So for that
Click on Edit Configurations.
Delete the existing configuration.
Then click on the + icon and then select Flutter.
Then provide name and entry point and flavors
Step 6: Configuring Flavours Natively
To make the flavors run, we need to configure them in Both android
and ios
.
Android Configuration
1. First open the app/build.gradle
Here we need to define the various properties of flavors.
defaultConfig{
///code
}
//below default config add the falvors properties
flavorDimensions "app"
productFlavors {
school1 {
dimension "app"
applicationId "com.flutterjunction.flavors_demo.school1" //packagename.falvor
versionCode 1
versionName "1.0"
}
school2 {
dimension "app"
applicationId "com.flutterjunction.flavors_demo.school2"
versionCode 1
versionName "1.0"
}
}
2. Create a String resource inside the android/src/main/res/values
Create the strings.xml
inside the android/src/main/res/value
. Add the app name here
strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Default App Name</string>
</resources>
3. Adding a label to AndroidManifest.xml
Find the AndroidMainfest.xml
in android/src/main
.
<application
android:label="@string/app_name" ///here
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"
>
//rest of the code
</application>
Note: Keep in Mind thatapp_name
should be the same key you provided in thestrings.xml
.
4. Adding folders for different flavors
Now inside the android/app/src
create two directories:
- school1
- school2
Inside both directories add directories create res/values
directories.
Insideschool1/res/values
create a new file namedstrings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">School One</string>
</resources>
Similarly, Insideschool2/res/values
create a new file namedstrings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">School Two</string>
</resources>
Step 7: Configure App Icons
We are going to use flutter_launcher_icons
to achieve so.
1. Create the different yaml files for different flavors
Create flutter_launcher_icons-school1.yaml
and flutter_launcher_icons-school2.yaml
in the root project folder.
flutter_launcher_icons-school1.yaml
flutter_icons:
android: true
ios: true
image_path: "assets/app_icons/one.png"
flutter_launcher_icons-school2.yaml
flutter_icons:
android: true
ios: true
image_path: "assets/app_icons/two.png"
2. Run pub
After that, you need to run the below code in the terminal to make the launcher icons work.
flutter pub run flutter_launcher_icons:main -f flutter_launcher_icons*
Step 8: Select and run specific flavors
You can now select the flavors and run. After running you can find two different apps with different properties inside them.
Conclusion
Here you learned how to use flavor in Flutter. You can also use flavors in Flutter to create different apps for different environments too. Play around with the code as per your need so that you can get the concept of the working mechanism of flavor in Flutter.
Thanks for reading this article.
Also, follow to get updated on exciting articles and projects.
If I got something wrong? Let me know in the comments. I would love to improve.
Full Code:
https://github.com/nbnD/flavors_demo
Let’s get connected
We can be friends. Find on Facebook, Linkedin, Github, YouTube,
BuyMeACoffee, and Instagram.
Contribute: BuyMeACoffee
Contact: Contact Us
-
Heya i’m for the primary time here. I found this board and I to find It truly helpful & it helped me out much. I’m hoping to present something again and help others such as you helped me.
-
I’d always want to be update on new blog posts on this website , saved to favorites! .
Leave a Reply