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

问题描述 投票:0回答:1

代码见下文。如何根据下拉列表中选择的内容,按下灰色按钮(颜色变化),从下拉列表中选择具有不同颜色形状的新窗口小部件?顶部容器在这里无关,只是一个占位符。

我已经在没有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,);
  }
}
flutter dropdown setstate
1个回答
1
投票

你需要在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,);
      }
    }
© www.soinside.com 2019 - 2024. All rights reserved.