web-dev-qa-db-ja.com

FlutterでSnackBarを表示する

Flutter内のシンプルなSnackBarのステートフルウィジェットを表示したい。私のアプリケーションは、MaterialAppの新しいインスタンスをMyHomePageと呼ばれるステートフルウィジェットで作成します。

ShowSnackBar()メソッドでSnackBarを表示しようとしています。ただし、「」で失敗します。メソッド「showSnackBar」はnullで呼び出されました。

このコードの何が問題になっていますか?

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

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

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

class _MyHomePageState extends State<MyHomePage> {

  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();

  @override
  void initState() {
    super.initState();
    showInSnackBar("Some text");
  }

  @override
  Widget build(BuildContext context) {
    return new Padding(
            key: _scaffoldKey,
            padding: const EdgeInsets.all(16.0),
            child: new Text("Simple Text")
    );
  }

  void showInSnackBar(String value) {
    _scaffoldKey.currentState.showSnackBar(new SnackBar(
        content: new Text(value)
    ));
  }
}

解決策:

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

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

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

class _MyHomePageState extends State<MyHomePage> {

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

  @override
  Widget build(BuildContext context) {
    showInSnackBar("Some text");
    return new Padding(
        padding: const EdgeInsets.all(16.0),
        child: new Scaffold(
          body: new Text("Simple Text")
        )
    );
  }

  void showInSnackBar(String value) {
    Scaffold.of(context).showSnackBar(new SnackBar(
        content: new Text(value)
    ));
  }
}

3つの問題があります。 1つ目は、どこにもScaffoldがないことです。Scaffoldウィジェットは、スナックバーの表示方法を知っているウィジェットです。 2つ目は、足場をつかむための鍵を持っているが、代わりに足場に置いたということです(足場にはスナックバーの知識がありません)。 3番目は、ビルドの前にinitStateが呼び出されるため、関連付けられているウィジェットが初期化される前にキーを使用したことです。

最も簡単な解決策は、MyAppウィジェットのhome行を次のように変更することです。

home: new Scaffold(body: new MyHomePage()),

...そして__scaffoldKey_のすべての言及を削除し、代わりに現在__scaffoldKey.currentState_があるところでScaffold.of(context)を使用します。

29
Ian Hickson

私の場合、このようなコードがありました(クラス状態)

final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();

void showInSnackBar(String value) {
    _scaffoldKey.currentState.showSnackBar(new SnackBar(content: new Text(value)));
}

しかし、scaffoldのキーをセットアップしませんでした。だからkey:_scaffoldKeyを追加すると

 @override
 Widget build(BuildContext context) {
  return new Scaffold(
    key: _scaffoldKey,
    body: new SafeArea(

スナックバーが働き始める:)

17
Jack the Ripper

スナックバーをゆらゆらと表示するより優れた、よりクリーンな方法があります。私はそれが難しい方法であると分かち合ったので、おそらく他の誰かに役立つでしょう。

メインアプリ部分を変更する必要はありません

_class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
  return new MaterialApp(
    title: 'MyApp',
    theme: new ThemeData(
    primarySwatch: Colors.orange),
    home: new MainPage());
  }
}
_

ページ状態コードは状況が変わる場所です

FlutterがScaffold.of(context).showSnackBarを提供することは知っています。ただし、コンテキストはScaffoldを含むコンテキストではなく、Scaffoldの子孫のコンテキストである必要があります。エラーを回避するために、以下のように、Scaffoldの本体にBuildContextを使用し、変数に保存する必要があります。

_class MainPageState extends State<MainPage> {                                                                         
BuildContext scaffoldContext;                                                                                                                                                                                                

@override                                                                                                           
Widget build(BuildContext context) {                                                                                

return new Scaffold(                                                                                              
    backgroundColor: Colors.grey,                                                                                 
    appBar: new AppBar(                                                                                           
      title: const Text(APP_TITLE),                                                                               
    ),                                                                                                             
    body: new Builder(builder: (BuildContext context) {                                                           
      scaffoldContext = context;                                                                                  
      return new Center(
           child: new Text('Hello World', style: new TextStyle(fontSize: 32.0)),
         );                                                                                
    }));                                                                                                           
}                                                                                                                   


void createSnackBar(String message) {                                                                               
  final snackBar = new SnackBar(content: new Text(message),                                                         
  backgroundColor: Colors.red);                                                                                      

  // Find the Scaffold in the Widget tree and use it to show a SnackBar!                                            
  Scaffold.of(scaffoldContext).showSnackBar(snackBar);                                                              
  }                                                                                                                   
}     
_

これで、この関数をどこからでも呼び出すことができ、スナックバーが表示されます。たとえば、インターネット接続メッセージを表示するために使用しています。

9
Wahib Ul Haq

私がやった、私のために働く:)

@override
Widget build(BuildContext context) {
  return new Scaffold(
    appBar: new AppBar(
      title: new Text('Demo')
    ),
    body: new Builder(
      // Create an inner BuildContext so that the onPressed methods
      // can refer to the Scaffold with Scaffold.of().
      builder: (BuildContext context) {
        return new Center(
          child: new RaisedButton(
            child: new Text('SHOW A SNACKBAR'),
            onPressed: () {
              Scaffold.of(context).showSnackBar(new SnackBar(
                content: new Text('Hello!'),
              ));
            },
          ),
        );
      },
    ),
  );
}
5
Programador

initStatebuildの前に呼び出された_scaffoldKey.currentStateは、呼び出し時に初期化されていません。

ScaffoldStateからinitStateを取得できるかどうかわかりません。コードを変更する場合は、buildメソッドからスナックバーを表示できます:

Scaffold.of(context).showSnackBar(new SnackBar(new Text(value)));
3

誰かがinitState()Snackbarを初期化しようとしている場合(言い換えると、ここでページがロードされるときが私の解決策です)。また、あなたはすでに_scaffoldKey 所定の位置に。

void initState() {
  super.initState();
  Future.delayed(Duration(seconds: 1)).then(
    (_) => _displaySnackbar
  );
}

// Display Snackbar
void get _displaySnackbar {
  _scaffoldKey.currentState.showSnackBar(SnackBar(
    duration: Duration(minutes: 1),
    content: Text('Your snackbar message')
  ));
}
2
Alvin Konda

InitState()でSnackbarを初期化するには、レイアウトが構築された後に関数を実行できます。

void initState() {
super.initState();
WidgetsBinding.instance
    .addPostFrameCallback((_) => _scaffoldKey.currentState.showSnackBar(SnackBar(content: Text("Your message here..")));}
1
Syed Ahmed
Scaffold.of(context).showSnackBar(
     SnackBar(content: Text("Thanks for using snackbar",
     textAlign: TextAlign.center, style: TextStyle(fontSize: 16.0, fontWeight: 
     FontWeight.bold),), duration: Duration(seconds: 2), backgroundColor: Colors.red,)
);
1
yubaraj poudel

これを使用できます:

_final _scaffoldKey = GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      appBar: AppBar(


    ),
  }
}
_

onPressed()にこのコードを追加できます

__scaffoldKey.currentState.showSnackBar(
       new SnackBar(
          content: new Text('Hello this is snackbar!')
       )
);
_
0
Rizki Syaputra