问题描述
我的代码实际上正在工作,并且当前正在使用从以前版本的Flutter构建的应用程序工作。我使用相同的代码再次构建了它,但使用Flutter 1.22进行了升级,并且现在在Provider上引起了错误。由于该代码实际上有效,所以我似乎无法弄清为什么它会引发错误。
这是我的代码:
class HomePage extends StatefulWidget {
static final String id = 'home_page';
final String currentUserId;
HomePage({this.currentUserId});
@override
_HomePageState createState() => _HomePageState();
}
CategoryProvider categoryProvider;
ProductProvider productProvider;
class _HomePageState extends State<HomePage> {
// variables
double height,width;
bool homeColor = true;
bool checkoutColor = false;
bool aboutColor = false;
bool contactUsColor = false;
bool profileColor = false;
MediaQueryData mediaQuery;
TextEditingController searchTextEditingController = TextEditingController();
//category each tile change to Service
Widget _buildCategoryProduct({String name,String image,int color}) {
return Container(
child: Column(
children: <Widget>[
Container(
height: 50,padding: EdgeInsets.all(10),decoration: Boxdecoration(
BoxShadow: shadowList,color: Colors.white,borderRadius: BorderRadius.circular(10)),// maxRadius: height * 0.1 / 2.1,// backgroundColor: Colors.white,child: Image(
image:
/// changed
Assetimage('images/category/$image'),),Text(
name,style: GoogleFonts.raleway(
fontSize: 12,fontWeight: FontWeight.bold,letterSpacing: 1.0,textStyle: TextStyle(color: Colors.black),],);
}
// firebase auth drawer details
/// look into it after
Widget _buildUserAccountsDrawerHeader() {
List<usermodel> usermodel = productProvider.usermodelList;
return Column(
children: usermodel.map((e) {
return UserAccountsDrawerHeader(
accountName: Text(
e.userName,style: TextStyle(color: Colors.black),currentAccountPicture: CircleAvatar(
backgroundColor: Colors.white,backgroundImage: e.userImage == null
? Assetimage("images/userImage.png")
: NetworkImage(e.userImage),decoration: Boxdecoration(color: Color(0xfff2f2f2)),accountEmail: Text(e.userEmail,style: TextStyle(color: Colors.black)),);
}).toList());
}
//build drawer left side/sidebar
Widget _buildMyDrawer() {
return Drawer(
child: ListView(
children: <Widget>[
_buildUserAccountsDrawerHeader(),ListTile(
selected: homeColor,onTap: () {
setState(() {
homeColor = true;
contactUsColor = false;
checkoutColor = false;
aboutColor = false;
profileColor = false;
});
},leading: Icon(Icons.home),title: Text("Home"),ListTile(
selected: checkoutColor,onTap: () {
setState(() {
checkoutColor = true;
contactUsColor = false;
homeColor = false;
profileColor = false;
aboutColor = false;
});
// Navigator.of(context).pushReplacement(
// MaterialPageRoute(builder: (ctx) => CheckOut()));
},leading: Icon(Icons.shopping_cart),title: Text("Checkout"),ListTile(
selected: aboutColor,onTap: () {
setState(() {
aboutColor = true;
contactUsColor = false;
homeColor = false;
profileColor = false;
checkoutColor = false;
});
// Navigator.of(context).pushReplacement(
// MaterialPageRoute(builder: (ctx) => About()));
},leading: Icon(Icons.info),title: Text("About"),ListTile(
selected: profileColor,onTap: () {
setState(() {
aboutColor = false;
contactUsColor = false;
homeColor = false;
profileColor = true;
checkoutColor = false;
});
// Navigator.of(context).pushReplacement(
// MaterialPageRoute(
// builder: (ctx) => ProfileScreen(),// ),// );
},title: Text("Profile"),ListTile(
selected: contactUsColor,onTap: () {
setState(() {
contactUsColor = true;
checkoutColor = false;
profileColor = false;
homeColor = false;
aboutColor = false;
});
// Navigator.of(context).pushReplacement(
// MaterialPageRoute(builder: (ctx) => ContactUs()));
},leading: Icon(Icons.phone),title: Text("Contant Us"),ListTile(
onTap: () {
FirebaseAuth.instance.signOut();
},leading: Icon(Icons.exit_to_app),title: Text("logout"),);
}
/// carousel on top/ change images ^^finalized
Widget _buildImageSlider() {
return Container(
height: 200,child: Carousel(
borderRadius: true,radius: Radius.circular(20),autoplay: true,autoplayDuration: Duration(seconds: 10),showIndicator: false,images: [
// change it up to more approp
Assetimage('images/banner2.jpg'),Assetimage('images/banner1.jpg'),Assetimage('images/banner4.jpg'),);
}
// build category/services row """"
Widget _buildCategory() {
return Column(
children: <Widget>[
Container(
height: 40,child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,children: <Widget>[
Text(
"SERVICES",style: GoogleFonts.caveat(
fontSize: 20,letterSpacing: 3.0,Container(
height: 70,// change new
child: ListView(
scrollDirection: Axis.horizontal,children: <Widget>[
Row(
children: <Widget>[
// each Service icon
_buildHairIcon(),SizedBox(width: 20),_buildWaxIcon(),_buildPedicureIcon(),_buildManicureIcon(),_buildFacialIcon(),);
}
// row of featured and archives view more
Widget _buildNewAchives() {
final Orientation orientation = MediaQuery.of(context).orientation;
return Container(
/// look into it
height: 500,child: GridView.count(
crossAxisCount: orientation == Orientation.portrait ? 2 : 3,childAspectRatio: orientation == Orientation.portrait ? 0.8 : 0.9,children: productProvider.getHomeAchiveList.map((e) {
return GestureDetector(
onTap: () {
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (ctx) => DetailScreen(
userId: widget.currentUserId,hairdresserId: e.id,image: e.image,rating: e.rating,name: e.name,surname: e.surname,description: e.description,city: e.city,waxPrice: e.waxPrice,facialPrice: e.facialPrice,manicurePrice: e.manicurePrice,pedicurePrice: e.pedicurePrice,hairPrice: e.hairPrice,);
},child: SingleProduct(
image: e.image,city: e.city),);
}).toList(),);
}
// row of featured and archives view more
Widget _buildrow() {
List<Product> newAchivesProduct = productProvider.getNewAchiesList;
return Container(
height: height * 0.1 - 30,child: Column(
mainAxisAlignment: MainAxisAlignment.end,children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,children: <Widget>[
Text(
"FEATURED ",GestureDetector(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (ctx) => ListProduct(
userId: widget.currentUserId,name: "Featured",isCategory: false,snapShot: newAchivesProduct,);
},child: Text(
"View all",style: GoogleFonts.raleway(
fontSize: 15,)
],);
}
final GlobalKey<ScaffoldState> _key = GlobalKey<ScaffoldState>();
// to get from online firebase database//change names
void getCallAllFunction() {
categoryProvider.getWaxData();
categoryProvider.getHairData();
categoryProvider.getPedicureData();
categoryProvider.getManicureData();
categoryProvider.getFacialData();
categoryProvider.getHairIconData();
productProvider.getNewAchiveData();
productProvider.getFeatureData();
productProvider.getHomeFeatureData();
productProvider.getHomeAchiveData();
categoryProvider.getWaxIcon();
categoryProvider.getPedicureIconData();
categoryProvider.getManicureIconData();
categoryProvider.getFacialIconData();
// productProvider.getUserData();
}
@override
Widget build(BuildContext context) {
//from models product= hairdresser data
categoryProvider = Provider.of<CategoryProvider>(context);
productProvider = Provider.of<ProductProvider>(context);
final String currentUserId = Provider.of<UserData>(context).currentUserId;
getCallAllFunction();
height = MediaQuery.of(context).size.height;
width = MediaQuery.of(context).size.width;
return Scaffold(
key: _key,drawer: _buildMyDrawer(),// bottomNavigationBar: BottomNavBar(),appBar: AppBar(
toolbarOpacity: 0,shape: RoundedRectangleBorder(),// search field
title: Text(
'The Mob',style: TextStyle(
color: Colors.white,fontFamily: 'Billabong',fontSize: 35.0,elevation: 0.0,backgroundColor: Colors.blueGrey,leading: IconButton(
icon: SvgPicture.asset("images/menu.svg"),onpressed: () {
_key.currentState.openDrawer();
},actions: <Widget>[
NotificationButton(),body: Container(
height: double.infinity,width: double.infinity,margin: EdgeInsets.symmetric(horizontal: 20),child: ListView(
scrollDirection: Axis.vertical,children: <Widget>[
SizedBox(height: 5),Container(
width: double.infinity,child: Column(
crossAxisAlignment: CrossAxisAlignment.start,children: <Widget>[
_buildImageSlider(),_buildCategory(),_buildrow(),_buildNewAchives(),);
}
}
'''
我主要提供了多个提供程序,而子级作为MaterialApp。因此,主文件如下所示:
'''
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(
create: (context) => ServicesNotifier(),ChangeNotifierProvider(
create: (context) => HairdresserData(),ChangeNotifierProvider(
create: (context) => ServicesNotifier(),ChangeNotifierProvider<CategoryProvider>(
create: (context) => CategoryProvider(),ChangeNotifierProvider<ProductProvider>(
create: (context) => ProductProvider(),ChangeNotifierProvider(
create: (context) => UserData(),child: MyApp(),);
}
'''
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,home: OnboardingScreen(),routes: {
// '/a': (_) => Authenticate(),SignInScreen.id: (context) => SignInScreen(),RegisterScreen.id: (context) => RegisterScreen(),LoginScreen.id: (context) => LoginScreen(),SignupScreen.id: (context) => SignupScreen(),'/b': (_) => Customer(),'/c': (_) => Hairdresser(),'/d': (_) => Choose(),'/e': (_) => IndicatorScreen(),},);
}
}
错误如下:
The following ProviderNotFoundException was thrown building HomePage(dirty,state:
Flutter: _HomePageState#fb424):
Flutter: Error: Could not find the correct Provider<CategoryProvider> above this HomePage Widget
Flutter:
Flutter: This likely happens because you used a `BuildContext` that does not include the provider
Flutter: of your choice. There are a few common scenarios:
Flutter:
Flutter: - The provider you are trying to read is in a different route.
Flutter:
Flutter: Providers are "scoped". So if you insert of provider inside a route,then
Flutter: other routes will not be able to access that provider.
Flutter:
Flutter: - You used a `BuildContext` that is an ancestor of the provider you are trying to read.
Flutter:
Flutter: Make sure that HomePage is under your MultiProvider/Provider<CategoryProvider>.
Flutter: This usually happen when you are creating a provider and trying to read it immediately.
Flutter:
Flutter: For example,instead of:
Flutter:
Flutter: ```
Flutter: Widget build(BuildContext context) {
Flutter: return Provider<Example>(
Flutter: create: (_) => Example(),Flutter: // Will throw a ProviderNotFoundError,because `context` is associated
Flutter: // to the widget that is the parent of `Provider<Example>`
Flutter: child: Text(context.watch<Example>()),Flutter: ),Flutter: }
Flutter: ```
Flutter:
Flutter: consider using `builder` like so:
Flutter: ```
Flutter: Widget build(BuildContext context) {
Flutter: return Provider<Example>(
Flutter: create: (_) => Example(),Flutter: // we use `builder` to obtain a new `BuildContext` that has access to the provider
Flutter: builder: (context) {
Flutter: // No longer throws
Flutter: return Text(context.watch<Example>()),Flutter: }
Flutter: ),Flutter: }
Flutter: ```
解决方法
我只是通过将所有文件移动到 lib 而不是将 provider 目录设置为 lib 来解决这个问题,因为 provider 无法找到我们想要使用的另一个文件。它对我有用。