Flutter, почему новый виджет не отображается? - PullRequest
0 голосов
/ 14 февраля 2019

Код прилагается ниже.Как создать новый виджет с другим цветом фигуры, выбранным из раскрывающегося списка, нажав серую кнопку (ИЗМЕНЕНИЕ ЦВЕТА), в зависимости от того, что выбрано в раскрывающемся списке?верхнему контейнеру здесь нечего делать, только заполнитель.

Я протестировал его без виджетов 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,);
  }
}

1 Ответ

0 голосов
/ 14 февраля 2019

Вам нужно конвертировать ваши - 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,);
      }
    }
...