My question is how to show a splash screen or alternatively show a loading screen if I execute the following code:
void main() async{
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
You can simply use Future Builder for that,
void main() async{
WidgetsFlutterBinding.ensureInitialized();
//remove this line from your code
//await Firebase.initializeApp();
runApp(MyApp());
}
this is code for MyApp()
class MyApp extends StatelessWidget {
final Future<FirebaseApp> _initialization = Firebase.initializeApp();
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: FutureBuilder(
future: _initialization,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return LoginWrapper();
}
return SplashScreen();
},
),
);
}
}
it shows your SplashScreen while loading your firebase App ;)
Related
flutter_local_notifications doesn't show permissions dialog on Android API level 33. Tested with emulator. In AndroidManifest.xml file, I've defined the needed permission:
This is an example code:
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
Future<void> setup() async {
final _localNotificationsPlugin = FlutterLocalNotificationsPlugin();
const androidSetting = AndroidInitializationSettings('#mipmap/ic_launcher');
const initSettings = InitializationSettings(android: androidSetting);
await _localNotificationsPlugin.initialize(initSettings).then((_) {
debugPrint('setupPlugin: setup success');
}).catchError((Object error) {
debugPrint('Error: $error');
});
bool? granted = await _localNotificationsPlugin.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()?.requestPermission() ?? false;
print('granted: $granted');
}
void main() {
WidgetsFlutterBinding.ensureInitialized();
setup();
runApp(myApp());
}
class myApp extends StatelessWidget {
myApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
child: Text('Notification test')
)
)
);
}
}
I am implementing ThemeMode feature on my fluter app for example if user have saved ThemeMode (light, dark or system) saved in SharedPreferences then it should load on app startup otherwise bydefault it is light. so i am using Provider for state management.
Here is my approach:
on themes_provider.dart
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../utils/themes.dart';
class ThemesProvider extends ChangeNotifier {
ThemeMode? _themeMode;
ThemeMode? get themeMode => _themeMode;
ThemeData get lightTheme => ThemeManager().lightTheme;
ThemeData get darkTheme => ThemeManager().darkTheme;
void initThemeMode() async {
final _prefs = await SharedPreferences.getInstance();
final _currentTheme = _prefs.getString('theme') ?? 'light';
if (_currentTheme == 'light') {
_themeMode = ThemeMode.light;
} else if (_currentTheme == 'dark') {
_themeMode = ThemeMode.dark;
} else {
_themeMode = ThemeMode.system;
}
notifyListeners();
}
void setThemeMode(int value) async {
final _prefs = await SharedPreferences.getInstance();
_prefs.setInt('theme', value);
notifyListeners();
}
}
and then on main.dart
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => UserProvider()),
ChangeNotifierProvider(
create: (context) => ThemesProvider(),
)
],
builder: (context, snapshot) {
final _themeNotifier =
Provider.of<ThemesProvider>(context, listen: false);
_themeNotifier.initThemeMode();
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: _themeNotifier.lightTheme,
darkTheme: _themeNotifier.darkTheme,
themeMode: _themeNotifier.themeMode,
home: HomeScreen(),
onGenerateRoute: RouteGenerator.generateRoute,
initialRoute: RouteGenerator.loginRoute,
);
});
}
}
But in debug console i am getting null value on _themeNotifier.themeMode
please help.
Writing on the page can not be converted to the page display the error message
... .... flutter ... ... dart
.......... application restart ..................
my code...
main
Future<void> main() async {
runZonedGuarded(() {
WidgetsFlutterBinding.ensureInitialized();
FlutterError.onError = (FlutterErrorDetails errorDetails) {
print('This is an error on the Flutter SDK');
// print(errorDetails.exception);
print('-----');
// print(errorDetails.stack);
};
runApp(const MyApp());
}, (error, stackTrace) {
print('This is a pure Dart error');
// print(error);
print('-----');
// print(stackTrace);
});
}
myApp
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
builder: (BuildContext context, Widget? widget) {
ErrorWidget.builder =
(FlutterErrorDetails errorDetails) => const ErrorPage();
return widget!;
},
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
debugShowCheckedModeBanner: false,
home: const MyApp());
}
}
i want wait 5 seconds on main page and display loading animation then navigate to another page.
here is my code
import 'mainPage.dart';
import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'dart:async';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool isLoading = true;
#override
void initState() {
super.initState();
loadData();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
backgroundColor: Colors.cyan,
body: Builder(
builder: (context) => Center(
child: Container(
child: SpinKitCubeGrid(color: Colors.white, size: 50.0),
),
),
),
),
);
}
Future loadData() async {
return new Timer(Duration(seconds: 5), () {
setState(() {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => MainPage()));
});
});
}
}
but i got this error:
Unhandled Exception: Navigator operation requested with a context that does not include a Navigator.
what should i do?
Wrap MyApp with MaterialApp which will provide the right context to Navigator
void main() {
runApp(MaterialApp(home: MyApp()));
}
Maybe this will help U
static Route route() {
return MaterialPageRoute<void>(builder: (_) => MyApp());
}
onPressed: () => Navigator.of(context).push<void>(MainPage.route()),
................
static Route route() {
return MaterialPageRoute<void>(builder: (_) => MainPage());
}
onPressed: () => Navigator.of(context).push<void>(MyApp.route()),
Can you try it like this? I didn't run the code but showing the basic idea. Just pass the context and call it from build function.
class _MyAppState extends State<MyApp> {
bool isLoading = true;
#override
Widget build(BuildContext context) {
loadData(context);
return MaterialApp(
...
);
}
Future loadData(context) async {
...
}
}
You need a context to navigate with the Navigator.
To navigate without using context you can use a package called GetX
Example:
Add "Get" before your MaterialApp, turning it into GetMaterialApp
GetMaterialApp( // Before: MaterialApp(
home: MyHome(),
)
Navigate to a new screen:
Get.to(NextScreen());
I'm trying to implement the camera package in flutter for android and iOS devices,
On android I don't have any problem but in iOS i get this error:
The following StateError was thrown building Builder:
Bad state: No element
When the exception was thrown, this was the stack:
#0 List.first (dart:core-patch/growable_array.dart:332:5)
#1 _CameraState.initState (package:glass_case_flutter/controllers/camera_controller.dart:21:45)
#2 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4632:57)
#3 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4469:5)
... Normal element mounting (24 frames)
this is the code of main.dart:
List<CameraDescription> cameras;
Future<Null> main() async {
WidgetsFlutterBinding.ensureInitialized();
cameras = await availableCameras();
await Firebase.initializeApp();
runApp(GlassCase());
}
class GlassCase extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(fontFamily: 'Nunito'),
initialRoute: WelcomeScreen.id,
routes: {
WelcomeScreen.id: (context) => WelcomeScreen(),
RegistrationScreen.id: (context) => RegistrationScreen(),
ResetPassword.id: (context) => ResetPassword(),
HomeScreen.id: (context) => HomeScreen(cameras),
ProfileScreen.id: (context) => ProfileScreen()
},
);
}
}
this is the code of my homepage.dart where I call camera.dart:
IconButton(
icon: Icon(Icons.camera_alt),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Camera(widget.cameras)));
},
color: Colors.black,
),
this is my camera.dart, that is very simple, just turn on the camera:
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
class Camera extends StatefulWidget {
List<CameraDescription> cameras;
Camera(this.cameras);
#override
_CameraState createState() => _CameraState();
}
class _CameraState extends State<Camera> {
CameraController controller;
#override
void initState() {
super.initState();
controller =
new CameraController(widget.cameras.first, ResolutionPreset.high);
controller.initialize().then((_) {
if (!mounted) {
return;
}
setState(() {});
});
}
#override
void dispose() {
controller?.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
if (!controller.value.isInitialized) {
return new Container();
}
return new AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: CameraPreview(controller),
);
}
}
I added this in my Info.plist to access the camera and microphone:
<key>NSCameraUsageDescription</key>
<string>Enable to access your camera to capture your photo</string>
<key>NSMicrophoneUsageDescription</key>
<string>Enable to access mic to record your voice</string>
I don't understand why in Android it work but in iOS I get that error, somebody can help me ?
Thank so much !