Как реализовать «эффективный способ» упаковки Scafold.of () - PullRequest
0 голосов
/ 23 мая 2018

Отображение панели закусок в качестве результата действия требует создания подконтекста для Scafold.of (), как отмечено в руководстве метода Scaffold .

Но я могу 'Вот пример этого более «эффективного метода», описанного здесь.

Более эффективное решение - разделить вашу функцию сборки на несколько виджетов.Это вводит новый контекст, из которого вы можете получить Эшафот.В этом решении у вас будет внешний виджет, который создает Scaffold, заполненный экземплярами ваших новых внутренних виджетов, а затем в этих внутренних виджетах вы будете использовать Scaffold.of.

Я хочу использовать этометод, поскольку все эти повторяющиеся отступы настолько сложны, насколько это возможно для чтения.Я уже пытался создать кнопку отправки моей формы с функциями и даже пытался расширить класс RaisedButton (поэтому Scaffold.of будет вызываться внутри нового экземпляра виджета, как указано в документации), но безрезультатно.

Это работает, только если я использую другой Builder внутри основного Scaffold моего приложения.

Это работает

class MyForm extends StatefulWidget {
  Login({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyFormState createState() => new _MyFormState();
}

class _MyFormState extends State<MyForm> {
  @override
  Widget build(BuildContext context) {
    final GlobalKey<FormState> _formKey = new GlobalKey<FormState>();
    return new Scaffold(
      body: new Builder(
        builder: (BuildContext context) {
          return new ListView(
            children: <Widget>[
              myForm(context, _formKey),
            ],
          );
        },
      ),
    );
  }
}

class SubmitButton extends RaisedButton {
  SubmitButton({
    Key key,
    this.onPressed,
    this.child,
  }) : super(key: key, onPressed: onPressed, child: child);
  final VoidCallback onPressed;
  final Widget child;

  @override
  Widget build(BuildContext context) {
    return super.build(context);
  }
}

Widget myForm(
  BuildContext context,
  GlobalKey<FormState> _formKey) => new Container(
  child: new Form(
    key: _formKey,
    child: new Column(
      children: <Widget>[
        new TextFormField(
          validator: (value) {
            if (value.isEmpty) {
              return 'Write Something';
            }
          },
        ),
        new SubmitButton(
          onPressed: () {
            if (_formKey.currentState.validate()) {
              Scaffold.of(context).showSnackBar(
                  new SnackBar(content: new Text('Processing'))
              );
            }
          },
          child: new Text('Submit'),
        ),
      ],
    ),
  ),
);

Как мне удалить Builder и упроститьЭто?Я также пытался расширить метод RaisedButton build(), но попал в беспорядок зависимости / типизации.И я не могу найти примеры этого.

Ответы [ 2 ]

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

Один простой способ split your build function into several widgets - это просто создать скаффолд в функции сборки одного виджета и кнопку в функции сборки другого виджета.(Между прочим, функция myForm в вашем коде не имеет никакого эффекта, потому что она запускается как часть той же функции сборки, поэтому значение context одинаково.) Я реорганизовал ваш код, чтобы ввести виджет MyPage, который создает скаффолд,и оставил остальное в виджете MyForm.Но теперь у нас есть два разных метода сборки: один строит скаффолд, а другой - форму и кнопку, необходимые для доступа к скаффолду.

class MyPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new MyForm(),
    );
  }
}

class MyForm extends StatefulWidget {
  @override
  _MyFormState createState() => new _MyFormState();
}

class _MyFormState extends State<MyForm> {
  final _formKey = new GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    return new ListView(
      children: <Widget>[
        new Container(
          child: new Form(
            key: _formKey,
            child: new Column(
              children: <Widget>[
                new TextFormField(
                  validator: (value) =>
                      (value.isEmpty) ? 'write something' : null,
                ),
                new RaisedButton(
                  onPressed: () {
                    if (_formKey.currentState.validate()) {
                      Scaffold.of(context).showSnackBar(new SnackBar(
                            content: new Text('Processing'),
                          ));
                    }
                  },
                  child: new Text('Submit'),
                ),
              ],
            ),
          ),
        ),
      ],
    );
  }
}
0 голосов
/ 23 мая 2018

Да, если мы вернем Скаффолд, этот контекст не может помочь получить закусочную.Используя GlobalKey, мы можем достичь этого.см. код ниже.

class ExampleWidget extends StatefulWidget {
  @override
  _ExampleWidgetState createState() => new _ExampleWidgetState();
}

class _ExampleWidgetState extends State<ExampleWidget> {
  GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState();

  _showSnackBar() {
    _scaffoldKey.currentState.showSnackBar(
    new SnackBar(
      content: new Text('You have clicked the button'),
      duration: new Duration(seconds: 4),
    ),
   );
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      key: _scaffoldKey,
      body: new Center(
        child: new RaisedButton(
          onPressed: _showSnackBar(),
          child: new Text('Click Me!'),
        ),
      ),
    );
  }
}
...