Flutter: обновить состояние виджета - PullRequest
0 голосов
/ 27 мая 2018

Как вы обновляете состояние виджета-брата во Flutter?

Например, если у меня есть виджет прямоугольника, я могу изменить его цвет из виджета, вызвав setState() и изменив цветпеременная (как кнопка «Turn Green» делает ниже).Но, скажем, я хотел кнопку вне прямоугольника, которая бы изменила его цвет.Как мне сообщить Rectangle, что пришло время изменить его цвет, и какой цвет изменить?

Вот мой пример кода.Когда пользователь нажимает кнопку «Синяя», я бы хотел, чтобы прямоугольник стал синим, но у меня нет доступа к его состоянию из виджета «Брат».

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Hello Rectangle',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Hello Rectangle'),
        ),
        body: Column(
          children: <Widget>[
            HelloRectangle(),
            FlatButton(
            child: Text('Turn Blue!',
              style: TextStyle(fontSize: 40.0),
              textAlign: TextAlign.center,
            ),
            onPressed: () {
              // How to update state of the Rectangle from here?
            },
          ),
          ]
        ),
      ),
    ),
  );
}

class HelloRectangle extends StatefulWidget {
  @override
  HelloRectangleState createState() {
    return new HelloRectangleState();
  }
}

class HelloRectangleState extends State<HelloRectangle> {
  Color _color;

  @override
    void initState() {
      super.initState();
      _color = Colors.red;
    }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        color: _color,
        height: 400.0,
        width: 300.0,
        child: Center(
          child: FlatButton(
            child: Text('Turn Green!',
              style: TextStyle(fontSize: 40.0),
              textAlign: TextAlign.center,
            ),
            onPressed: () {
              // I can update the state from here because I'm inside the widget
              setState(() {
               _color = Colors.green;
              });
             },
          ),
        ),
      ),
    );
  }
}

Ответы [ 2 ]

0 голосов
/ 27 мая 2018

Практическое правило заключается в том, что вы не можете получить доступ к состоянию любого виджета, который не находится над вами в иерархии.Итак, в основном нам нужно переместить состояние (цвет) до предка.Представьте StatefulWidget, который создает Scaffold или Column и сохраняет там цвет прямоугольника.Теперь виджету прямоугольника больше не нужно хранить цвет, поэтому он может стать виджетом без состояния - и вы можете передать цвет через конструктор.Оба обратных вызова onPressed теперь могут вызывать метод нового StatefulWidget, который вызывает setState.(Вы можете передать этот метод в виджет прямоугольника, среди других способов.)

Есть два хороших введения в лучшие практики здесь и здесь .

0 голосов
/ 27 мая 2018

Вот базовый пример, как это сделать снаружи.

import 'package:flutter/material.dart';

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

class MyApp extends StatefulWidget {
  const MyApp({
    Key key,
  }) : super(key: key);

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

class MyAppState extends State<MyApp> {
  MaterialColor _color = Colors.green;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Hello Rectangle',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Hello Rectangle'),
        ),
        body: Column(children: <Widget>[
          HelloRectangle(_color),
          FlatButton(
            child: Text(
              _color == Colors.green ? "Turn Blue" : "Turn Green",
              style: TextStyle(fontSize: 40.0),
              textAlign: TextAlign.center,
            ),
            onPressed: () {
              setState(() {
                _color = _color == Colors.green ? Colors.blue : Colors.green;
              });
            },
          ),
        ]),
      ),
    );
  }
}

class HelloRectangle extends StatefulWidget {
  final Color color;

  HelloRectangle(this.color);

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

class HelloRectangleState extends State<HelloRectangle> {
  HelloRectangleState();

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        color: widget.color,
        height: 400.0,
        width: 300.0,
      ),
    );
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...