I have some error in the Flutter code main.dart file .I create AuthService class,I create Provider method in the main.dart file, but it has some error at the call up the Provider method . i need solve this error.
enter image description here
import 'package:flutter/material.dart';
import 'package:trip/screen/first_screen.dart';
import 'package:trip/screen/sign_up_screen.dart';
import 'package:trip/services/auth_service.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return Provider(
auth: AuthService,
child: MaterialApp(
title: 'Test FireBase',
theme: ThemeData(
primarySwatch: Colors.green,
),
home: FirstScreen(),
routes: <String, WidgetBuilder>{
'/signUp': (BuildContext context) => SignUpScreen(),
'/home': (BuildContext context) => FirstScreen(),
},
),
);
}
}
class Provider extends InheritedWidget {
final AuthService auth;
Provider(Key key, Widget child, this.auth) : super(key: key, child: child);
#override
bool updateShouldNotify(InheritedWidget oldWidget) => true;
static Provider of(BuildContext context) =>
(context.dependOnInheritedWidgetOfExactType<Provider>() as Provider);
}
You are getting the error because the Provider constructor you made is working with positional parameters, not with named. For more information on named and positional parameters check out this post.
You can either change your constructor to work with named parameters like this:
Provider({Key? key, required Widget child, required this.auth}) : super(key: key, child: child);
or you can remove namings of your parameters in the cosntructor call like this:
return Provider(
UniqueKey(),
MaterialApp(
...
),
AuthService(),
);
I would prefer the first solution.
Related
Hello. I created 3 pages. The pages are as follows:
main.dart:
import 'package:flutter/material.dart';
import 'package:fotografci_sitesi/pages/home.dart';
import 'package:fotografci_sitesi/pages/profile.dart';
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
void main() {
setUrlStrategy(PathUrlStrategy());
runApp(mainApp());
}
class mainApp extends StatefulWidget {
mainApp({Key? key}) : super(key: key);
#override
State<mainApp> createState() => _mainAppState();
}
class _mainAppState extends State<mainApp> {
#override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: '/',
routes: {
homePage.route: (context) => homePage(),
profile.route: (context) => profile(),
},
home: homePage(),
);
}
}
pages/home.dart:
import 'package:flutter/material.dart';
import 'package:fotografci_sitesi/pages/profile.dart';
class homePage extends StatefulWidget {
static const String route = '/home';
homePage({Key? key}) : super(key: key);
#override
State<homePage> createState() => _homePageState();
}
class _homePageState extends State<homePage> {
#override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: 'Ana ',
home: Scaffold(
appBar: AppBar(
title: Text("Home"),
),
body: Column(
children: [
OutlinedButton(
child: Text("Profile"),
onPressed: () {
Navigator.of(context).pushNamed(profile.route);
},
),
],
),
),
);
}
}
pages/profile.dart:
import 'package:flutter/material.dart';
import 'package:flutter/material.dart';
class profile extends StatefulWidget {
static const String route = '/profile';
profile({Key? key}) : super(key: key);
#override
State<profile> createState() => _profileState();
}
class _profileState extends State<profile> {
#override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: '/profile',
home: Scaffold(
appBar: AppBar(
title: Text("Profile"),
),
body: Center(
child: Text("Profile"),
),
),
);
}
}
If you look at the codes, I tried to set up a URL system. I want to set up a URL system like this:
If it is entered to example.com, I want it to be redirected to homePage via main.dart.
If I enter example.com/home, I want it to be redirected to homePage.
If it is entered in example.com/profile, I want it to be redirected to profile.
Actually, I did what I wanted, but there is a problem. For example, when I enter example.com/profile, the URL in the address bar changes to example.com/. So it goes to the profile in the URL.
How can I solve this problem?
Sorry if I confused you. I think you understand my problem. Thanks in advance for your help.
Well, I notice you use both initialRoute and home property in the Material app (NB* ONLY USE ONE!!!). Try removing the home property and using only initialRoute. Also as a rule when you use forward slash as an initalRoute use '/' do not use something like '/profile'. compare with code below ...
MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => const homepage(),
'/profile': (context) => const profile(),
},
)
I just created a new flutter project and started organized my folders, this is what I have for now:
I'm trying to run it on Windows since I'll use Flutter Desktop for this project, and when I hit run it builds and runs just fine, but when I do a hot-reload the application throws this error message:
No constructor 'MaterialApp.' with matching arguments declared in class 'MaterialApp'.
Receiver: MaterialApp
Tried calling: new MaterialApp.()
Found: new MaterialApp.({Key? key, GlobalKey<NavigatorState>? navigatorKey, GlobalKey<ScaffoldMessengerState>? scaffoldMessengerKey, Widget? home, Map<String, (BuildContext) => Widget> routes, String? initialRoute, ((RouteSettings) => Route<dynamic>?)? onGenerateRoute, ((String) => List<Route<dynamic>>)? onGenerateInitialRoutes, ((RouteSettings) => Route<dynamic>?)? onUnknownRoute, List<NavigatorObserver> navigatorObservers, ((BuildContext, Widget?) => Widget)? builder, String title, ((BuildContext) => String)? onGenerateTitle, Color? color, ThemeData? theme, ThemeData? darkTheme, ThemeData? highContrastTheme, ThemeData? highContrastDarkTheme, ThemeMode? themeMode, Locale? locale, Iterable<LocalizationsDelegate<dynamic>>? localizationsDelegates, ((List<Locale>?, Iterable<Locale>) => Locale?)? localeListResolutionCallback, ((Locale?, Iterable<Locale>) => Locale?)? localeResolutionCallback, Iterable<Locale> supportedLocales, bool debugShowMaterialGrid, bool showPerformanceOverlay, bool checkerboardRasterCacheImages, bool checkerboardOffscreenLayers, bool showSemanticsDebugger, bool debugShowCheckedModeBanner, Map<LogicalKeySet, Intent>? shortcuts, Map<Type, Action<Intent>>? actions, String? restorationScopeId}) => MaterialApp
This is the content of my main.dart:
import 'package:flutter/material.dart';
import 'package:beryllium/src/screens/HomeScreen.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
MyApp({Key key}) : super(key: key);
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Beryllium',
initialRoute: '/',
routes: {
'/': (contex) => HomeScreen(), //Home screen widget
},
);
}
}
And this the content of the HomeScreen.dart file:
import 'package:flutter/material.dart';
class HomeScreen extends StatefulWidget {
HomeScreen({Key key}) : super(key: key);
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
#override
Widget build(BuildContext context) {
return new _HomeScreen();
}
}
class _HomeScreen extends StatelessWidget {
const _HomeScreen({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('My Book'),
),
body: Center(
child: Container(
child: Text('Home Screen'),
),
));
}
}
If someone has any idea about avoiding this error, please give me a hand.
Thanks in advance.
im trying to use StreamProvider with MultiProvider in MaterialApp
when I try accessing the provider, I get the following error:
Error: Could not find the correct Provider above this MyApp Widget
main.dart
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
final provider = Provider.of<SignInProvider>(context, listen: false);
return MultiProvider(
providers: [
StreamProvider<UserModel>.value(value: provider.authStateChange())
],
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primaryColor: primaryColor,
accentColor: secondaryColor,
textTheme: customTextTheme
),
home: AuthHandler()
),
);
}
}
class AuthHandler extends StatelessWidget {
#override
Widget build(BuildContext context) {
UserModel _userModel = Provider.of<UserModel>(context);
return (_userModel != null) ? HomeScreen() : LoginScreen();
}
}
user_model.dart
class UserModel {
String uid;
String displayName;
String photoURL;
String email;
UserModel({ this.uid, this.displayName, this.photoURL, this.email, });
}
signin_provider.dart
Stream<UserModel> authStateChange() {
return firebaseAuth.authStateChanges().map((User user) => (user != null) ? UserModel(uid: user.uid) : null);
}
Go to main.dart and Add Your Provider :
Example :
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider<ThemeBloc>(
create: (_) => ThemeBloc(),
child: Consumer<ThemeBloc>(
builder: (_, mode, child) {
return MultiProvider(
providers: [
ChangeNotifierProvider<SignInBloc>(
create: (context) => SignInBloc(),
),
ChangeNotifierProvider<NewsDataBloc>(
create: (context) => NewsDataBloc(),
),
ChangeNotifierProvider<PopularDataBloc>(
create: (context) => PopularDataBloc(),
),
],
child: MaterialApp(
home: MyHomePage()),
);
},
),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return WelcomePage();
}
}
I want to access and change data on parent class from child class. For this when I do it as in the code example below, it works. However, when I import the child class (ChildPage) from outside, not inside the same dart file, I cannot access the _MainPageState class.
It works like this.
main.dart
import 'package:flutter/material.dart';
class MainPage extends StatefulWidget {
#override
_MainPageState createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
int selectedIndex = 0;
#override
Widget build(BuildContext context) {
return Column(
children: [
ChildPage(this),
],
);
}
}
//this is my child page
class ChildPage extends StatefulWidget {
_MainPageState parent;
ChildPage(this.parent);
#override
_ChildPageState createState() => _ChildPageState();
}
class _ChildPageState extends State<ChildPage> {
#override
Widget build(BuildContext context) {
return Container(
child: GestureDetector(
onTap: (){
widget.parent.setState(() {
widget.parent.selectedIndex = 1;
});
},
child: Text('click'),
),
);
}
}
It works when I write the above way. However, I want to separate both classes and write them as different dart files. For this, I tried to do as follows, but was not successful. I want to change the selectedIndex variable in main.dart by accessing it from the child.dart file. How can I do it?
main.dart
import 'package:flutter/material.dart';
class MainPage extends StatefulWidget {
#override
_MainPageState createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
int selectedIndex = 0;
#override
Widget build(BuildContext context) {
return Column(
children: [
ChildPage(this),
],
);
}
}
child.dart
import 'package:flutter/material.dart';
import 'main.dart';
class ChildPage extends StatefulWidget {
_MainPageState parent; // it shows Undefined class '_MainPageState'.
ChildPage(this.parent);
#override
_ChildPageState createState() => _ChildPageState();
}
class _ChildPageState extends State<ChildPage> {
#override
Widget build(BuildContext context) {
return Container(
child: GestureDetector(
onTap: (){
// here i want to access selectedIndex in main.dart like widget.parent.selectedIndex
},
child: Text('click'),
),
);
}
}
As i understand you want to do like tab controller.
Or you can use like below with Navigator.
1- Navigation Helper
class NavigationHelper{
static const String HOME="/home";
static const String DETAIL="/detail";
}
2- Main
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter sadas',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
routes: {
"/home": (context) => MyHomePage(title: 'Flutter Demo asdad Page'),
"/firebase": (context) => FireBaseBook(),
"/pageview": (context) => PageViewM(),
"/html": (context) => HTML(),
"/file": (context) => FileDown(),
"/tab": (context) => MyTabBar(),
"/sliver": (context) => SliverView(),
"/detail": (context) => Detail(),
"/": (context) => DownloadWidget(),
});
}
}
3- Navigator
Navigator.pushNamed(context, NavigationHelper.DETAIL);
Question:
How to call methodA() from onPressed() of IconButton.
I've tryed to do this by using GlobalKey:
GlobalKey<_MyButtonState> globalKey = GlobalKey();
But it's returns an error.
I have read many forums on this and I have tried all the solutions posed but none of them are working for me.
CODE:
main.dart
import 'package:flutter/material.dart';
import 'button.dart';
void main() {
runApp(MaterialApp( title: 'My app', home: MyApp(),));
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.help),
onPressed: () {
// how can I call methodA from here?
},
),
),
body: HomePage(),
),
);
}
}
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
#override
Widget build(BuildContext context) {
return Center(
child: MyButton(),
);
}
}
button.dart
import 'package:flutter/material.dart';
class MyButton extends StatefulWidget {
#override
_MyButtonState createState() => _MyButtonState();
}
class _MyButtonState extends State<MyButton> {
#override
Widget build(BuildContext context) {
return Container( );
}
void methodA(){
print('methodA');
}
}
I have read many forums on this and I have tried all the solutions posed but none of them are working for me.
first, you will have to import the file as a package in main.dart:
Main.dart: (just writing the way to import the file)
import 'package:prioject_name/file_name.dart';
Note: this is for files under lib directory.
if your file is under a different directory inside lib
then add the path accordingly,
eg: Button.dart is inside the widgets folder inside the lib folder:
lib
|____widgets
|____Button.dart
then the import statement will be as follows:
import 'package:prioject_name/widgets/Button.dart';
Then try your global key method to call the function:
If it is still not working then you can use my method,
how I call methods from different class in onPressed or onTapped:
your Button.dart file.
import 'package:flutter/material.dart';
// changed the method definition class
class MyButton extends StatefulWidget {
void methodA(){
print('methodA');
}
#override
_MyButtonState createState() => _MyButtonState();
}
class _MyButtonState extends State<MyButton> {
#override
Widget build(BuildContext context) {
...
widget.methodA(); // this would call the method A, anywhere inside the Widget build() function.
return Container( );
}
}
Now in Main.dart:
import 'package:prioject_name/Button.dart';
//call the function here using className().functioName();
....
onPressed(){
MyButton().methodA();
}
Take a look at the InheritedWidget class (and watch the videos).
Base class for widgets that efficiently propagate information down the
tree.
You can look at creating an InheritedWidget that contains a ValueNotifier.
class MyInheritedWidget extends InheritedWidget {
final ValueNotifier<int> buttonTapCountNotifier;
const MyInheritedWidget({
Key key,
#required this.buttonTapCountNotifier,
#required Widget child,
}) : assert(child != null),
super(key: key, child: child);
static MyInheritedWidget of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<MyInheritedWidget>();
}
}
Your MyButton class can call MyInheritedWidget.of(context).buttonTapCountNotifier to get hold of the ValueNotifier and add a listener to it.
Each time the ValueNotifier notifies your MyButton class that the value has been incremented, you can execute methodA.
You could use the Provider package which is quite the preferred method to manage state in Flutter apps. This will help you as well in organizing and growing the app in a clever way.
Take a look at the working code below.
define a ChangeNotifier (PressedProvider) which will save
current state of the app in a unique location and the behavior of your onPress function
you wrap your app
with a ChangeNotifierProvider widget
you wrap the receiving
Widget with a Consumer
you get the Provider.of() when you
need to do something and call a method on it
it will notify the Consumer of a change
Code:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(ChangeNotifierProvider<PressedProvider>( // 2
create: (_) => PressedProvider(),
child: MyApp(),
));
}
class PressedProvider extends ChangeNotifier { // 1
void pressButton() {
print("pressButton");
notifyListeners();
}
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
leading: Consumer<PressedProvider>( // 3
builder: (_, provider, widget) => IconButton(
icon: Icon(Icons.help),
onPressed: () {
provider.pressButton();
},
),
),
),
body: Center(
child: MyButton(),
),
),
);
}
}
class MyButton extends StatelessWidget {
#override
Widget build(BuildContext context) {
PressedProvider provider = Provider.of<PressedProvider>(context); // 4
return Center(
child: RawMaterialButton(
child: Text("Press me"),
onPressed: () => provider.pressButton()),
);
}
}