简体   繁体   English

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

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

I have created myself a widget which creates either a form switch with text or just returns the switch.我为自己创建了一个小部件,它可以创建带有文本的表单开关或仅返回开关。 Now I want to use this widget called PlatformSwitch (child) multiple times in my filter (parent).现在我想在我的过滤器(父级)中多次使用这个名为PlatformSwitch (子级)的小部件。

In order to have to correct selected values in my filter I need to pass the selected values (either true or false ) back to the filter from each switch.为了必须更正过滤器中的选定值,我需要将选定值( truefalse )从每个开关传递回过滤器。 I have already tried to solve this but I am simply not able to adapt the solutions from google to my code.我已经尝试解决这个问题,但我根本无法将谷歌的解决方案应用到我的代码中。

The onChange method gets fired even with the correct value I have selected, however the value passed to the child again is the old value.即使我选择了正确的值,onChange 方法也会被触发,但是再次传递给孩子的值是旧值。 How can this be?怎么会这样?

I already tried to wrap my PlatformSwitch in an Obx from GetX but this leads to the exact same problem.我已经尝试将我的PlatformSwitch包装在ObxGetX中,但这会导致完全相同的问题。 Does anyone know how to update the child value again?有谁知道如何再次更新子值?

Printed values:打印值:

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

Filter (parent):过滤器(父级):

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;
            });
          }),
    );
  }
}

PlatformSwitch (child):平台开关(子):

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,
    );
  }
}

UPDATE!更新!

It seems like I have found a workaround now.看来我现在找到了解决方法。 I just use widget.selected instead of just selected on my switches within the function platformSwitch .我只是在 function platformSwitch的开关上使用widget.selected而不是selected Can anybody tell me why this is working?谁能告诉我为什么这是有效的?

Also, is this a correct way of implementing?另外,这是正确的实施方式吗? Whats the correct way?正确的方法是什么?

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,
    );
  }

Kind regards and thank you!亲切的问候和谢谢!

State outlives StatefulWidget . State StatefulWidget长。 When widget instance is recreated with new parameters, old state instance is kept.当使用新参数重新创建小部件实例时,将保留旧的 state 实例。

To get updated data in state, you have two options:要获取 state 中的更新数据,您有两种选择:

  • access data from widget using widget.something使用widget.something从小部件访问数据
  • update state's fields in didUpdateWidgetdidUpdateWidget中更新状态字段

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

相关问题 如何从子更新父小部件的 state - How to update state of parent widget from child 如何从其子 Widget 更新 Parent Widget 的状态,同时在 Flutter 中更新 Child 的状态? - How to update the state of Parent Widget from its Child Widget while also updating the Child's state in Flutter? 父小部件中的 State 更新未反映在子小部件中 - State update in parent widget not reflected in child widget 如何从子小部件更新父小部件的状态并将其反映在子小部件中? - How to update state of parent widget from child widget and reflect it in child widget? 在颤动中从父小部件重置子小部件 - Reset child widget from parent widget in flutter 如何在更新父有状态小部件时更新子有状态小部件 - How to Update child stateful widget on update parent stateful widget Flutter:从子小部件设置父小部件状态 - Flutter: set parent widget state from child widget 如何从 flutter 中的父小部件访问所有孩子的 state? - How to access all of child's state from Parent Widget in flutter? 如何在子部件更改变量时更新父部件 - how to update a parent widget when a variable is changed by a child widget 如何在flutter中从父小部件调用子小部件的initState()方法 - How to Invoke initState() method of child widget from parent widget in flutter
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM