2017-09-10 1 views
0

아래쪽 탭을 클릭하면 SnackBar 위젯이 표시됩니다. 나는로 보여 주려하고있다 :Flutter에서 SnackBar를 표시하는 방법

앱이 다음과 같은 예외가 발생하지만
Scaffold.of(context).showSnackBar(new SnackBar(
       content: new Text("Live Clicked"), 
      )); 

: 예외가 자체 설명이지만

I/flutter (4965): The following assertion was thrown while handling a gesture: 
I/flutter (4965): Scaffold.of() called with a context that does not contain a Scaffold. 
I/flutter (4965): No Scaffold ancestor could be found starting from the context that was passed to Scaffold.of(). This 
I/flutter (4965): usually happens when the context provided is from the same StatefulWidget as that whose build 
I/flutter (4965): function actually creates the Scaffold widget being sought. 
I/flutter (4965): There are several ways to avoid this problem. The simplest is to use a Builder to get a context that 
I/flutter (4965): is "under" the Scaffold. For an example of this, please see the documentation for Scaffold.of(): 
I/flutter (4965): https://docs.flutter.io/flutter/material/Scaffold/of.html 
I/flutter (4965): A more efficient solution is to split your build function into several widgets. This introduces a 
I/flutter (4965): new context from which you can obtain the Scaffold. In this solution, you would have an outer widget 
I/flutter (4965): that creates the Scaffold populated by instances of your new inner widgets, and then in these inner 
I/flutter (4965): widgets you would use Scaffold.of(). 
I/flutter (4965): A less elegant but more expedient solution is assign a GlobalKey to the Scaffold, then use the 
I/flutter (4965): key.currentState property to obtain the ScaffoldState rather than using the Scaffold.of() function. 
I/flutter (4965): The context used was: 
I/flutter (4965): MyHomePage(state: _MyHomePageState(603645610)) 

합니다. MyHomePage 위젯에 Scaffold이 있기 때문에 그것이 왜 발생하는지 이해할 수 없습니다.

전체 코드는 :

import 'package:flutter/material.dart'; 

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

class MyApp extends StatelessWidget { 
    // This widget is the root of your application. 
    @override 
    Widget build(BuildContext context) { 
    return new MaterialApp(
     title: 'App Name', 
     theme: new ThemeData(
     primarySwatch: Colors.blue, 
    ), 
     home: new MyHomePage(title: 'App Name'), 
    ); 
    } 
} 

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> { 
    var bottomBarLabels = [ 
    new DestinationLabel(
     icon: new Icon(Icons.live_tv), title: new Text("Live")), 
    new DestinationLabel(
     icon: new Icon(Icons.date_range), title: new Text("Matches")), 
    ]; 

    @override 
    Widget build(BuildContext context) { 
    void _handleBottomNavigationBarTap(int newValue) { 
     switch (newValue) { 
     case 0: 
      print("Live Clicked"); 
      Scaffold.of(context).showSnackBar(new SnackBar(
       content: new Text("Live Clicked"), 
      )); 
      break; 
     case 1: 
      print("Matches Clicked"); 
      break; 
     } 
    } 

    return new Scaffold(
     key: new Key("homepage"), 
     appBar: new AppBar(
     title: new Text(config.title), 
    ), 
     bottomNavigationBar: new BottomNavigationBar(
      labels: bottomBarLabels, onTap: _handleBottomNavigationBarTap), 
    ); 
    } 
} 

답변

2

당신은이 발판을 할 수 있지만, MyHomePage의하지 위의 상황 . 귀하의 스캐 폴드는 MyHomePage의 하위입니다. Scaffold.of(context)은 가장 가까운 부모 스캐 폴드에 액세스하려고 시도하고 있습니다. 그리고 아무 것도 없기 때문에 충돌합니다.

아마도 BottomNavigationBar를 새로운 클래스로 래핑해야합니다. 그리고 위젯의 컨텍스트를 사용하여 Scaffold.of(context)을 수행하십시오.

+0

코드로 답변을 업데이트 해 주실 수 있습니까? –

1

불행히도 현재 Flutter 버전을 업그레이드 할 수 없습니다. 그러나 라이브 Icon을 눌렀을 때만 SnackBar을 표시하려고합니다.

그래서 당신은, 다음 BuilderIconButton 포장 대신 IconButton로 라이브 Icon을하고 BottomNavigationBaronTap 속성을 사용하는 대신 자체의 onPressed 속성을 사용하여 다음과 같은 일을 할 수 있습니다 :

new BottomNavigationBar(
      labels: [ 
      new DestinationLabel(title: new Text("Live"), 
       icon: new Builder(builder: (BuildContext context) { 
       return new IconButton(icon: new Icon(Icons.live_tv), 
        onPressed:() { 
         Scaffold.of(context).showSnackBar(
          new SnackBar(content: new Text("Live Clicked"))); 
        }); 
       }), 
      ), 
      new DestinationLabel(icon: new Icon(Icons.date_range), 
       title: new Text("Matches"),) 


      ], 
     ) 

이것이 최선의 방법인지 확신 할 수없는 우리의 Flutter 전문가는 항상 여러 클래스에서 더 복잡한 위젯을 작성하도록 제안합니다.

+0

작동하지 않습니다. 오류가 발생합니다. '인수 유형'빌더 '를 매개 변수 유형'아이콘 '에 지정할 수 없습니다. –

1

_handleBottomNavigationBarTap 메서드를 변경하여 BuildContext 인수를 취하십시오. 다음과 같이

void _handleBottomNavigationBarTap(int newValue, BuildContext context) { 
    ... 
} 

는 그런 다음 bottomNavigationBar 인수를 변경 :

bottomNavigationBar: new Builder(
    builder: (BuildContext context) { 
    return new BottomNavigationBar(
     labels: bottomBarLabels, 
     onTap: (index) => _handleBottomNavigationBarTap(index, context), 
    ); 
    } 
), 

이 당신이 context의 조상 인 ScaffoldState을 찾을 수있을 것입니다 Scaffold.of(context)에 전화를 보장합니다.