Reputation: 31
I'm experiencing an issue in my Flutter app where the app launches with an incorrect cursor color (e.g., purple instead of the expected color). This issue persists through the login process, and only a hot reload or restart fixes it, restoring the expected behavior.
Here is the relevant part of my MaterialApp
configuration:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
bool supabaseInitialized = false;
bool firebaseInitialized = false;
try {
await Supabase.initialize(
url: 'https://XXXXXXXXXXXXXXX.supabase.co',
anonKey:
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
);
supabaseInitialized = true;
} catch (e) {
}
try {
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform); FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
} catch (e) {
}
updateExistingUsersExpiration();
ValueNotifier<bool> switchNotifier = ValueNotifier<bool>(false);
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider<LocaleProvider>(
create: (context) {
return LocaleProvider()..loadLocale();
},
),
ChangeNotifierProvider<UserNotifier>(
create: (context) {
final userNotifier = UserNotifier();
userNotifier.initializeUser();
return userNotifier;
},
),
ChangeNotifierProvider<ThemeNotifier>(
create: (context) {
return ThemeNotifier();
},
),
ValueListenableProvider<bool>.value(
value: switchNotifier,
),
],
child: const MyApp(),
),
);
}
@override
Widget build(BuildContext context) {
final _ = Provider.of<LocaleProvider>(context, listen: false);
final __ = Provider.of<UserNotifier>(context, listen: false);
final ___ = Provider.of<ThemeNotifier>(context, listen: false);
return FutureBuilder<String>(
future: getCurrentUserId(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
),
);
} else if (snapshot.hasError) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: Text('Failed to get user ID'),
),
),
);
} else {
final userId = snapshot.data;
if (userId == null || userId.isEmpty) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: AuthPage(),
);
} else {
return MultiProvider(
providers: [
ChangeNotifierProvider<LocaleProvider>(
create: (_) => LocaleProvider()..loadLocale(),
),
ChangeNotifierProvider<UserNotifier>(
create: (context) => UserNotifier(),
),
ChangeNotifierProvider<ThemeNotifier>(
create: (context) => ThemeNotifier(),
),
ChangeNotifierProvider<BalanceNotifier>(
create: (context) => BalanceNotifier(userId),
),
ChangeNotifierProvider<Cart>(
create: (context) => Cart(),
),
ChangeNotifierProvider<RateNotifier>(
create: (context) => RateNotifier(),
),
ChangeNotifierProvider<ValueNotifier<bool>>(
create: (context) => ValueNotifier<bool>(false),
),
],
child: Consumer<ThemeNotifier>(
builder: (context, themeNotifier, child) {
return Consumer<LocaleProvider>(
builder: (context, localeProvider, child) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: lightMode,
darkTheme: darkMode,
themeMode: themeNotifier.currentTheme,
locale: localeProvider.locale,
supportedLocales: const [
Locale('fr'), // Français
Locale('en'), // Anglais
Locale('es'), // Espagnol
// Locale('ht'), // Créole haïtien
],
localizationsDelegates: const [
AppLocalizations
.delegate, // Utilisation de AppLocalizations
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
initialRoute: '/',
routes: {
'/': (context) {
return const SplashScreen();
},
'/ProfilePage': (context) => const ProfilPage(),
'/LanguageSelection': (context) =>
const LanguageSelectionPage(),
},
// Routes dynamiques pour gérer les arguments
onGenerateRoute: (settings) {
switch (settings.name) {
case '/homePage':
final firebase_auth.User? user =
settings.arguments as firebase_auth.User?;
if (user == null) {
return MaterialPageRoute(
builder: (_) => const Scaffold(
body: Center(
child: Text('user not found')),
),
);
}
return MaterialPageRoute(
builder: (_) => HomePage(user: user),
);
case '/GalleryPage':
final pinController =
settings.arguments as TextEditingController?;
if (pinController == null) {
return MaterialPageRoute(
builder: (_) => const Scaffold(
body: Center(
child:
Text('PinController is missing')),
),
);
}
return MaterialPageRoute(
builder: (_) =>
GalleryPage(pinController: pinController),
);
case '/TransfertPage':
final args =
settings.arguments as Map<String, dynamic>?;
if (args == null ||
!args.containsKey('total') ||
!args.containsKey('userId') ||
!args.containsKey('pinController')) {
return MaterialPageRoute(
builder: (_) => const Scaffold(
body: Center(
child: Text(
'No Arguments for TransfertPage')),
),
);
}
return MaterialPageRoute(
builder: (_) => TransfertPage(
total: args['total'],
userId: args['userId'],
pinController: args['pinController'],
),
);
default:
return MaterialPageRoute(
builder: (_) => const Scaffold(
body: Center(child: Text('Page not found')),
),
);
}
},
);
},
);
}));
}
}
},
);
}
}
Details:
The cursor color is incorrect immediately after the app launches and continues through the login process.
After signing in, the app does not behave as expected until I perform a hot reload or restart.
themeNotifier.currentTheme
dynamically switches between ThemeMode.light
and ThemeMode.dark
, and both themes are properly configured.
This issue does not occur after a hot reload or restart.
What I’ve Tried:
Verified that themeNotifier.currentTheme
always returns the correct ThemeMode
.
Checked if lightMode
and darkMode
themes are correctly defined.
Ensured the login flow and app initialization do not overwrite theme settings.
What could cause the app to start with the wrong cursor color and require a hot reload to fix the theme and login behavior? How can I ensure everything works correctly from the initial launch?
Thank you in advance for your suggestions!
Upvotes: 1
Views: 49
Reputation: 277
For cursor Color
final ThemeData lightMode = ThemeData(
brightness: Brightness.light,
primaryColor: Colors.blue,
textSelectionTheme: TextSelectionThemeData(
cursorColor: Colors.blue,
selectionColor: Colors.blue.withOpacity(0.4),
selectionHandleColor: Colors.blue,
),
);
final ThemeData darkMode = ThemeData(
brightness: Brightness.dark,
primaryColor: Colors.deepPurple,
textSelectionTheme: TextSelectionThemeData(
cursorColor: Colors.deepPurple,
selectionColor: Colors.deepPurple.withOpacity(0.4),
selectionHandleColor: Colors.deepPurple,
),
);
Update your themeNotifier
class ThemeNotifier extends ChangeNotifier {
ThemeMode _currentTheme = ThemeMode.system;
ThemeMode get currentTheme => _currentTheme;
ThemeNotifier() {
loadThemeMode();
}
void loadThemeMode() async {
final savedThemeMode = await SharedPreferences.getInstance()
.then((prefs) => prefs.getString('themeMode'));
_currentTheme = savedThemeMode == 'dark'
? ThemeMode.dark
: savedThemeMode == 'light'
? ThemeMode.light
: ThemeMode.system;
notifyListeners();
}
void setThemeMode(ThemeMode mode) async {
_currentTheme = mode;
await SharedPreferences.getInstance()
.then((prefs) => prefs.setString('themeMode', mode.name));
notifyListeners();
}
}
Upvotes: 0