Scaffoldmessenger widget ancestor problem - flutter

void main() async {
WidgetsFlutterBinding.ensureInitialized();
await SharedPrefs.init();
runApp(MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => UserProvider()),
Provider(
create: (context) => AuthService(),
),
],
child: Builder(builder: (context) {
return const MyApp();
})));
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
void initState() {
super.initState();
context.read<AuthService>().getUserData(context);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Amazon Clone',
onGenerateRoute: (settings) => generateRoute(settings),
theme: ThemeData(
scaffoldBackgroundColor: GlobalVariables.backgroundColor,
colorScheme:
const ColorScheme.light(primary: GlobalVariables.secondaryColor),
appBarTheme: const AppBarTheme(
elevation: 0,
iconTheme: IconThemeData(color: Colors.black),
),
),
home: Builder(builder: (context) {
return context.watch<UserProvider>().user.token.isNotEmpty
? const HomeScreen()
: const AuthScreen();
}));
}
}
i am using snackbar from utils file i get no scaffoldmessenger widget found error.I tried to use builder scaffoldmessengerkey but didnt work.what can i do.i used try catch with snackbar.What is the solve of my problem

You need both MaterialApp and a Scaffold widget in the tree before using ScaffoldMessenger. For example:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
#override
Widget build(BuildContext context) {
return MaterialApp( // required MaterialApp
title: _title,
home: Scaffold( // required Scaffold
appBar: AppBar(title: const Text(_title)),
body: const Center(
child: MyStatelessWidget(),
),
),
);
}
}
class MyStatelessWidget extends StatelessWidget {
const MyStatelessWidget({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return OutlinedButton(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('A SnackBar has been shown.'),
),
);
},
child: const Text('Show SnackBar'),
);
}
}

Related

Routemaster replace is doing push

import 'package:flutter/material.dart';
import 'package:routemaster/routemaster.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
MyApp({Key? key}) : super(key: key);
late final RoutemasterDelegate _routerDelegate = RoutemasterDelegate(
routesBuilder: (context) => RouteMap(
routes: buildRoutingTable(
routerDelegate: _routerDelegate,
),
),
);
#override
Widget build(BuildContext context) => MaterialApp.router(
title: 'Flutter Demo',
theme: ThemeData(
useMaterial3: true,
colorSchemeSeed: Colors.lightGreenAccent,
),
routeInformationParser: const RoutemasterParser(),
routerDelegate: _routerDelegate,
);
}
Map<String, PageBuilder> buildRoutingTable({
required RoutemasterDelegate routerDelegate,
}) =>
{
PathConstants.tabContainerPath: () => MaterialPage(
name: 'first-screen',
child: FirstScreen(
onNavigate: () => routerDelegate.replace(
_PathConstants.secondScreen,
),
),
),
PathConstants.secondScreen: () => const MaterialPage(
name: 'second-screen',
child: SecodScreen(),
),
};
class _PathConstants {
const PathConstants.();
static String get tabContainerPath => '/';
static String get secondScreen => '${tabContainerPath}second-screen';
}
class FirstScreen extends StatelessWidget {
final VoidCallback onNavigate;
const FirstScreen({
Key? key,
required this.onNavigate,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Fisrt screen'),
),
body: Center(
child: ElevatedButton(
onPressed: onNavigate,
child: const Text('Replace'),
),
),
);
}
}
class SecodScreen extends StatelessWidget {
const SecodScreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Second screen'),
),
);
}
}

Is it possible to change ShowDurationPicker colors in flutter?

Trying to change duration pickers color theme but the package does not allow me to change.
In other timer pickers like showTimePickers the widget containes a builder where you can add a theme to it but in this one there is no builder.
I am currently using this package pub.dev link
I tried to wrap it with a theme but that didn't help.
If you put your ThemeData in MaterialApp like this, you can easily change colors in showDurationPicker:
import 'package:flutter/material.dart';
import 'package:duration_picker/duration_picker.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Duration Picker Demo',
theme: ThemeData(
colorScheme: const ColorScheme.light(
primary: Colors.red,
secondary: Colors.green,
),
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Test')),
body: Container(),
floatingActionButton: Builder(
builder: (BuildContext context) => FloatingActionButton(
onPressed: () async {
var resultingDuration = await showDurationPicker(
context: context,
initialTime: const Duration(minutes: 20),
);
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Choose duration: $resultingDuration')));
},
tooltip: 'Popup Duration Picker',
child: const Icon(Icons.add),
),
),
);
}
}
Output:

How can I resolve this Flutter Navigator.push() error?

I am trying to move from one page to another via Navigator.push. Here is my code:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
int count = 0;
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
backgroundColor: Colors.deepOrange,
title: const Text("Noice!"),
),
body: ElevatedButton(
child: const Text('About'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AboutScreen(),
),
);
},
),
class AboutScreen extends StatelessWidget {
const AboutScreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: const Color.fromARGB(255, 0, 255, 8),
title: const Text("Flutter ballert")),
);
}
}
The code compiles and I can access the app, but clicking the button leads to an error:
Exception has occurred.
FlutterError (Navigator operation requested with a context that does not include a Navigator.
The context used to push or pop routes from the Navigator must be that of a widget that is a descendant of a Navigator widget.)
I know that in the offical docs the example for navigation is a tiny bit different. They dont return MaterialApp, instead they return Scaffold. Whats the difference between the two? Why should I return MaterialApp in the first place? And why doesnt it work with returning MaterialApp?
I dont know why this happens. I am new to flutter, so apologies if thats really trivial.
EDIT: Duplicate of:
Navigator operation requested with a context that does not include a Navigator
The problem is with the context. To fix this. Wrap your widget in a Builder() Class:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
int count = 0;
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Builder(builder: (context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.deepOrange,
title: const Text("Noice!"),
),
body: ElevatedButton(
child: const Text('About'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AboutScreen(),
));
},
),
);
}),
);
}
}
class AboutScreen extends StatelessWidget {
const AboutScreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: const Color.fromARGB(255, 0, 255, 8),
title: const Text("Flutter ballert")),
);
}
}
Here is a YouTube video by the Google team explaining Builder
You need to pass the context:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
int count = 0;
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
backgroundColor: Colors.deepOrange,
title: const Text("Noice!"),
),
body: ElevatedButton(
child: const Text('About'),
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => AboutScreen(),
),
);
},
),
),
);
}
}
class AboutScreen extends StatelessWidget {
const AboutScreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: const Color.fromARGB(255, 0, 255, 8),
title: const Text("Flutter ballert")),
);
}
}
Basically you did:
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AboutScreen(),
),
);
But you need to do this:
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => AboutScreen(),
),
);

Flutter: MaterialApp throws Null check operator used error

Here is where I instantiate my MaterialApp:
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'My New App';
#override
Widget build(BuildContext context) {
return const MaterialApp(
title: _title,
initialRoute: '/special',
routes: {
'/special': (context) => const SpecialPage(),
'/another': (context) => const AnotherPage()
});
}
}
The pages are very similar. Here is the Special page:
class SpecialPage extends StatelessWidget {
const SpecialPage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Special Stuff'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, '/another');
},
child: const Text('Special Content Goes Here'),
),
),
);
}
When I try to compile I get the error: Null check operator used on a null value. Why?
The error message indicates the problem occurs in the construction of MaterialApp.
Remove the const in the build method of MyApp
Like so:
#override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
initialRoute: '/special',
routes: {
'/special': (context) => const SpecialPage(),
'/another': (context) => const AnotherPage()
});
}

Setting theme data for flutter app seems broken

I've tried everything I can think of to change the background color of my flutter app, but every time I run the app, the background is black.
This is main.dart
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'auth_controller.dart';
import 'themes/color.dart';
import 'index.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp().then((value) => Get.put(AuthController));
runApp(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 MaterialApp(
//ThemeData
title: 'Title',
theme: ThemeData(
brightness: Brightness.light,
),
home:const Index(),
debugShowCheckedModeBanner: false,
);
}
}
I don't think I'm even using themes/color.dart but I thought I'd leave it in anyway. Brightness should set it.
This is index.dart
import 'package:flutter/material.dart';
import 'themes/color.dart';
import 'signup.dart';
Future<void> main() async {
runApp(MyApp(
routes: <String, WidgetBuilder>{
'/signup': (BuildContext context) => const SignUp()
},
debugShowCheckedModeBanner: false,
));
}
class MyApp extends StatelessWidget {
const MyApp({Key? key, required Map<String, WidgetBuilder> routes, required bool debugShowCheckedModeBanner}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Welcome to Flutter',
home: Scaffold(
backgroundColor: const Color(0xFFe3e4e4),
appBar: AppBar(
title: const Text('Flutter Screen Background Color Example'),
),
body: const Center(child: Index()),
),
);
}
}
class Index extends StatelessWidget {
const Index({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const SizedBox(height: 20,),
ElevatedButton(
child: const Text('WTF'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const SignUp()),
);
}
),
]
)
);
}
}
It seems like the background should be a light grey,but it's black. I tried invalidating the caches and restarting too.