Какой контекст использовать во флаттере?В чем разница? - PullRequest
0 голосов
/ 31 мая 2018

У меня возникают проблемы с пониманием различий между Widget BuildContext и Builder BuildContext в следующих фрагментах кода:

@override
  Widget build(BuildContext context) {

и

new Builder(
  builder: (BuildContext context){

При использовании Widget BuildContext SnackBar не появляется в пользовательском интерфейсе, но в журналах отображается ошибка, которая указывает на то, что Scaffold.of() Context не имеет скаффолда при использовании Builder context все работает нормально.

Scaffold.of(context).showSnackBar(
  new SnackBar(content: new Text('Processing Data')));

Редактировать: файл main.dart:

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(title: 'APP'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
  final formKey = new GlobalKey<FormState>();
  String username;
  @override
  //This context
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(
        body: new Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisSize: MainAxisSize.max,
          mainAxisAlignment: MainAxisAlignment.start,
          children: <Widget>[
            new Flexible(
              child: new Container(
                child: new Center(
                  child: new Text(widget.title),
                ),
              ),
              flex: 1,
            ),
            new Form(
              key: formKey,
              child:
              new Row(children: <Widget>[
                new Flexible(child:
                  new Container(
                    margin: EdgeInsets.zero,
                    child: new TextFormField(
                      decoration:
                      new InputDecoration(
                        hintText: 'Username',
                        labelText: "1",
                        labelStyle: new TextStyle(color: new Color.fromARGB(255, 0, 0, 0)),
                      ),
                      validator: (val) => val.isEmpty? 'Username can\'t be empty.' : null,
                      ),
                  ),
                  flex: 1,
                ),
                new Flexible(child:
                  new Container(
                    margin: EdgeInsets.only(
                      left: 8.0,
                      right: 8.0,
                    ),
                    child: new TextFormField(
                      decoration: new InputDecoration(
                        border: InputBorder.none,
                        hintText: "Password",

                      ),
                      validator: (val) => val.isEmpty? 'Password can\'t be empty.' : null,
                      obscureText: true,
                    ),
                  ),
                  flex: 1,
                ),
                new Container(
                  child:
                  new Builder(
                    //And this context
                    builder: (BuildContext context){
                    return RaisedButton(
                      child: new Text("Sign in"),
                      onPressed: (){
                        if (formKey.currentState.validate()) {
                          // If the form is valid, display a snackbar. In the real world, you'd
                          // often want to call a server or save the information in a database
                          Scaffold.of(context).showSnackBar(
                          new SnackBar(content: new Text('Processing Data')));
                        }
                      },
                    );
                    },
                  ),
                ),
              ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

1 Ответ

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

Лучше, если вы ссылаетесь на текущий Scaffold, где вы хотите, чтобы SnackBar появлялся, используя свойство key.

final GloabalKey<ScaffoldState> _key = GlobalKey<ScaffoldState>();

Scaffold(
key:_key,
...
)

покажите снэк-бар

_key.currentState.showSnackBar(mySnackBar)

Обратите внимание, что каждый метод построителя получает context, чтобы иметь возможность ссылаться на него при использовании виджетов, которым необходим доступ к этому контексту.В вашем коде context сбивается с толку, если вы измените свой build метод context на что-то уникальное, например (Buildcontext scaffoldContext), а затем используете Scaffold.of(scaffoldContext) Я не уверен, будет ли это работать, поскольку я вижу эту путаницудовольно часто.

В любом случае, решение, приведенное выше, намного чище.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...