从子有状态小部件访问数据

时间:2021-05-01 15:26:49

标签: flutter

简而言之:我有一个有状态小部件,其中包含另一个带有变量的有状态小部件,我想从父级访问该变量,但我找不到不使用提供程序的方法(我想避免保留布局和数据分开)。有没有办法做到这一点?

总而言之:我正在尝试创建一个工具,让一个人可以输入几个学校成绩并获得它们的平均值。要输入等级,我使用按钮,并为用户提供一行可能的等级(从 A* 到 U),用户可以单击加号图标按钮添加另一行。整个小部件是一个有状态小部件,因此可以动态添加和删除行,每一行也是一个有状态小部件,只能选择一个等级并突出显示颜色。整个事情看起来像这样: enter image description here

到目前为止,系统运行良好,只是我现在想计算所选成绩的平均成绩。为此,我需要访问每一行中的选定成绩,但我想不出一个好的方法。我知道这可以通过使用提供程序来完成,但我宁愿避免这种情况,因为平均成绩纯粹是视觉上的,我希望尽可能将设计和数据部分分开。

我的容器小部件代码:

class GradeSection extends StatefulWidget {
  @override
  _GradeSectionState createState() => _GradeSectionState();
}

class _GradeSectionState extends State<GradeSection> {
  int numGrades = 3;

  Widget avgGrade() {
    return ClipRRect(
      borderRadius: BorderRadius.circular(10),
      child: Container(
        padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
        color: Colors.grey,
        child: Center(child: Text('average grade here')),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [
          for (var i in List.generate(numGrades, (index) => index))
            ButtonBox(i),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              avgGrade(),
              IconButton(
                  icon: Icon(Icons.add),
                  onPressed: () => setState(() => numGrades++)),
              numGrades > 0
                  ? IconButton(
                      icon: Icon(Icons.remove),
                      onPressed: () => setState(() => numGrades--))
                  : Container(),
            ],
          )
        ],
      ),
    );
  }
}

每一行的代码:

class ButtonBox extends StatefulWidget {
  final int index;
  ButtonBox(this.index);

  @override
  _ButtonBoxState createState() => _ButtonBoxState();
}

class _ButtonBoxState extends State<ButtonBox> {
  String selectedButton = 'B';

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(5),
        color: Colors.grey,
      ),
      margin: EdgeInsets.symmetric(vertical: 10),
      padding: EdgeInsets.symmetric(vertical: 5),
      child: Row(
        children: ['A*', 'A', 'B', 'C', 'D', 'E', 'U']
            .map(
              (e) => Expanded(
                child: Container(
                  padding: EdgeInsets.symmetric(horizontal: 10),
                  child: ElevatedButton(
                    style: ButtonStyle(
                        backgroundColor: selectedButton != e
                            ? MaterialStateProperty.all(Colors.grey)
                            : MaterialStateProperty.all(Colors.blue)),
                    onPressed: () => setState(() => selectedButton = e),
                    child: Text(e),
                  ),
                ),
              ),
            )
            .toList(),
      ),
    );
  }
}

编辑:我确实通过不创建子有状态小部件来实现该功能,而是在父小部件中使用了一个以索引为键、以等级为值的映射。但是知道原始问题的解决方案在未来会非常有用。

1 个答案:

答案 0 :(得分:0)

您的问题基本上是状态管理之一。如果您不想使用任何外部包 InheritedWidget 允许您传递状态。但是,通过使用 BloCriverpod 等外部库进行状态管理,您可能会更满意。