Dynamic Splash Screen in Flutter
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)
}
This code works for me. :)
Michael Amir
Updated on December 22, 2022Comments
-
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 almost 4 yearsYou 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 almost 4 years@ShubhamGupta the native splash screens shows up before any line in the main method runs
-
-
Michael Amir almost 4 yearsAnd how exactly does storing and retrieving the theme before starting the app makes the app show different native splash screen?!
-
Sanket Vekariya almost 4 yearsAt 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 almost 4 yearsYes but nothing in your code refers to a different splash screen file, just a theme string
-
zahaniza over 3 yearsThanks @SanketVekariya I tried your way but it doesn't work.
setTheme
Not affect. Can you share more info? -
Priya Sindkar about 3 yearsThis solution won't work as MainActivity.kt is called before the main() method of flutter.