Flutter,为什么新的小部件没有出现?

Flutter, Why is the new widget not showing up?

下面附上代码。 我如何创建一个具有不同颜色形状的新小部件, 从下拉菜单中选择,按下灰色按钮(颜色更改), 基于下拉列表中选择的内容? top Container在这里没有任何作用,只是一个占位符。

我已经在不使用 Widgets MySquare、MyRound 和 MyRectangle 的情况下对其进行了测试,仅根据下拉选择更改颜色并且它有效。但是使用其他小部件 类 MySquare、MyRound 和 MyRectangle 似乎不会重绘新的小部件。

void main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: MyTrial(strShape: 'ROUND'));
  }
}

class MyTrial extends StatefulWidget{
  final String strShape;

  MyTrial({this.strShape});

  @override
  MyTrialState createState() {
    return new MyTrialState();
  }
}

class MyTrialState extends State<MyTrial> {
  List<String> listShapes;
  String strShapeSelected;

  Widget widgetType;

  @override
  void initState() {
    super.initState();
    listShapes = ['SQUARE', 'ROUND','RECTANGLE'];
    strShapeSelected = widget.strShape;

    widgetType = _myGetShape('ROUND');
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(title: Text('Change\nColor'),
        actions: <Widget>[
          /// button to change color
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 10.0),
            child: GestureDetector(onTap: () {
              _myChangeShapeColor(strShapeSelected);
              setState(() {});
              //print('Gesture $strShapeSelected');
            },
              child: new Container(
                child: new Center(
                    child: new Padding(
                      padding: const EdgeInsets.all(5.0),
                      child: new Text('COLOR\nCHANGE',textAlign: TextAlign.center,),
                    )),
                decoration: new BoxDecoration(
                    color: Colors.blueGrey, shape: BoxShape.circle),
              ),
            ),
          ),
          /// drop down list
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 10.0),
            child: DropdownButton<String>(
                items: listShapes.map((String value) {
                  return new DropdownMenuItem(
                    child: new Text('$value'),
                    value: value,
                  );
                }).toList(),
                value: strShapeSelected,
                onChanged: (String newValue) {
                  setState(() {
                    strShapeSelected = newValue;
                  });
                  widgetType = _myGetShape(strShapeSelected);
                }),
          )
        ],),
      body: Column(
        children: <Widget>[
          /// place holder
          Padding(
            padding: const EdgeInsets.all(10.0),
            child: Container(
              height: 80.0, color: Colors.teal,),
          ),
          /// shape widget
          /// changed by drop-down
          Center(child: widgetType),
        ],
      ),
    );
  }

  Widget _myGetShape(String newValue) {
    Widget newShape;
    switch(newValue){
      case 'SQUARE':
        newShape = MySquare(myColor: Colors.brown,);
        break;
      case 'ROUND':
        newShape = MyRound(myColor: Colors.green,);
        break;
      case 'RECTANGLE':
        newShape = MyRectangle(myColor: Colors.blue,);
        break;
    }
    return newShape;
  }

  void _myChangeShapeColor(String strNewShape) {
    switch(strNewShape){
      case 'SQUARE':
        widgetType = MySquare(myColor: Colors.amber,);
        break;
      case 'ROUND':
        widgetType = MyRound(myColor: Colors.lightGreenAccent,);
        break;
      case 'RECTANGLE':
        widgetType = MyRectangle(myColor: Colors.purple,);
        break;
    }
    setState(() {});
  }
}

/// SQUARE
class MySquare extends StatefulWidget{
  final Color myColor;

  MySquare({this.myColor});

  @override
  MySquareState createState() {
    return new MySquareState();
  }
}

class MySquareState extends State<MySquare> {
  Color newColor;

  @override
  void initState() {
    newColor = widget.myColor;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Container(child: Center(
        child: Text('SQUARE',style: TextStyle(fontSize: 15.0))),
      color: newColor,
      width: 120.0,height: 120.0,);
  }
}

/// ROUND
class MyRound extends StatefulWidget{
  final Color myColor;

  MyRound({this.myColor});

  @override
  MyRoundState createState() {
    return new MyRoundState();
  }
}

class MyRoundState extends State<MyRound> {
  Color newColor;

  @override
  void initState() {
    newColor = widget.myColor;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Container(child: Center(
        child: Text('ROUND',style: TextStyle(fontSize: 15.0))),
      decoration: BoxDecoration(color: newColor,
          shape: BoxShape.circle),
      width: 120.0,height: 120.0,);
  }
}

/// RECTANGLE
class MyRectangle extends StatefulWidget{
  final Color myColor;

  MyRectangle({this.myColor});

  @override
  MyRectangleState createState() {
    return new MyRectangleState();
  }
}

class MyRectangleState extends State<MyRectangle> {
  Color newColor;

  @override
  void initState() {
    newColor = widget.myColor;
    super.initState();
  }
  @override
  Widget build(BuildContext context) {
    return Container(child: Center(
        child: Text('RECTANGLE',style: TextStyle(fontSize: 15.0))),
      color: newColor,
      width: 200.0,height: 120.0,);
  }
}

您需要将您的 - MySquare,MyRound & MyRectangle 类 转换为 StatelessWidget。其余代码保持不变,它将按预期工作。

现在您将其设置为 StatefulWidget - 因此它们在初始化后保持状态。因此不改变颜色。

   /// SQUARE
    class MySquare extends StatelessWidget {
      final Color myColor;
      MySquare({this.myColor});

      @override
      Widget build(BuildContext context) {
        return Container(
          child: Center(child: Text('SQUARE', style: TextStyle(fontSize: 15.0))),
          color: myColor,
          width: 120.0,
          height: 120.0,
        );
      }
    }

矩形和圆形相同。

更新:

如果您想将其保留为 StatefulWidget。然后你需要使用 - didUpdateWidget 方法。

 class MySquareState extends State<MySquare> {
      Color newColor;

      @override
      void initState() {
        newColor = widget.myColor;
        super.initState();
      }

      @override
      void didUpdateWidget(MySquare oldWidget) {
        super.didUpdateWidget(oldWidget);
        print('Called');
        newColor = widget.myColor;
      }

      @override
      Widget build(BuildContext context) {
        return Container(child: Center(
            child: Text('SQUARE',style: TextStyle(fontSize: 15.0))),
          color: newColor,
          width: 120.0,height: 120.0,);
      }
    }