首页 > 解决方案 > setState 没有在 Flutter 中更新 UI

问题描述

我有一个对话框,它是一个有状态的小部件,其中包含多个选项卡,包含在 Animated Switcher 中。在它里面我有一个按钮,点击它会调用一个函数,该函数switchPage()有一个 switch 语句,每种情况都将Widget? currentTab变量的状态设置为不同的状态。当我使用此switchPage()函数将 的值更改为currentTab也包装在不同方法中的不同小部件时,问题就出现了getWidget2()

DartPad 上的示例代码

按照我的建议尝试点击...

我在任何地方都找不到解决方案,我真的需要尽可能优化代码结构。请,如果有人有任何解释或任何建议,将不胜感激..

提前致谢。

标签: flutterdartflutter-state

解决方案


这是一个非常粗略的工作示例,但您可以在此基础上进行构建。在下面的代码中,您可以看到我创建了两个方法来处理为每个小部件设置复选框的状态。触发此方法后,我还重置了页面。这样做是触发内部小部件的重绘(这是我在评论中解释的)。

    class _DemoDialogState extends State<DemoDialog> {
    Widget? currentTab;

    bool valueOfCheckbox1 = false;
    bool valueOfCheckbox2 = false;

    void switchPage(name) {
    switch (name) {
      case 1:
        setState(() {
          currentTab = getWidget1(setCheckbox1State);  // <---- Notice the change here
        });
        break;

      case 2:
        setState(() {
          currentTab = getWidget2(setCheckbox2State);  // <---- Notice the change here
        });
        break;
      }
    }
  
    void setCheckbox1State(bool? newState) {
    if (newState != null) {
       setState(() {  // <---- Notice the change here
        valueOfCheckbox1 = newState;
         currentTab = getWidget1(setCheckbox1State);
      });
    }
    
   }
  
    void setCheckbox2State(bool? newState) {
      if (newState != null) {
       setState(() {  // <---- Notice the change here
        valueOfCheckbox2 = newState;
         currentTab = getWidget2(setCheckbox2State);
      });
     }
    }

  

    Widget getWidget1(Function(bool?) checkboxFunction) {
        return Container(
            child: Row(
          children: [
            Text('Hello from widget 1'),
            Checkbox(
                value: valueOfCheckbox1,
                onChanged: (value) {  // <---- Notice the change here
                  checkboxFunction(value);
                })
          ],
        ));
      }
    
      Widget getWidget2(Function(bool?) checkboxFunction) {
        return Container(
            child: Row(
          children: [
            Text('Hello from widget 2'),
            Checkbox(
                value: valueOfCheckbox2,
                onChanged: (value) {  // <---- Notice the change here
                  checkboxFunction(value);
                })
          ],
        ));
      }

      @override
       Widget build(BuildContext context) {
    return Dialog(
      child: Container(
        width: 280,
        height: 600,
        color: Colors.white,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            AnimatedSwitcher(
              duration: Duration(milliseconds: 250),
              reverseDuration: Duration(milliseconds: 250),
              transitionBuilder: (child, animation) {
                var begin = Offset(0.5, 0);
                var end = Offset.zero;
                var curve = Curves.easeIn;
                var tween = Tween(begin: begin, end: end)
                    .chain(CurveTween(curve: curve));

                var begin2 = 0.0;
                var end2 = 1.0;
                var curve2 = Curves.easeIn;
                var tween2 = Tween(begin: begin2, end: end2)
                    .chain(CurveTween(curve: curve2));

                return SlideTransition(
                  position: animation.drive(tween),
                  child: FadeTransition(
                      opacity: animation.drive(tween2), child: child),
                );
              },
              layoutBuilder: (widget, list) {
                return Align(
                  alignment: Alignment.topCenter,
                  child: widget,
                );
              },  // <---- Notice the change here
              child: currentTab == null ? getWidget1(setCheckbox1State) : currentTab,
            ),
            TextButton(
                onPressed: () {
                  switchPage(1);
                },
                child: Text('PAGE 1')),
            TextButton(
                onPressed: () {
                  switchPage(2);
                },
                child: Text('PAGE 2'))
          ],
        ),
      ),
    );
  }
}

这只是一个让事情发挥作用的例子,但它绝不代表你应该如何适当地构建事情。我会考虑将代码分成无状态和有状态的小部件。


推荐阅读