有没有一种方法可以将一行按钮导出为小部件?

时间:2020-03-01 11:07:46

标签: flutter dart widget refactoring

我在两页上都有该行,我想提取为小部件以避免重复,但是我的IDE不允许我这样做,而是显示消息气泡:

无法提取对封闭类方法的引用

下面是我的行,我尝试将其包含在Container中,但结果相同。

  child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: <Widget>[
                  TagButton(
                    isActive: _selectedTag == 'cart',
                    tagIcon: Icons.local_grocery_store,
                    onTap: () {
                      setState(() {
                        _selectedTag = 'cart';
                      });
                    },
                  ),
                  TagButton(
                    isActive: _selectedTag == 'school',
                    tagIcon: Icons.school,
                    onTap: () {
                      setState(() {
                        selectedTag = 'school';
                      });
                    },
                  ),
                  TagButton(
                    isActive: _selectedTag == 'all',
                    tagIcon: Icons.block,
                    onTap: () {
                      setState(() {
                        _selectedTag = 'all';
                      });
                    },
                  ),
                  TagButton(
                    isActive: _selectedTag == 'relax',
                    tagIcon: Icons.spa,
                    onTap: () {
                      setState(() {
                        _selectedTag = 'relax';
                      });
                    },
                  ),
                  TagButton(
                    isActive: _selectedTag == 'recipes',
                    tagIcon: Icons.restaurant,
                    onTap: () {
                      setState(() {
                        _selectedTag = 'recipes';
                      });
                    },
                  ),
                ],
              ),

我尝试将其提取为一种方法,但是一旦将其移动到另一个dart文件中(以便可以导入到两个页面并在其中使用它),就会出现很多警告

lib/widgets/tagsBar.dart:17:13: Error: Method not found: 'setState'.
  setState(() {
  ^^^^^^^^
lib/widgets/tagsBar.dart:23:21: Error: Getter not found: 'selectedTag'.
  isActive: selectedTag == 'school',
  ^^^^^^^^^^^

1 个答案:

答案 0 :(得分:0)

一种更好的方法是将其实现为单独的类widget

import 'package:flutter/material.dart';

class SharedWidgetRow extends StatefulWidget {
  final stateRebuild;

  SharedWidgetRow({@required this.stateRebuild});
  @override
  _SharedWidgetRowState createState() => _SharedWidgetRowState();
}

class _SharedWidgetRowState extends State<SharedWidgetRow> {
  var  _selectedTag = 'cart';
  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: <Widget>[
        TagButton(
          isActive: _selectedTag == 'cart',
          tagIcon: Icons.local_grocery_store,
          onTap: () {
            _selectedTag = 'cart';
            widget.stateRebuild();
          },
        ),
        TagButton(
          isActive: _selectedTag == 'school',
          tagIcon: Icons.school,
          onTap: () {
            selectedTag = 'school';
            widget.stateRebuild();
          },
        ),
        TagButton(
          isActive: _selectedTag == 'all',
          tagIcon: Icons.block,
          onTap: () {
            _selectedTag = 'all';
            widget.stateRebuild();
          },
        ),
        TagButton(
          isActive: _selectedTag == 'relax',
          tagIcon: Icons.spa,
          onTap: () {
            _selectedTag = 'relax';
            widget.stateRebuild();
          },
        ),
        TagButton(
          isActive: _selectedTag == 'recipes',
          tagIcon: Icons.restaurant,
          onTap: () {
            _selectedTag = 'recipes';
            widget.stateRebuild();
          },
        ),
      ],
    );
  }
}

并且setState()必须在相同的上下文中,因此在调用此小部件时应将其作为参数传递

SharedWidgetRow(stateRebuild: setState((){})),

如果要在其他地方使用此变量,则应考虑将此变量_selectedTag设置为全局变量