1
votes

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

1
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. - Shubham Gupta
@ShubhamGupta the native splash screens shows up before any line in the main method runs - Michael Amir

1 Answers

2
votes

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. :)