4

我有一个父小部件,它调用我制作的自定义 Switch 小部件。我需要父小部件中的开关值(无论是打开还是关闭)。我可以在我的开关小部件中创建一个控制器来返回该值吗?

目前,我正在从我的父小部件传递函数,它根据开关小部件中的开关值更改我的父小部件中的布尔值的值。

父小部件:

bool isSwitchOn = false;
Switch(onSwitchToggle: (bool val) {
                      isSwitchOn = val;
                  })

自定义开关小部件:

class Switch extends StatefulWidget {
 Widget build(BuildContext context) {
    return CupertinoSwitch(
        value: widget.value,
        onChanged: (bool value) {
          setState(() {
            widget.value = value;
          });
          widget.onSwitchToggle(value);
        },
),
}

每当我需要开关时,代码中的任何地方都会使用开关小部件,有时我不需要知道开关的状态,我只需要在开关切换时执行一个函数,但是我编写代码的方式,每当我调用开关时,我都需要在任何地方传递 bool 。寻找更好的方法来做到这一点。例如: Bool val 是不必要的,因为我不需要它。

Switch(onSwitchToggle: (bool val) {
                     print('abc')
                 })
4

1 回答 1

1

您可以使用 ChangeNotifier 轻松解决它。这实际上也是它在TextFieldControllerand中解决的方式ScrollController

根据您的描述,我为您提供了一些示例代码:

class SwitchController extends ChangeNotifier {
  bool isSwitchOn = false;

  void setValue(bool value) {
    isSwitchOn = value;
    notifyListeners();
  }
}

现在你包装了 Switch 的小部件:

class CustomSwitch extends StatefulWidget {
  CustomSwitch({
    required this.controller
  });

  final SwitchController controller;

  @override
  State<StatefulWidget> createState() {
    return _CustomSwitchState();
  }
}

class _CustomSwitchState extends State<CustomSwitch> {
  @override
  Widget build(BuildContext context) {
    return CupertinoSwitch(
      onChanged: (bool value) {
        widget.controller.setValue(value);
      },
      value: widget.controller.isSwitchOn,
    );
  }
}

只需监听原生 switch 的 change 事件,设置控制器的值即可。然后通知观察者。

然后您可以创建小部件并传递一个您添加侦听器的控制器:

class SwitchTest extends StatefulWidget {
  @override
  _SwitchTestState createState() => _SwitchTestState();
}

class _SwitchTestState extends State<SwitchTest> {
  SwitchController controller = SwitchController();

  @override
  void initState() {
    controller.addListener(() {
      setState(() {
        print(controller.isSwitchOn);
      });
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          children: [
            CustomSwitch(
              controller: controller
            ),
            Text(controller.isSwitchOn.toString()),
          ],
        ),
      ),
    );
  }
}

我在我的博客上写了一篇关于如何创建这样的自定义控制器的详细教程:https ://www.flutterclutter.dev/flutter/tutorials/create-a-controller-for-a-custom-widget/2021/2149/

于 2021-03-07T22:36:40.783 回答