Dynamic Splash Screen in Flutter

1,001

I would say shared preference can be one of the approaches to achieve this.
After some efforts I come up with this below example code.:
main.dart

SharedPreferences prefs;
String theme;

void main() async {
  prefs = await SharedPreferences.getInstance();
  // just for checking purpose
  if (prefs.getString("theme") == null) {
    await prefs.setString("theme", "darkTheme");
  }
  theme = (prefs.getString("theme") != null) ? "darkTheme" : "lightTheme";
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MyApp(theme: theme));
}

class MyApp extends StatelessWidget {
  final theme;

  const MyApp({Key key, this.theme}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    Brightness themeData =
        theme == "darkTheme" ? Brightness.dark : Brightness.light;
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(brightness: themeData),
      home: theme == "darkTheme"
          ? Scaffold(
              body: Center(
                child: Container(
                  child: Text("Dark Theme"),
                ),
              ),
            )
          : Scaffold(
              body: Center(
                child: Container(
                  child: Text("Light Theme"),
                ),
              ),
            ),
      debugShowCheckedModeBanner: false,
    );
  }
}

MainActivity.kt

import android.content.Context
import android.content.SharedPreferences
import io.flutter.embedding.android.FlutterActivity

class MainActivity : FlutterActivity() {
    var sharedPreferences: SharedPreferences =
            getSharedPreferences("FlutterSharedPreferences", 0)
    private val theme: String? = sharedPreferences.getString("flutter." + "theme", "lightTheme")
    override fun setTheme(resid: Int) {
        super.setTheme(resid)
        if (theme == "darkTheme") {
            application.setTheme(R.style.LaunchTheme)
        }
        if (theme == "lightTheme") {
            application.setTheme(R.style.NormalTheme)
        }
    }
}

styles.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
        <item name="android:windowEnableSplitTouch">false</item>
        <item name="android:splitMotionEvents">false</item>
        <item name="android:windowBackground">@android:color/black</item>
    </style>

    <style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
        <item name="android:windowBackground">@android:color/white</item>
        <item name="android:windowEnableSplitTouch">false</item>
        <item name="android:splitMotionEvents">false</item>
    </style>
</resources>

FYI:-

Ultimately, Flutter stores the value in native shared preference. The format of retrieval of data is different.

Android:

var sharedPreferences: SharedPreferences =
            getSharedPreferences("FlutterSharedPreferences", 0)
    private val theme: String? = sharedPreferences.getString("flutter." + "theme", "lightTheme")

IOS:

if let name = NSUserDefaults.standard.string(forKey: "flutter.test") {
    print(name)
}

Reference:-

ios, android

This code works for me. :)

Share:
1,001
Michael Amir
Author by

Michael Amir

Updated on December 22, 2022

Comments

  • Michael Amir
    Michael Amir over 1 year

    I've different versions of my native splash screen that I want to show each one when its theme was previously selected in the app. So for example, let's say I have a light splash screen and a dark splash screen and the light one shows by default but if the user changed the app theme to the dark theme in the app settings, then beside the changes I'm going to do in my app, the next time the user opens the app I want to show him the dark version of the splash screen.

    NOTE: I AM TALKING ABOUT NATIVE SPLASH SCREEN SCREENS

    • Shubham Gupta
      Shubham Gupta almost 4 years
      You can have a variable that holds the value of whether your theme is dark or light and use that to make the decision to show the proper splash screen. You can save the data (selected theme) maybe to shared preferences or database and fetch it in main method.
    • Michael Amir
      Michael Amir almost 4 years
      @ShubhamGupta the native splash screens shows up before any line in the main method runs
  • Michael Amir
    Michael Amir almost 4 years
    And how exactly does storing and retrieving the theme before starting the app makes the app show different native splash screen?!
  • Sanket Vekariya
    Sanket Vekariya almost 4 years
    At the very first time after app installation, default splash screen you will see. after that, we have to set the shared preference to some value if it is null. when you open the app for the first time (not after first time like app installation) MainActivity gets the theme from shared preference and will execute accordingly. Ultimately you are setting the shared preference from dart and using its value next time at the time of native splash screen.
  • Michael Amir
    Michael Amir almost 4 years
    Yes but nothing in your code refers to a different splash screen file, just a theme string
  • zahaniza
    zahaniza over 3 years
    Thanks @SanketVekariya I tried your way but it doesn't work. setTheme Not affect. Can you share more info?
  • Priya Sindkar
    Priya Sindkar about 3 years
    This solution won't work as MainActivity.kt is called before the main() method of flutter.