Flutter:通过单个父窗口小部件控制多个子窗口小部件的状态

时间:2020-07-14 11:44:25

标签: flutter dart

我有一个Menu状态微件,它是MenuIcon子微件的多个实例的父微件,该实例返回一个容器。用户可以分别点击MenuIcon小部件,以便它们在active bool为true时突出显示,而在MenuIcon bool为true时不突出显示。现在,所有操作都在Menu类中进行控制,考虑到每个图标的状态将在应用程序中扮演重要角色,因此从阅读here并不是最佳方法。我希望能够在父窗口小部件中进行管理。但是我不确定该怎么做,前面链接的教程仅包含一个父窗口小部件->一个子窗口小部件,因此从父窗口小部件管理状态非常容易。但是在这种情况下,由于父窗口小部件包含多个子窗口小部件实例,每个实例都具有各自的活动/非活动状态,所以我想不出一种简单的方法来实现此目的。

目前,我的层次结构如下所示: 我打算让MenuIcons简单地管理自己的动画,让MenuIcon类管理每个HomePage的状态,并让MenuIcon保留每个Menu的列表当前处于活动状态。

MenuIcon//----------------- Menu ------------------------------------------ //These classes control the scrollable menu that appears when the //dropdown is pressed class Menu extends StatefulWidget { final String _category; Menu(this._category); @override _MenuState createState() => _MenuState(category: this._category); } class _MenuState extends State<Menu> { List<Offer> _offersList = createOffers(); String category; _MenuState({@required this.category}); //build method Widget build(BuildContext context) { final _menuItems = List<Container>(); //builds an item widget if the category is correct. for (int i = 0; i < _offersList.length; i++) { if (this.category == _offersList[i].category) { // adds a container containing the MenuIcon object, with the offer // in question passed through _offersList[i] _menuItems.add(Container( child: MenuIcon( offer: _offersList[i], ))); } } //This particular widget tree allows to have a horizontal scrolling //menu within a fixed widget if (_menuItems.length > 0) { return SizedBox( child: Row( children: [ Expanded( child: ListView( children: _menuItems, scrollDirection: Axis.horizontal, )), ], ), height: 154, ); } else { return Row( children: [ Container( child: Text( 'Sorry! There are no offers available for this category', textAlign: TextAlign.center, style: TextStyle( fontSize: 14.0, ), ), padding: EdgeInsets.only(left: 12), ), ], ); } } } //------------------- MenuIcon class ----------------------------- class MenuIcon extends StatefulWidget { Offer offer; MenuIcon({@required this.offer}); @override _MenuIconState createState() => _MenuIconState(this.offer); } class _MenuIconState extends State<MenuIcon> { Offer _offer; bool active; _MenuIconState(this._offer) { this.active = false; } void _handleTap() { setState(() { active = !active; }); } Widget build(BuildContext context) { //print('icon rebuilt with active = $active'); var label = _offer.discount.toString(); return Container( child: GestureDetector( child: Column( children: [ _offer.image, Text( '$label% off', style: TextStyle( color: Colors.red, fontSize: 14.0, ), ), ], mainAxisAlignment: MainAxisAlignment.center, ), onTap: _handleTap, ), //changes the colour if the icon is selected or not color: active ? Colors.yellow : Colors.white, ); } } 类的代码如下:

1. Value inputted should be between 0-10
2. Only numbers should be allowed
3. As the value is added greater than 10 it changes automatically to 10 but I want to show a message below the form field that it cannot be inputted above 10 and the submit button should be disabled. So it is invalid when when larger than 10 is added. 

3 个答案:

答案 0 :(得分:2)

答案 1 :(得分:1)

另一个可行的选择是pub.dev上可用的Async_Redux软件包

它具有更少的样板代码,并允许非常简单的状态实现。您可以将ReduxAction配置为从操作中操作状态。整个应用程序会对状态操作做出反应。然后,使用ReduxSelector在每个屏幕上显示特定的更改。

进行探索:

https://pub.dev/packages/async_redux

https://pub.dev/packages/provider_for_redux

有大量文档。

https://www.fireship.io在状态管理方面也有一些有趣的内容。

答案 2 :(得分:0)

您可以使用1包来处理子树的状态(在这种情况下,以菜单为根)

这里有个例子:

ArrayTest2

如果您在单击MenuIcon时需要在子树中的任何位置执行某些操作,则可以使用BlocListener,该触发器在每次状态更改时触发