繁体   English   中英

Flutter:如何从子小部件更新子(和父)小部件的 state(父小部件得到更新,子小部件没有)

[英]Flutter: How to update state of child (and parent) widget from child widget (parent widget gets update, child does not)

我为自己创建了一个小部件,它可以创建带有文本的表单开关或仅返回开关。 现在我想在我的过滤器(父级)中多次使用这个名为PlatformSwitch (子级)的小部件。

为了必须更正过滤器中的选定值,我需要将选定值( truefalse )从每个开关传递回过滤器。 我已经尝试解决这个问题,但我根本无法将谷歌的解决方案应用到我的代码中。

即使我选择了正确的值,onChange 方法也会被触发,但是再次传递给孩子的值是旧值。 怎么会这样?

我已经尝试将我的PlatformSwitch包装在ObxGetX中,但这会导致完全相同的问题。 有谁知道如何再次更新子值?

打印值:

flutter: Selected: false <-- Initialized
flutter: State update: true <-- Updated
flutter: Selected: false <-- Reinitialized with wrong value!

过滤器(父级):

class FilterModal extends StatefulWidget {
  const FilterModal({Key? key}) : super(key: key);

  @override
  State<FilterModal> createState() => _FilterModalState();
}

class _FilterModalState extends State<FilterModal> {
  bool showExpiredProducts = false;

  _FilterModalState();

  final FilterController filterController = Get.put(FilterController());

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: PlatformSwitch(
          selected: showExpiredProducts,
          onlySwitch: false,
          prefix: "Abgelaufen Angebote anzeigen",
          onChanged: (value) {
            setState(() {
              print("State update: " + value.toString());
              showExpiredProducts = value;
            });
          }),
    );
  }
}

平台开关(子):

class PlatformSwitch extends StatefulWidget {
  String? prefix;
  bool onlySwitch;
  bool selected;
  ValueChanged onChanged;

  PlatformSwitch(
      {Key? key,
      this.selected = false,
      this.onlySwitch = true,
      this.prefix,
      required this.onChanged})
      : super(key: key);

  @override
  // ignore: no_logic_in_create_state
  _PlatformSwitchState createState() => _PlatformSwitchState(
      selected,
      onlySwitch,
      prefix,
      onChanged);
}

class _PlatformSwitchState extends State<PlatformSwitch> {
  String? prefix;
  bool onlySwitch;
  bool selected;
  ValueChanged onChanged;

  _PlatformSwitchState(
      this.selected,
      this.onlySwitch,
      this.prefix,
      this.onChanged);

  @override
  Widget build(BuildContext context) {
    print("Selected: " + selected.toString());

    if (!onlySwitch) {
      return platformFormRowSwitch();
    }

    return platformSwitch();
  }

  platformFormRowSwitch() {
    return Container(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Column(
              children: [Text(prefix!)],
            ),
            Column(
              children: [platformSwitch()],
            )
          ],
        ));
  }

  platformSwitch() {
    if (defaultTargetPlatform == TargetPlatform.android) {
      return Switch(
        value: selected,
        onChanged: onChanged
      );
    }

    return CupertinoSwitch(
      value: selected,
      onChanged: onChanged,
    );
  }
}

更新!

看来我现在找到了解决方法。 我只是在 function platformSwitch的开关上使用widget.selected而不是selected 谁能告诉我为什么这是有效的?

另外,这是正确的实施方式吗? 正确的方法是什么?

platformSwitch() {
    if (defaultTargetPlatform == TargetPlatform.android) {
      return Switch(
        value: widget.selected,
        onChanged: onChanged,
        inactiveTrackColor: inactiveTrackColor,
        activeColor: activeColor,
      );
    }

    return CupertinoSwitch(
      value: widget.selected,
      activeColor: activeColor,
      trackColor: inactiveTrackColor,
      onChanged: onChanged,
    );
  }

亲切的问候和谢谢!

State StatefulWidget长。 当使用新参数重新创建小部件实例时,将保留旧的 state 实例。

要获取 state 中的更新数据,您有两种选择:

  • 使用widget.something从小部件访问数据
  • didUpdateWidget中更新状态字段

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM