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.

Adding Flavors

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:

Different Apps
falvors in flutter
School A
flavors in Flutter
School B

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.

add flavors in flutter

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

adding flavors in flutter

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 that app_name should be the same key you provided in the strings.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.

Inside school1/res/values create a new file named strings.xml 
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">School One</string>
</resources>
Similarly, Inside school2/res/values create a new file named strings.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 FacebookLinkedinGithubYouTube

BuyMeACoffee, and Instagram.

Contribute: BuyMeACoffee

ContactContact Us

  1. tlovertonet Avatar

    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.

  2. zoritoler imol Avatar

    I’d always want to be update on new blog posts on this website , saved to favorites! .

Leave a Reply

Your email address will not be published. Required fields are marked *

flavors in flutter

Related Post