'my provider is not found, when I use selector
I run the below code using consumer and provider and it worked smoothly but when I add selector it geive me an error, the error: Error: Could not find the correct Provider above this Selector<SignInUpProvider, int> Widget
This happens because you used a BuildContext that does not include the provider
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import 'providers/sign_in_up_provider.dart';
import 'utilities/myColors.dart' ;
class SigInUpPage extends StatefulWidget {
const SigInUpPage({Key? key}) : super(key: key);
@override
_SigInUpPageState createState() => _SigInUpPageState();
}
class _SigInUpPageState extends State<SigInUpPage> {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(create: (context)=> SignInUpProvider(),
child: const SignInUpScreen(),);
}
}
class SignInUpScreen extends StatefulWidget {
const SignInUpScreen({Key? key}) : super(key: key);
@override
_SignInUpScreenState createState() => _SignInUpScreenState();
}
class _SignInUpScreenState extends State<SignInUpScreen> {
// determine the sign in or sign up screen!!
// 0 = sign up , 1 = sign in
// sign up contents
// final GlobalKey<FormState> _keySignUp = GlobalKey<FormState>();
final TextEditingController _nameSignUp = TextEditingController();
final TextEditingController _passSignup = TextEditingController();
final TextEditingController _emailSignUp = TextEditingController();
// sign in contents
final GlobalKey<FormState> _keySignIn = GlobalKey<FormState>();
final TextEditingController _emailSignIn = TextEditingController();
final TextEditingController _passSifnIn = TextEditingController();
@override
void dispose() {
_nameSignUp.dispose();
_passSifnIn.dispose();
_passSignup.dispose();
_emailSignIn.dispose();
_emailSignUp.dispose();
// TODO: implement dispose
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.white,
child: Stack(
children: [
// dummy design
firstScreen(context),
// dummy design
secondScreen(context),
// sign in screen
thirdScreen(context),
],
),
),
);
}
// first background in stack
Widget firstScreen(BuildContext context){
return
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color:MyColors.blueColor(),
);
}
// second background in stack
Widget secondScreen(BuildContext context){
return Align(
alignment: Alignment.bottomRight,
child: Container(
decoration: BoxDecoration(
color: MyColors.purple(),
borderRadius: const BorderRadius.only(bottomLeft:Radius.circular(1000),
topLeft: Radius.circular(1000)
)
),
width: MediaQuery.of(context).size.width * 0.5,
height: MediaQuery.of(context).size.height,
),
);
}
// sign in up screen // the white box
Widget thirdScreen(BuildContext context){
return Align(alignment: Alignment.bottomCenter,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Container(
margin: EdgeInsets.only(bottom: MediaQuery.of(context).size.height*0.1),
width: MediaQuery.of(context).size.width*0.7,
height: MediaQuery.of(context).size.height*0.7,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(50))),
child: Selector<SignInUpProvider, int>(
selector: (context, userState) => userState.getUserState,
builder: (context, state, widget){
return Form(
key: _keySignIn,
child: (state == 0 )?
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children:
[
logo(context),
nameBox(context),
emailBox(context),
passText(context),
signButton(context),
// this to change between sign in and sign up
changeState(context),
],
):
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children:
[
logo(context),
emailBox(context),
passText(context),
signButton(context),
// this to change between sign in and sign up
changeState(context),
],
),
);
}
),
),
),
);
}
// the logo inside the white box
Widget logo(context) {
return Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(50))
),
width: MediaQuery.of(context).size.width*0.7,
height: MediaQuery.of(context).size.height*0.1,
child: const Align(
alignment: Alignment.center,
child: Text("mekyajat",style: TextStyle(
fontStyle: FontStyle.italic,
fontSize: 16,
color: Color.fromRGBO(249, 229, 230, 1),
),)),
);
}
// name box
Widget nameBox(context){
return Container(
width: MediaQuery.of(context).size.width*0.55,
height: MediaQuery.of(context).size.height*0.1,
decoration: const BoxDecoration(
color: Colors.white70,
),
child: TextFormField(
controller:_nameSignUp ,
decoration: const InputDecoration(
icon: Icon(Icons.person),
hintText: "name",
hintStyle: TextStyle(
color: Colors.black12,
fontSize: 14
),
),
textAlign: TextAlign.center,
validator: (value){
if( value.toString().length < 8 ){
Fluttertoast.showToast(msg: "please insert your name \n more than 8 charecters",
gravity: ToastGravity.CENTER,
toastLength: Toast.LENGTH_SHORT,
backgroundColor: Colors.redAccent,
textColor: Colors.white,
fontSize: 16
);
} return null ;
},
),
);
}
Widget emailBox(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width*0.55,
height: MediaQuery.of(context).size.height*0.1,
decoration: const BoxDecoration(
color: Colors.white70,
),
child: TextFormField(
controller:(context.read<SignInUpProvider>().getUserState
== 0) ? _emailSignUp : _emailSignIn ,
decoration: const InputDecoration(
icon: Icon(Icons.email_outlined),
hintText: "E-mail @",
hintStyle: TextStyle(
color: Colors.black12,
fontSize: 14
),
),
textAlign: TextAlign.center,
validator: (value){
if( value.toString().length < 10 ){
Fluttertoast.showToast(msg: "please insert your email \n ",
gravity: ToastGravity.CENTER,
toastLength: Toast.LENGTH_SHORT,
backgroundColor: Colors.redAccent,
textColor: Colors.white,
fontSize: 16
);
}
else if (!containSymbol(value.toString(), "@")){
return "please insert @ symbol";
}
return null ;
},
),
);
}
Widget passText(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width*0.55,
height: MediaQuery.of(context).size.height*0.1,
decoration: const BoxDecoration(
color: Colors.white70,
),
child: TextFormField(
controller:(context.read<SignInUpProvider>().getUserState ==0)? _passSignup :_passSifnIn ,
decoration: const InputDecoration(
icon: Icon(Icons.password_sharp),
hintText: "password",
hintStyle: TextStyle(
color: Colors.black12,
fontSize: 14
),
),
textAlign: TextAlign.center,
validator: (value){
if( value.toString().length < 8 ){
Fluttertoast.showToast(msg: "please insert your password \n more than 8 charecters",
gravity: ToastGravity.CENTER,
toastLength: Toast.LENGTH_SHORT,
backgroundColor: Colors.redAccent,
textColor: Colors.white,
fontSize: 16
);
} return null ;
},
),
);
}
Widget signButton(BuildContext context) {
return Selector<SignInUpProvider, int>(
selector: (context,userState)=> userState.getUserState,
builder: (context, currentState, widget){
return InkWell(
child: Container(
alignment: Alignment.center,
width: MediaQuery.of(context).size.width*0.40,
height: MediaQuery.of(context).size.height*0.06,
child: (currentState == 0 )?
const Text("SIGN UP", textAlign: TextAlign.center,style: TextStyle(color: Colors.white),):
const Text("SIGN IN",textAlign: TextAlign.center, style: TextStyle(color: Colors.white),),
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(25)),
gradient: LinearGradient(colors: [
MyColors.blueColor(),
MyColors.purple(),
]),
),
),
onTap: (){},
);
},
);
}
Widget changeState(BuildContext context) {
return Consumer<SignInUpProvider>(
builder: (context, userSt , widget){
return InkWell(
child: SizedBox(
width: MediaQuery.of(context).size.width*0.55,
height: MediaQuery.of(context).size.height*0.05,
child:(userSt.userState == 0)?
const Text("sign in",
textAlign: TextAlign.right,
style: TextStyle(color:Color.fromRGBO(205, 221, 232, 1),fontSize: 12,
),) :
const Text("sign up",
textAlign: TextAlign.right,
style: TextStyle(
color:Color.fromRGBO(205, 221, 232, 1),fontSize: 12,
),)
),
onTap: (){
userSt.changeUserState(userSt.userState);
// SignInUpProvider().changeUserState(userState);
// signProvider.changeUserState(signProvider.userState);
},
);
},
);
}
}
// provide this function with one char and one string
// this run to see if the string contains char or not
bool containSymbol(String fullString , String char){
bool _result = false ;
List<String> _chars = [];
int _stringLingth = fullString.length;
int _keyLoop = 0 ;
while (_keyLoop < _stringLingth){
_chars.add(fullString[_keyLoop]);
_keyLoop++;
}
for(int x = 0 ; x < _chars.length; x++){
if(_chars[x] == char){
_result = true;
break;
}
}
return _result;
}
Solution 1:[1]
1 - move up your ChangeNotifierProvider step above in the widget tree for example in the routes you can wrap the SigInUpPage like this :
ChangeNotifierProvider<SignInUpProvider>(
create: (_) => SignInUpProvider(),
child: SigInUpPage(),
),
2 - don't pass the context as a parameter to the other screens,use a builder in each screen like this for the second screen:
class secondScreen extends StatelessWidget {
const secondScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Align(
alignment: Alignment.bottomCenter,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Container(
margin: EdgeInsets.only(bottom: MediaQuery.of(context).size.height*0.1),
width: MediaQuery.of(context).size.width*0.7,
height: MediaQuery.of(context).size.height*0.7,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(50))),
child: Selector<SignInUpProvider, int>(
selector: (context, userState) => userState.getUserState,
builder: (context, state, widget){
return Form(
key: _keySignIn,
child: (state == 0 )?
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children:
[
logo(context),
nameBox(context),
emailBox(context),
passText(context),
signButton(context),
// this to change between sign in and sign up
changeState(context),
],
):
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children:
[
logo(context),
emailBox(context),
passText(context),
signButton(context),
// this to change between sign in and sign up
changeState(context),
],
),
);
}
),
),
),
);
}
}
this should work
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
