管理/处理多个小部件

时间:2019-01-24 08:28:36

标签: dart flutter

我提前为我的英语致歉。

我目前正在开发移动应用程序,这是一个简单的游戏。该游戏类似于SimonSays。在我的应用程序中,有4种彩色的Container。容器会随机突出显示,玩家必须点击突出显示的容器。每个Container与一个GestureDetector相关联。此集合的理想行为是一次只能窃听一个(通过更改容器的颜色来显示窃听)。问题是我不知道如何管理容器。 我目前的方法是:

利用Notification类并通知其他容器(或父窗口小部件)该容器已被窃听。

我研究了该主题,但找不到如何利用Notification类的好例子。下面提供了当前状态的代码段:

class _parentColorWidget extends State<colorWidget> {
  bool tapped = false;
  Color _initColor;
  Color color;
  _parentColorWidget(Color color) {
    this.color = color;
    this._initColor = color;
  }

  void onTap(bool tapped) {
    setState(() {
      if (tapped) {
        color = Colors.white70;
      } else {
        color = _initColor;
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Container(
      child: _colorWidget(
        onChanged: onTap,
        context: context,
      ),
    );
  }
}

class colorWidget extends StatefulWidget {
  Color color;
  colorWidget(Color color) {
    this.color = color;
  }
  _parentColorWidget createState() => _parentColorWidget(color);
}

class _colorWidget extends StatelessWidget {

  _colorWidget({@required this.onChanged, this.color, this.context});
  final ValueChanged<bool> onChanged;
  BuildContext context;
  Color color;
  bool tapped = false;

  void _onTap() {
    CustomNotification(current_widget: this).dispatch(context);
    onChanged(!tapped);
  }

  @override
  Widget build(BuildContext context) {
    return new GestureDetector(
        onTap: _onTap,
        child: new Container(
          color: color,
        ));
  }
}

我从这段代码生成了四个小部件。通过父窗口小部件进行管理是从我在Flutter官方文档中找到的一个示例得出的。

如果点击了正确的container widget,那么如何使用通知来识别是哪个container或更准确地进行了识别?

感谢您提前提出所有答案。

1 个答案:

答案 0 :(得分:0)

如果使用Notification,则将某些标识符(例如color值)分配给父对象。如果您传递回调,则此信息可以在自身回调中进行编码,例如:

class _ParentState extends State<Parent> {
   String selectedColor;

   Widget build() {
      return Stack(children: ['Red', 'Green', 'Blue'].map((final color) =>
          Child(
            color: color,
            tapped: selectedColor == color,
            onTap: () { 
              setState(() {
                 selectedColor = color;
              })
            }
          )
      ]).toList());
   }
}

使用这种技术无法同时选择2种颜色,因为所选颜色仅在selectedColor中进行跟踪,其他所有内容均根据其值重新计算。

我建议您坚持将呼叫传递给父窗口小部件的一种方式,这样既可以通过回调也可以通过通知,而不是在单个回调中同时使用:

  void _onTap() {
    CustomNotification(current_widget: this).dispatch(context);
    onChanged(!tapped);
  }

对于您正在做的事情,我认为回调应该足以实现所有功能。

一些使代码更好的技巧:

  1. 遵循命名约定,类名应为大写

  2. 不要传递不必要的信息。在您的代码onChanged(!tapped)中,此处!tapped是不必要的,因为此值是从父级传递过来的。因此,当您在父窗口小部件中向上传递此值时,您将拥有2个信息源,以获得相同的信息安全性。避免从多个地方访问相同的信息-这只会使引入与状态相关的错误更容易。

  3. class colorWidget extends StatefulWidget {我看不到该小部件为有状态的任何原因。避免使用太多的状态小部件-最好有一个具有集中式游戏状态和逻辑的状态控制器,然后将信息传递给无状态小部件。尤其要避免使用2个或更多状态微件,它们之间必须具有同步状态。一条信息应该只有一个有状态的小部件来跟踪和控制它。