从子/孙子小部件刷新对话框和父项

时间:2020-02-29 15:48:58

标签: flutter

我有一个带有单选按钮的对话框,我想在用户点击它们时刷新它们,我也希望它也刷新父窗口。对于类似问题的答案建议将对话框的内容包装在StatefulBuilder中,但这不起作用,因为对话框的子级是这些dialogOption小部件。

我举了一个简单的例子:

class _MyHomePageState extends State<MyHomePage> {
  String selectedOption = "None";

  Widget dialogOption({@required String optionName}) {
    return InkWell(
      child: Row(children: [
        Icon(
          optionName == selectedOption
              ? Icons.radio_button_checked
              : Icons.radio_button_unchecked,
        ),
        Text(optionName),
      ]),
      onTap: () {
        setState(() {
          selectedOption = optionName;
        });
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          Text("Selected option: $selectedOption"),
          RaisedButton(
            child: Text("Open dialog"),
            onPressed: () {
              showDialog(
                  context: context,
                  builder: (BuildContext context) {
                    return AlertDialog(
                      content: Column(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          dialogOption(optionName: "Option 1"),
                          dialogOption(optionName: "Option 2"),
                        ],
                      ),
                    );
                  });
            },
          )
        ],
      ),
    );
  }
}

点击上面的dialogOption小部件只会刷新父级。

现在,如果我像这样用StatefulBuilder这样做:

return AlertDialog(
  content: StatefulBuilder(
    builder: (BuildContext context, StateSetter setState) {
      return Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          // tapping will NOT refresh dialog
          dialogOption(optionName: "Option 1"), 
          // tapping will NOT refresh dialog
          dialogOption(optionName: "Option 2"),
          InkWell(
            child: Text("This will refresh dialog"),
            onTap: () { // this WILL refresh dialog
              setState(() {});
            },
          ),
        ],
      );
    },
  ),
);

点击两个dialogOption小部件将不会刷新对话框,但是点击上方的Inkwell。我不知道这有什么区别,但是显然我希望这两个选项刷新对话框和父对话框。

1 个答案:

答案 0 :(得分:2)

enter image description here

class _MyHomePageState extends State<MyHomePage> {
  String selectedOption = "None";

  Widget dialogOption({@required String optionName, @required Function refresh}) {
    return InkWell(
      child: Row(
        children: [
          Icon(
            optionName == selectedOption ? Icons.radio_button_checked : Icons.radio_button_unchecked,
          ),
          Text(optionName),
        ],
      ),
      onTap: () {
        refresh(() {
          setState(() {
            selectedOption = optionName;
          });
        });
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Column(
        children: [
          Text("Selected option: $selectedOption"),
          RaisedButton(
            child: Text("Open dialog"),
            onPressed: () {
              showDialog(
                context: context,
                builder: (BuildContext context) {
                  return StatefulBuilder(
                    builder: (context, refresh) {
                      return AlertDialog(
                        content: Column(
                          mainAxisSize: MainAxisSize.min,
                          children: [
                            dialogOption(optionName: "Option 1", refresh: refresh),
                            dialogOption(optionName: "Option 2", refresh: refresh),
                          ],
                        ),
                      );
                    },
                  );
                },
              );
            },
          )
        ],
      ),
    );
  }
}