我想将数据从小部件发送到另一个小部件,在我的示例中,我想将一些过滤器数据从FilterScreen.dart发送到ShopScreen.dart 它工作正常,但我不知道我在做什么是正确的?
在过滤器模型文件中:
class FilterData with ChangeNotifier {
bool isFreeShipping;
bool isSomeThingElse;
FilterData({this.isFreeShipping = false, this.isSomeThingElse = false});
void setFreeShippingValue(bool newval) {
isFreeShipping = newval;
notifyListeners();
}
void setSomeThingElseValue(bool newval) {
isSomeThingElse = newval;
notifyListeners();
}
}
在main.dart中:
return ChangeNotifierProvider(
create: (context) => FilterData(),
child: MaterialApp(
.........
)
);
在标签屏幕中:
class TabsScreen extends StatefulWidget {
@override
_TabsScreenState createState() => _TabsScreenState();
}
class _TabsScreenState extends State<TabsScreen> {
List<Map<String, Object>> _pages;
int _selectedPageIndex = 0;
@override
void initState() {
_pages = [
{
'page': ShopScreen(),
'title': 'shop',
},
{
'page': FilterScreen(),
'title': 'filter',
},
];
super.initState();
}
void _selectPage(int index) {
setState(() {
_selectedPageIndex = index;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(_pages[_selectedPageIndex]['title']),
),
drawer: DrawerApp(),
body: _pages[_selectedPageIndex]['page'],
bottomNavigationBar: BottomNavigationBar(
onTap: _selectPage,
backgroundColor: Theme.of(context).primaryColor,
unselectedItemColor: Colors.white,
selectedItemColor: Theme.of(context).accentColor,
currentIndex: _selectedPageIndex,
// type: BottomNavigationBarType.fixed,
items: [
BottomNavigationBarItem(
backgroundColor: Theme.of(context).primaryColor,
icon: Icon(Icons.shop),
title: Text('Shop'),
),
BottomNavigationBarItem(
backgroundColor: Theme.of(context).primaryColor,
icon: Icon(Icons.search),
title: Text('Filter'),
),
],
),
);
}
}
在FilterScreen.dart中:
class FilterScreen extends StatefulWidget {
@override
_FilterScreenState createState() => _FilterScreenState();
}
class _FilterScreenState extends State<FilterScreen> {
@override
Widget build(BuildContext context) {
final data = Provider.of<FilterData>(context);
return Container(
child: Center(
child: Expanded(
child: ListView(
children: <Widget>[
SwitchListTile(
title: Text('Free Shipping'),
value: data.isFreeShipping,
subtitle: Text('get free shipping products'),
onChanged: (newValue) {
data.setFreeShippingValue(newValue);
}),
SwitchListTile(
title: Text('Some thing else'),
value: data.isSomeThingElse,
subtitle: Text('get filtred products'),
onChanged: (newValue) {
data.setSomeThingElseValue(newValue);
}),
],
),
),
),
);
}
}
在ShopScreen.dart中:
class ShopScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
final data = Provider.of<FilterData>(context);
return Container(
child: Center(
child: Text(
data.isFreeShipping ? 'get favorite Products' : 'get all products'),
),
);
}
}
答案 0 :(得分:0)
对于大多数开发人员来说,您的问题确实很痛苦,就像我不知道它是如何工作的!
因此,如果您听不懂。这样做有两个原因:
Flutter Provider State Management works
的方式。因此,为此,请仔细阅读以下内容:
所以,现在让我们跳到代码。 您的代码如何工作?
造成这一情况的原因有很多:
1。提供商包装:如果您仔细查看main.dart
代码,就可以做到
return ChangeNotifierProvider(
create: (context) => FilterData(), // here you define the ChangeNotifier class
child: MaterialApp(
.........
)
);
现在查看上面的代码,您会发现,每当用ChangeNotifierProvider()
包装应用程序时,只要您在其中提供的类中的状态发生了变化,它就会始终重建 >,在这种情况下为FilterData()
。任何发生的更改都将反映在整个应用中,因为ChangeNotifierProvider()
的整个应用都将继续重建直子的状态,在这种情况下,您的MaterialApp()
将被包装。
2。来自ChangeNotifier类的NotifyChanges::如果您查看FilterData
,它是负责应用重建的应用,它由ChangeNotifierProvider()
包装。
让我们看看如何:
void setFreeShippingValue(bool newval) {
isFreeShipping = newval;
notifyListeners();
}
void setSomeThingElseValue(bool newval) {
isSomeThingElse = newval;
notifyListeners();
}
如果您仔细查看上面我在您的FilterData
类中的代码中提到的方法,则它们具有notifyListeners()
。这些是负责任的,每当调用这两种方法时,它都会通知ChangeNotifierListener
重建小部件,因此,每次使用这两种方法中的任何一种时,您都会看到更新的数据
3。在FilterScreen的FilterData中使用NotifyListeneres方法:因此,再次仔细观察第2点中提到的内容,我们会看到应该将method方法调用为在ChangeNotifierProvider()
SwitchListTile(
title: Text('Free Shipping'),
value: data.isFreeShipping,
subtitle: Text('get free shipping products'),
onChanged: (newValue) {
data.setFreeShippingValue(newValue);
}),
SwitchListTile(
title: Text('Some thing else'),
value: data.isSomeThingElse,
subtitle: Text('get filtred products'),
onChanged: (newValue) {
data.setSomeThingElseValue(newValue);
}),
因此,当您调用onChanged
中的任何方法时,它会立即通知Provider,该值已更改,并且应用程序将重建,并且当您切换到另一个选项卡时,您会看到更新结果如魔术。
最重要的:您的final data = Provider.of<FilterData>(context);
是Provider类的实例,它触发该方法来帮助通知ChangeNotifierProvider()
在应用中进行更改
所以映射是这样的:
Listens to the change
FilterData {setFreeShippingValue, setSomeThingElseValue} <----------------------> ChangeNotifierProvider() REBUILDS MATERIALAPP()