- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试添加网格列表,同时添加第二个网格的项目时发现以下错误:
Error: Could not find the correct Provider<Cities> above this PropertiesGrid Widget
To fix, please:
* Ensure the Provider<Cities> is an ancestor to this PropertiesGrid Widget
* Provide types to Provider<Cities>
* Provide types to Consumer<Cities>
* Provide types to Provider.of<Cities>()
* Always use package imports. Ex: `import 'package:my_app/my_code.dart';
* Ensure the correct `context` is being used.
If none of these solutions work, please file a bug at:
https://github.com/rrousselGit/provider/issues
我认为我的
Home Screen
中的问题在下面的代码部分:
Expanded(
child: FutureBuilder<bool>(
future: getData(),
builder: (BuildContext context,
AsyncSnapshot<bool> snapshot) {
if (!snapshot.hasData) {
return const SizedBox();
} else {
return ChangeNotifierProvider(
create: (context) => Properties(),
child: PropertiesGrid(_showOnlyFavorites),
);
}
},
),
),
所以这是我在这类部分中划分的代码
Providers
,
Screens
,
Widgets
如下图所示:
import 'package:flutter/rendering.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../providers/properties.dart';
import '../providers/cities.dart';
import '../widgets/properties_grid.dart';
import '../app_theme.dart';
class MyHomePage extends StatefulWidget {
const MyHomePage({Key key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
int currentTab = 0;
ScrollController _scrollController = ScrollController();
bool _showBottomBar = true;
_scrollListener() {
if (_scrollController.position.userScrollDirection ==
ScrollDirection.reverse) {
setState(() {
_showBottomBar = false;
});
} else if (_scrollController.position.userScrollDirection ==
ScrollDirection.forward) {
setState(() {
_showBottomBar = true;
});
}
}
var _showOnlyFavorites = false;
AnimationController animationController;
bool multiple = true;
@override
void initState() {
animationController = AnimationController(
duration: const Duration(milliseconds: 2000), vsync: this);
_scrollController.addListener(_scrollListener);
super.initState();
}
Future<bool> getData() async {
await Future<dynamic>.delayed(const Duration(milliseconds: 0));
return true;
}
@override
void dispose() {
animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 6, // Added
initialIndex: 0,
child: Scaffold(
resizeToAvoidBottomPadding: false,
extendBody: true,
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {},
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
bottomNavigationBar: AnimatedContainer(
duration: Duration(milliseconds: 500),
child: _showBottomBar
? BottomAppBar(
elevation: 0,
shape: CircularNotchedRectangle(),
notchMargin: 10,
child: Container(
height: 60,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
MaterialButton(
padding: EdgeInsets.all(0),
minWidth: 155,
onPressed: () {
setState(() {
// currentScreen =
// Chat(); // if user taps on this dashboard tab will be active
currentTab = 1;
});
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.home,
color: currentTab == 1
? Colors.blue
: Colors.grey,
),
Text(
'Home',
style: TextStyle(
color: currentTab == 1
? Colors.blue
: Colors.grey,
),
),
],
),
)
],
),
// Right Tab bar icons
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
MaterialButton(
padding: EdgeInsets.all(0),
minWidth: 60,
onPressed: () {
setState(() {
// currentScreen =
// Settings(); // if user taps on this dashboard tab will be active
currentTab = 3;
});
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.view_list,
color: currentTab == 3
? Colors.blue
: Colors.grey,
),
Text(
'Property List',
style: TextStyle(
color: currentTab == 3
? Colors.blue
: Colors.grey,
),
),
],
),
),
MaterialButton(
padding: EdgeInsets.all(0),
minWidth: 77,
onPressed: () {
setState(() {
// currentScreen =
// Settings(); // if user taps on this dashboard tab will be active
currentTab = 4;
});
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.location_searching,
color: currentTab == 4
? Colors.blue
: Colors.grey,
),
Text(
'Map',
style: TextStyle(
color: currentTab == 4
? Colors.blue
: Colors.grey,
),
),
],
),
),
],
)
],
),
),
)
: Container(
color: Colors.white,
width: MediaQuery.of(context).size.width,
),
),
backgroundColor: AppTheme.white,
body: Stack(
children: <Widget>[
FutureBuilder<bool>(
future: getData(),
builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
if (!snapshot.hasData) {
return const SizedBox();
} else {
return Padding(
padding: EdgeInsets.only(
top: MediaQuery.of(context).padding.top),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
appBar(),
tabBar(),
Expanded(
child: FutureBuilder<bool>(
future: getData(),
builder: (BuildContext context,
AsyncSnapshot<bool> snapshot) {
if (!snapshot.hasData) {
return const SizedBox();
} else {
return ChangeNotifierProvider(
create: (context) => Properties(),
child: PropertiesGrid(_showOnlyFavorites),
);
}
},
),
),
],
),
);
}
},
),
],
),
),
);
}
Widget appBar() {
return SizedBox(
height: AppBar().preferredSize.height,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 8, left: 8),
child: Container(
width: AppBar().preferredSize.height - 8,
height: AppBar().preferredSize.height - 8,
),
),
Expanded(
child: Center(
child: Padding(
padding: const EdgeInsets.only(top: 4),
child:
Image.asset('assets/images/logo.png', fit: BoxFit.contain),
),
),
),
Padding(
padding: const EdgeInsets.only(top: 8, right: 8),
child: Container(
width: AppBar().preferredSize.height - 8,
height: AppBar().preferredSize.height - 8,
color: Colors.white,
child: Material(
color: Colors.transparent,
child: InkWell(
borderRadius:
BorderRadius.circular(AppBar().preferredSize.height),
child: Icon(
Icons.location_on,
color: AppTheme.dark_grey,
),
onTap: () {
setState(() {
multiple = !multiple;
});
},
),
),
),
),
],
),
);
}
Widget tabBar() {
return SizedBox(
height: AppBar().preferredSize.height,
child: TabBar(
isScrollable: true,
unselectedLabelColor: Colors.green,
labelColor: Colors.blue,
indicatorColor: Colors.blue,
labelStyle: TextStyle(fontSize: 15.0,fontStyle: FontStyle.italic),
tabs: [
Tab(
child: Text('All'),
),
Tab(
child: Text('Office'),
),
Tab(
child: Text('Commercial'),
),
Tab(
child: Text('Land'),
),
Tab(
child: Text('House/Villa'),
),
Tab(
child: Text('Apartement'),
),
],
),
);
}
}
这是 Grid 小部件的列表:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import './province_item.dart';
import './property_item.dart';
import '../providers/cities.dart';
import '../providers/properties.dart';
// import '../providers/properties.dart';
class PropertiesGrid extends StatelessWidget {
final bool showFavs;
PropertiesGrid(this.showFavs);
@override
Widget build(BuildContext context) {
final propertiesData = Provider.of<Properties>(context);
final citiesData = Provider.of<Cities>(context);
// final productData = Provider.of<Cities>(context);
final properties = showFavs ? propertiesData.favoriteItems : propertiesData.items;
final cities = citiesData.items;
return Container(
color: Colors.transparent,
child: SingleChildScrollView(
child: Column(
children: [
Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(6.0),
child: Align(
child: Text(
"Show All",
style: TextStyle(
fontSize: 16,
fontStyle: FontStyle.italic,
color: Colors.green),
),
alignment: Alignment.topLeft,
),
),
Container(
margin: const EdgeInsets.only(left: 95.0),
child: Padding(
padding: const EdgeInsets.all(6.0),
child: Align(
child: Text(
"Popular Properties",
style: TextStyle(
fontSize: 18,
fontStyle: FontStyle.italic,
color: Colors.black.withOpacity(0.8)),
),
alignment: Alignment.topRight,
),
),
),
],
),
SizedBox(
height: 250,
child: Column(
children: <Widget>[
Expanded(
child: GridView.builder(
padding: const EdgeInsets.all(10.0),
itemCount: properties.length,
itemBuilder: (ctx, i) => ChangeNotifierProvider.value(
// builder: (c) => products[i],
value: properties[i],
child: PropertyItem(
// products[i].id,
// products[i].title,
// products[i].imageUrl,
),
),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
childAspectRatio: 3 / 4,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
scrollDirection: Axis.horizontal,
),
),
],
),
),
Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(6.0),
child: Align(
child: Text(
"Show All",
style: TextStyle(
fontSize: 16,
fontStyle: FontStyle.italic,
color: Colors.green),
),
alignment: Alignment.topLeft,
),
),
Container(
margin: const EdgeInsets.only(left: 180.0),
child: Padding(
padding: const EdgeInsets.all(6.0),
child: Align(
child: Text(
"Province",
style: TextStyle(
fontSize: 18,
fontStyle: FontStyle.italic,
color: Colors.black.withOpacity(0.8)),
),
alignment: Alignment.topRight,
),
),
),
],
),
SizedBox(
height: 250,
child: Column(
children: <Widget>[
Expanded(
child: GridView.builder(
padding: const EdgeInsets.all(10.0),
itemCount: cities.length,
itemBuilder: (ctx, i) => ChangeNotifierProvider.value(
// builder: (c) => products[i],
value: cities[i],
child: ProvinceItem(
// products[i].id,
// products[i].title,
// products[i].imageUrl,
),
),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
childAspectRatio: 3 / 4,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
scrollDirection: Axis.horizontal,
),
),
],
),
),
],
),
),
);
}
}
这是与小部件相关的省份项目:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../providers/city.dart';
class ProvinceItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
final city = Provider.of<City>(context, listen: false);
return Padding(
padding: const EdgeInsets.all(8.0),
child: InkWell(
splashColor: Colors.transparent,
onTap: () => {},
child: Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(16.0)),
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.grey.withOpacity(0.6),
offset: const Offset(2.5, 2.5),
blurRadius: 16,
),
],
),
margin: EdgeInsets.all(2),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(15),
topRight: Radius.circular(15),
bottomLeft: Radius.circular(15),
bottomRight: Radius.circular(15),
),
child: Image.asset(
city.cityImage,
fit: BoxFit.cover,
),
),
),
),
);
}
}
这是
City
提供者:
import 'package:flutter/material.dart';
class City with ChangeNotifier {
final String cityId;
final String cityName;
final String cityImage;
City({
@required this.cityId,
@required this.cityName,
@required this.cityImage,
});
}
我把这个虚拟数据放在 Provider 中,就像下面的代码一样:
import '../providers/city.dart';
import 'package:flutter/material.dart';
// import './property.dart';
class Cities with ChangeNotifier {
List<City> _items = [
City(
cityId: 'city1',
cityName: 'Amman',
cityImage: 'assets/images/amman.png',
),
City(
cityId: 'city2',
cityName: 'Jerash',
cityImage: 'assets/images/amman.png',
),
City(
cityId: 'city3',
cityName: 'Karak',
cityImage: 'assets/images/amman.png',
),
City(
cityId: 'city4',
cityName: 'Aqaba',
cityImage: 'assets/images/amman.png',
),
City(
cityId: 'city5',
cityName: 'Zarqa',
cityImage: 'assets/images/amman.png',
),
City(
cityId: 'city6',
cityName: 'Madaba',
cityImage: 'assets/images/amman.png',
),
City(
cityId: 'city7',
cityName: 'Balqa',
cityImage: 'assets/images/amman.png',
),
City(
cityId: 'city8',
cityName: 'Mafraq',
cityImage: 'assets/images/amman.png',
),
City(
cityId: 'city9',
cityName: 'Maan',
cityImage: 'assets/images/amman.png',
),
City(
cityId: 'city10',
cityName: 'Ajloun',
cityImage: 'assets/images/amman.png',
),
City(
cityId: 'city11',
cityName: 'Irbid',
cityImage: 'assets/images/amman.png',
),
City(
cityId: 'city12',
cityName: 'Tafila',
cityImage: 'assets/images/amman.png',
),
];
List<City> get items {
return [..._items];
}
City findById(String cityId) {
return _items.firstWhere((cit) => cit.cityId == cityId);
}
}
我很抱歉添加了很多代码我试图添加所有需要的信息......
最佳答案
哇,那是你发布的相当多的代码。我必须承认我没有仔细研究它,但我想我明白了问题所在:正如错误消息指出的那样,您没有注入(inject)类型为 Cities
的 Provider在上下文树中 PropertiesGrid
的点上方建成。PropertiesGrid
中的这些行:
final propertiesData = Provider.of<Properties>(context);
final citiesData = Provider.of<Cities>(context);
Properties
的实例和
Cities
之一从上下文树中的点上方。如果您不满足此类要求,提供商将无情地对您进行崩溃。事实上,你得到了:
(22371): Error: Could not find the correct Provider<Cities> above this PropertiesGrid Widget
PropertiesGrid
小部件内置在您的主页中:
if (!snapshot.hasData) {
return const SizedBox();
} else {
return ChangeNotifierProvider(
create: (context) => Properties(),
child: PropertiesGrid(_showOnlyFavorites),
);
}
Properties
上面的实例
PropertiesGrid
,但没有人提供
Cities
的实例,因此您的小部件具有无法满足的依赖关系。
MultiProvider
注入(inject)两个依赖项。像这样
if (!snapshot.hasData) {
return const SizedBox();
} else {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => Properties()),
ChangeNotifierProvider(create: (context) => Cities()),
],
child: PropertiesGrid(_showOnlyFavorites),
);
}
MultiProvider
不是强制性的:即使在 HomePage 树的不同高度,您也可以使用两个提供程序注入(inject)这两个实例。只要这两个提供程序构建在
PropertiesGrid
之上你很厉害。
关于flutter - 如何在同一个 `ChangeNotifierProvider` 小部件上返回多个 `Expanded`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62232360/
我正在尝试从flutter应用程序构建apk,但出现此错误: Note: /mnt/Software/Linux/Flutter/flutter/.pub-cache/hosted/pub.dartl
我有一个名为 X 的较大应用程序,还有另一个名为 Y 的较小应用程序。他们现在彼此分开,并且工作正常。我想将应用程序 Y 集成到 X 中。我想将 Y 的代码放入 X 项目中,但它们应该有不同的 Mai
在android Studio中选择Create New Flutter Project,出现如下4个选项。 Flutter 应用程序 Flutter 插件 Flutter 包 flutter 模块
我看到我的 flutter 项目生成了一个文件 ios/Flutter/Flutter.podspec ,这个文件有什么用? 如果它与生成的 Flutter.framework 有关? 我应该将它包含
我尝试过的 在包含flutter SDK的位置添加/编辑.bash_profile.rtf文件。 导出PATH = / Users / temur / Documents / Projects / F
Flutter 日志会打印数千个详细/垃圾邮件日志。 我正在尝试调试一个复杂的应用程序,但是打印太冗长了,以至于我很难找到我自己打印的东西。 有没有办法禁用详细? 就像是: Logger.level.
在flutter 1.22更新之后,我在Lineargradient colors属性中遇到错误,这给我一个错误,即未定义名称colors参数。.在Android中更新flutter和flutter插
在下面的代码 widget.hintText 中给出错误,我试图将日期选择器作为单独的组件,并在从其他文件调用它时动态传递提示文本值。 import 'package:date_field/date_
在下面的代码 widget.hintText 中给出错误,我试图将日期选择器作为单独的组件,并在从其他文件调用它时动态传递提示文本值。 import 'package:date_field/date_
Flutter 1.0 发布后,我正在按照步骤搭建 Flutter 开发环境。 在步骤中(如所附屏幕截图所示),它说要更新 $PATH 两次,一次使用 flutter 工具的路径 export PAT
我有一个用 flutter 编写的移动应用程序,我想将其转换为 flutter_web 应用程序(集成 flutter_web 尚不可用)。我目前遇到包裹问题。 我已按照本网站中列出的说明进行操作 h
如何向我的 Flutter 路由添加自定义转换?这是我目前的路线结构。 class MyApp extends StatelessWidget { // This widget is the
我正在尝试通过 URL 在 webview 中显示网页。我试过 flutter_webview_plugin 插件,但是当我在浏览器上运行项目时它不起作用。 在 flutter web applica
我正在使用 animatedContainer 在按下按钮时显示 listView.builder()。这是一个要显示的简单子(monad)列表,但问题是我不知道 ListView 构建器的高度会传递
我目前正在我的应用程序中制作渐变背景动画......我正在使用 lottie 动画的帮助下这样做!我试图将它封装在一个容器中并成功地做到了。但是有一个问题,尽管我将高度更改为大于 2000 的东西,但
美好的一天! 我无法弄清楚如何使用 google 标签管理器设置 flutter。我找到了 this package包括标签管理器 api。但是我不知道如何正确配置它。 (在网络上我只需要复制粘贴一个
我的购物车模型如下 class Cart { String description; double unitCost; double amount; int quantity; S
在 Flutter 应用程序中,我想为在线托管的资源(图像、视频等)实现缓存。 我希望它能在原生平台 (Android/iOS)(例如使用文件系统)和网络(例如使用 IndexedDB)上运行。 Fl
我写了一个页面,在顶部一切都很好,应该是这样。在底部我有一个事件的历史。我的容器的宽度是自动确定的(取决于屏幕的宽度),而高度 - 不,在不同的设备上有不同的高度(底部的缩进是不同的)。是否可以自动确
我正在处理一个页面,其中有一些字段,例如 textfield 和 slider。在页面的末尾必须有一个用于进行下一步的按钮,该按钮被包裹在 Align 中以在页面之间具有固定位置。 另一方面,resi
我是一名优秀的程序员,十分优秀!