【问题标题】:Flutter SetState from custom widget (or more down the line)Flutter SetState 来自自定义小部件(或更多)
【发布时间】:2021-02-20 11:03:22
【问题描述】:

我有一个简单的颤振应用程序。它在主页中有一个stateful widget,带有一个只有一个列的简单脚手架。该列中的一个子项是一个名为buildBodyLayout() 的自定义小部件。这个小部件有自己的列,其中包含一些文本小部件,以及另一个名为 buildButton() 的自定义小部件。这个新的小部件有一个按钮,需要在 Home 视图中设置变量的状态。我在调用小部件时传递了变量的值。但是每个小部件都在自己的 dart 文件中,因为我在其他页面中重复使用相同的小部件。

如何从自定义小部件中设置主要有状态小部件? 如果我将所有内容都写在同一页面内,一切正常。如何使用不同 dart 文件中的小部件来设置父小部件的状态?

示例代码

主页状态小部件

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {

  int changeValue; 

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          
          Text("Welcome to my App"),
          Text("The Change Value is: $changeValue"),
          buildBodyLayout(changeValue),
          
        ],
      ),
    );
  }
}

buildBodyLayouot 小部件

Widget buildBodyLayout(int value){

  return Column(
    children: [
      Text("Press the + and - Buttons to change Value"),
      buildButtons(value),
    ],
  );

构建按钮小部件 小部件 buildButtons(int value){

  return Column(
    children: [
      RaisedButton(
        child: Text("Increase Value"),
          onPressed: (){
        value = value + 1;  //THIS SHOULD SET STATE
      })  ,
      RaisedButton(
          child: Text("Decrease Value"),
          onPressed: (){
            value = value - 1;  //THIS SHOULD SET STATE
          })
    ],
  );

}
}

感谢您的帮助!

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    flutter中的Widget是继承了widget(StatefulWidget, StatelessWidget)类的类。

    在您的代码中,您使用函数来构建您的小部件,不推荐这样做。

    您可以在这里看到类小部件和函数小部件之间的区别: What is the difference between functions and classes to create reusable widgets?

    除此之外,使用函数或类来解决您的问题,您需要使用callback

    class Home extends StatefulWidget {
      @override
      _HomeState createState() => _HomeState();
    }
    
    class _HomeState extends State<Home> {
    
      int changeValue = 0; 
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Column(
            children: [
              Text("Welcome to my App"),
              Text("The Change Value is: $changeValue"),
              buildBodyLayout(changeValue,
                addToValue: (int increment){
                  setState((){
                    changeValue += increment;
                  });
                }
              ),
            ],
          ),
        );
      }
    }
    
    Widget buildBodyLayout(int value, Function(int newValue) addToValue){
      return Column(
        children: [
          Text("Press the + and - Buttons to change Value"),
          buildButtons(value, addToValue),
        ],
      );
    }
    
    Widget buildButtons(int value, Function(int newValue) addToValue){
      return Column(
        children: [
          RaisedButton(
            child: Text("Increase Value"),
              onPressed: (){
                addToValue(1);
              }),
          RaisedButton(
              child: Text("Decrease Value"),
              onPressed: (){
                addToValue(-1);
              })
        ],
      );
     }
    

    您也不需要将小部件放在不同的文件中以重复使用它们,但建议您这样做。

    【讨论】:

    • oohh.. 感谢您提供的重要信息。我有一个问题......返回字符串或整数的可重用函数怎么样?那些可以用对吗?
    • @KalinduAragorn 是的,函数适用于其他目的,甚至适用于一些简单的小部件,例如返回LinearGradient,因为您不想为此制作一个新的整个小部件。对于更大的布局,最好重构为小部件。
    猜你喜欢
    • 2019-04-01
    • 2020-10-15
    • 2020-08-18
    • 1970-01-01
    • 2019-08-31
    • 2019-09-26
    • 1970-01-01
    • 2020-12-12
    • 1970-01-01
    相关资源
    最近更新 更多