A product was used after being disposed once you have called dispose() on a product, it can no longer used - flutter

i am getting error after going back
A product was used after being disposed once you have called dispose() on a product, it can no longer used.
my code is written down
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import './screens/product_detail_screen.dart';
import './screens/products_overview_screen.dart';
import '/provider/products.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (ctx) => Products(),
child: MaterialApp(
title: 'Ram Shop',
theme: ThemeData(
primarySwatch: Colors.purple,
accentColor: Colors.deepOrange,
fontFamily: 'Lato',
),
home: ProductsOverviewScreen(),
routes: {
ProductDetailScreen.routeName: (ctx) => ProductDetailScreen(),
},
),
);
}
}
i tried searching for solution but didn't found any . please check my code and tell me what's wrong.

Related

could not find a generator for route RouteSettings("org_Item", null) in the _WidgetsAppState

I´m newbie to flutter and reveice one exception about route, I don't why I am getting this error in the debug console 'could not find a generator for route RouteSettings("org_Item", null) in the _WidgetsAppState.'
provinces_item.dart
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:let_us_volunteer/screens/orgscreen.dart';
class provwidget extends StatelessWidget {
final String id;
final String title;
final String image;
provwidget(this.id, this.title, this.image);
void selectOrg(BuildContext ctx) {
Navigator.of(ctx).pushNamed(orgscreen.routeName);
}
#override
Widget build(BuildContext context) {
return InkWell(
onTap: () => selectOrg(context),
child: Image.asset(image),
);
}
}
main.dart
import 'package:flutter/material.dart';
import 'package:let_us_volunteer/screens/log_in.dart';
import 'screens/page_view.dart';
import 'screens/log_in.dart';
import 'screens/orgscreen.dart';
void main() async {
runApp(page_view());
}
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(
title: 'flutter demo',
theme: ThemeData(
primarySwatch: Colors.purple,
primaryColor: Colors.purple,
),
home: const log_in_screen(),
routes: {
'/': (context) => log_in_screen(),
orgscreen.routeName: (context) => orgscreen(),
},
);
}
}
orgscreen.dart
import 'package:flutter/material.dart';
class orgscreen extends StatefulWidget {
static const routeName = 'org_Item';
#override
State<orgscreen> createState() => _orgscreenState();
}
class _orgscreenState extends State<orgscreen> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('ggg')),
body: null,
);
}
}
If someone knows the solution it would be grateful for help, and explaining what was wrong, thanks
Try to remove your home: const log_in_screen(), and for format case use '/org_Item';
title: 'flutter demo',
theme: ThemeData(
primarySwatch: Colors.purple,
primaryColor: Colors.purple,
),
routes: {
'/': (context) => log_in_screen(),
orgscreen.routeName: (context) => orgscreen(),
},
And not sure about your page_view, you can check
runApp(MyApp());
The correct way of define route is use / with it, So change your route to this:
static const routeName = '/org_Item';
when yo do not run your main class (MyApp) in your runApp, it can not define that route, so also correct this:
runApp(MyApp());
last thing when you define / this in your routes, you should not use home property of MaterialApp, so remove home: const log_in_screen(), and your final MaterialApp should look like this:
MaterialApp(
title: 'flutter demo',
theme: ThemeData(
primarySwatch: Colors.purple,
primaryColor: Colors.purple,
),
routes: {
'/': (context) => log_in_screen(),
orgscreen.routeName: (context) => orgscreen(),
},
)

Flutter : Losing Provider State on Hot Reload

I'm using Provider v4.0.0 and when I hot reload the app I lose state from Provider class.
I know provider preserves it's state so obviously my code has some flaw. But I'm unable to find out what's wrong with my code.
Following is my main.dart file :
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:scapperapp/provider/auth.dart';
import 'package:scapperapp/screens/authenticated.dart';
import 'package:scapperapp/screens/homepage.dart';
import 'package:scapperapp/screens/login.dart';
import 'package:scapperapp/screens/started.dart';
void main() {
HttpOverrides.global = new MyHttpOverrides();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [ChangeNotifierProvider(create: (context) => User())],
child: Consumer<User>(
builder: (context, User user, _) => MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.deepPurple,
primaryColor: Color(0xFF5B5A92),
accentColor: Color(0xFFadacdf),
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: user.isAuthorised
? HomeScreen()
: FutureBuilder(
future: user.tryAutoLogin(),
builder: (ctx, authResultSnapshot) =>
authResultSnapshot.connectionState ==
ConnectionState.waiting
? HomePage()
: HomePage(),
),
routes: {
SignupChoice.routeName: (context) => SignupChoice(),
LoginPage.routeName: (context) => LoginPage(),
HomeScreen.routeName: (context) => HomeScreen()
},
),
));
}
}
class MyHttpOverrides extends HttpOverrides {
#override
HttpClient createHttpClient(SecurityContext context) {
return super.createHttpClient(context)
..badCertificateCallback =
(X509Certificate cert, String host, int port) => true;
}
}

Navigation Issue in my flutter Application. Unable to redirect to the required page or screen in flutter

Below code mainform.dart when run individually i.e keeping Dart entrypint: as mainform.dart working fine and redirecting or navigating to the correct page i.e Feed();
mainform.dart
import 'package:sqlite_crud_flutter/detail.dart';
import 'package:sqlite_crud_flutter/login.dart';
import 'package:sqlite_crud_flutter/notifier/food_notifier.dart';
import 'package:sqlite_crud_flutter/feed.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'notifier/auth_notifier.dart';
void main() => runApp(MultiProvider(
providers: [
ChangeNotifierProvider(
create: (context) => AuthNotifier(),
),
ChangeNotifierProvider(
create: (context) => FoodNotifier(),
),
],
child: MainFormPage(),
));
class MainFormPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Application Name',
theme: ThemeData(
primarySwatch: Colors.blue,
accentColor: Colors.lightBlue,
),
home: Consumer<AuthNotifier>(
builder: (context, notifier, child) {
return Feed();
},
),
);
}
}
But where as when I want to redirect to the Feed() page from another screen or page of my main application using
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (context) =>
MainFormPage()
)
);
},
I am seeing a blank screen with error
Another exception was thrown: Instance of 'DiagnosticsProperty<void>'"
How to the Feed page from another screen?
Screenshot of the error shown on mobile when debugged:

multi Provider doesn't work in material app in flutter?

I've created an app and I have used MultiProvider but it doesn't work when I use it inside MaterialApp
I want to use it to change app theme color but
it gives me an error:
*Note: when I use posts provider in any other screen it works.
My Code:
import 'package:blog_app/provider/posts.dart';
import 'package:blog_app/provider/settings.dart';
import 'package:blog_app/screens/splash_screen.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider<Posts>(
builder: (context) => Posts(),
),
ChangeNotifierProvider<Settings>(
builder: (context) => Settings(),
),
],
child: MaterialApp(
darkTheme: Provider.of<Settings>(context).darkModeEnabled ? ThemeData.dark() : ThemeData.light(),
debugShowCheckedModeBanner: false,
title: 'Blogy',
theme: ThemeData(
primaryColor: Colors.deepPurple[900],
cursorColor: Colors.deepPurple[900],
accentColor: Colors.deepPurple[900],
fontFamily: 'Ubuntu',
),
home: SplashScreen(),
),
);
}
}
The Error :-
I/flutter ( 9316): The following ProviderNotFoundError was thrown building MyApp(dirty):
I/flutter ( 9316): Error: Could not find the correct Provider<Settings> above this MyApp Widget
I/flutter ( 9316):
I/flutter ( 9316): To fix, please:
I/flutter ( 9316):
I/flutter ( 9316): * Ensure the Provider<Settings> is an ancestor to this MyApp Widget
I/flutter ( 9316): * Provide types to Provider<Settings>
I/flutter ( 9316): * Provide types to Consumer<Settings>
I/flutter ( 9316): * Provide types to Provider.of<Settings>()
The following test code work without error, you can test with your case
Use Consumer to wrap MaterialApp
code snippet
return MultiProvider(
providers: [
ChangeNotifierProvider<Posts>(
create: (context) => Posts(),
),
ChangeNotifierProvider<Settings>(
create: (context) => Settings(darkModeEnabled: true),
),
],
child: Consumer<Settings>(builder: (_, settings, child) {
return MaterialApp(
darkTheme:
settings.darkModeEnabled ? ThemeData.dark() : ThemeData.light(),
debugShowCheckedModeBanner: false,
title: 'Blogy',
theme: ThemeData(
primaryColor: Colors.deepPurple[900],
cursorColor: Colors.deepPurple[900],
accentColor: Colors.deepPurple[900],
fontFamily: 'Ubuntu',
),
home: SplashScreen(),
);
}),
);
full test code
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() => runApp(MyApp());
class Posts extends ChangeNotifier {}
class Settings extends ChangeNotifier {
bool darkModeEnabled;
Settings({this.darkModeEnabled});
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider<Posts>(
create: (context) => Posts(),
),
ChangeNotifierProvider<Settings>(
create: (context) => Settings(darkModeEnabled: true),
),
],
child: Consumer<Settings>(builder: (_, settings, child) {
return MaterialApp(
darkTheme:
settings.darkModeEnabled ? ThemeData.dark() : ThemeData.light(),
debugShowCheckedModeBanner: false,
title: 'Blogy',
theme: ThemeData(
primaryColor: Colors.deepPurple[900],
cursorColor: Colors.deepPurple[900],
accentColor: Colors.deepPurple[900],
fontFamily: 'Ubuntu',
),
home: SplashScreen(),
);
}),
);
}
}
class SplashScreen extends StatefulWidget {
SplashScreen({Key key}) : super(key: key);
//final String title;
#override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("test"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
This error happens because you are creating your providers and your consumers in the same build method. This results in them having the same context, which doesn't have any Provider<Settings> registered yet. Provider.of<Settings>(context) is trying to find a Provider<Settings> above in the widget tree, but there is no such provider there.
Using Consumer seems like a valid workaround, but recreating the whole MaterialApp on every change might be pretty heavy.
I suggest instead creating separate widgets for providers and the app root:
class AppProviders extends StatelessWidget {
final Widget child;
AppProviders({this.child});
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider<Posts>(
builder: (context) => Posts(),
),
ChangeNotifierProvider<Settings>(
builder: (context) => Settings(),
),
],
child: child;
);
}
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
darkTheme: Provider.of<Settings>(context).darkModeEnabled ? ThemeData.dark() :
ThemeData.light(),
debugShowCheckedModeBanner: false,
title: 'Blogy',
theme: ThemeData(
primaryColor: Colors.deepPurple[900],
cursorColor: Colors.deepPurple[900],
accentColor: Colors.deepPurple[900],
fontFamily: 'Ubuntu',
),
home: SplashScreen(),
);
}
}
Then wrap the MyApp widget in AppProviders inside the runApp function.
void main() {
runApp(
AppProviders(
child: MyApp(),
)
);
}
This ensures that the Providers are registered above your root app widget and that they are visible in its context.
Alternatively you can declare three widgets where the third one is just AppProviders(child: MyApp()) and call that one in runApp. Note that creating AppProviders inside MyApp's build method will result in the same error as before, so don't try it that way.

Flutter stateless UI life cycle

I have a Flutter app which is based on StatelessWidget. I saw an example with StatefulWidget which allows the programmer to perform some actions in the dispose() method. I am trying to see if the StatelessWidget also provides such feature?
import 'package:flutter/material.dart';
import 'routes.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My App',
theme: ThemeData(
primarySwatch: colorCustom,
fontFamily: 'Roboto',
),
initialRoute: '/',
routes: routes,
);
}
}
UPDATED
import 'package:flutter/material.dart';
import 'routes.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
Future<bool> _exitApp(BuildContext context) {
return showDialog(
context: context,
child: new AlertDialog(
title: new Text('Do you want to exit this application?'),
content: new Text('We hate to see you leave...'),
actions: <Widget>[
new FlatButton(
onPressed: () => Navigator.of(context).pop(false),
child: new Text('No'),
),
new FlatButton(
onPressed: () => Navigator.of(context).pop(true),
child: new Text('Yes'),
),
],
),
) ??
false;
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My App',
home: WillPopScope(
child: MaterialApp(
theme: ThemeData(
primarySwatch: colorCustom,
fontFamily: 'Roboto',
),
initialRoute: '/',
routes: routes
),
onWillPop: () => _exitApp(context)
)
);
}
Hm, after updating the code, the AlertDialog does not pop up though?
The short answer is no, there is no method similar to dispose() available in a StatelessWidget since as the name suggests, it does not maintain a State.
The long answer is the dispose() mehtod -
The framework calls this method when this State object will never build again. After the framework calls dispose, the State object is considered unmounted and the mounted property is false. It is an error to call setState at this point.
This stage of the lifecycle is terminal: there is no way to remount a State object that has been disposed.
Since the StatelessWidget has no State associated with it, there is no dispose() method.
A similar solution for StatelessWidgets -
So what should we do if we want to run some code only after theStatelessWidgets are popped from the navigation stack or return some data from the StatelessWidget?
Well, this Flutter docmentation page has a this explained along with an example. Hope this helps!