ProgramingTip

Scaffold를 포함하지 않는 것이로 호출 된 Scaffold.of ()

bestdevel 2020. 10. 18. 18:55
반응형

Scaffold를 포함하지 않는 것이로 호출 된 Scaffold.of ()


보시다시피 내 버튼은 Scaffold가 있습니다. 하지만 예외가 발생합니다.

Scaffold.of ()는 Scaffold를 포함하지 않는 경우로 호출됩니다.

import 'package:flutter/material.dart';

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

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

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('SnackBar Playground'),
      ),
      body: Center(
        child: RaisedButton(
          color: Colors.pink,
          textColor: Colors.white,
          onPressed: _displaySnackBar(context),
          child: Text('Display SnackBar'),
        ),
      ),
    );
  }
}

_displaySnackBar(BuildContext context) {
  final snackBar = SnackBar(content: Text('Are you talkin\' to me?'));
  Scaffold.of(context).showSnackBar(snackBar);
}

편집하다 :

이 문제에 대한 또 다른 해결책을 찾았습니다. Scaffold에 GlobalKey 인 키를 주면 Builder 위젯으로 몸을 살피지 다음과 같이 SnackBar를 표시 할 수 있습니다. 하지만 Scaffold를 반환하는 위젯은 Stateful 위젯이어야합니다. :

 _scaffoldKey.currentState.showSnackBar(snackbar); 

이 예외 context는 인스턴스화 한 위젯을 사용하고 있기 때문에 발생합니다 Scaffold. context의 하위가 아닙니다 Scaffold.

다른 맥락을 사용 하여이 문제를 해결할 수 있습니다.

Scaffold(
    appBar: AppBar(
        title: Text('SnackBar Playground'),
    ),
    body: Builder(
        builder: (context) => 
            Center(
            child: RaisedButton(
            color: Colors.pink,
            textColor: Colors.white,
            onPressed: () => _displaySnackBar(context),
            child: Text('Display SnackBar'),
            ),
        ),
    ),
);

Builder여기서 사용하는 동안 다른 BuildContext.

다른 하위 트리로 추출 할 수도 있습니다 Widget(일반적으로 extract widget리팩터링 사용 ).


당신은을 사용할 수 있습니다 GlobalKey. 유일한 단점은 GlobalKey를 사용하는 것이이를 수행하는 가장 효율적인 방법이 아닐 수 있다는 것입니다.

이것에 대한 좋은 점은 스캐 폴드를 포함하지 않는 다른 사용자 정의 위젯 클래스에도이 키를 전달할 수 있다는 것입니다. 참조 ( 여기 )

class HomePage extends StatelessWidget {
  final _scaffoldKey = GlobalKey<ScaffoldState>(); \\ new line
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,                           \\ new line
      appBar: AppBar(
        title: Text('SnackBar Playground'),
      ),
      body: Center(
        child: RaisedButton(
          color: Colors.pink,
          textColor: Colors.white,
          onPressed: _displaySnackBar(context),
          child: Text('Display SnackBar'),
        ),
      ),
    );
  }
}

_displaySnackBar(BuildContext context) {
  final snackBar = SnackBar(content: Text('Are you talkin\' to me?'));
  _scaffoldKey.currentState.showSnackBar(snackBar);   \\ edited line
}

방법 문서에서 이것을 확인하십시오.

스캐 폴드가 실제로 동일한 빌드 함수에서 생성 될 때 빌드 함수에 대한 컨텍스트 인수를 사용하여 스캐 폴드를 찾을 수 없습니다 (반환되는 위젯 "위에"있기 때문에). 이러한 경우 빌더와 함께 다음 기술을 사용하여 스캐 폴드 "아래"에있는 BuildContext가있는 새 범위를 제공 할 수 있습니다.

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

메소드 문서 의 설명을 확인할 수 있습니다.


이 문제를 해결하는 간단한 방법은 다음 코드를 사용하여 마지막과 같이 스캐 폴드에 대한 키를 만드는 것입니다.

먼저: GlobalKey<ScaffoldState>() _scaffoldKey = GlobalKey<ScaffoldState> ();

Scecond : 스캐 폴드에 키 할당 key: _scaffoldKey

셋째 : 다음을 사용하여 스낵바를 호출합니다. _scaffoldKey.currentState.showSnackBar(SnackBar(content: Text("Welcome")));

참고 URL : https://stackoverflow.com/questions/51304568/scaffold-of-called-with-a-context-that-does-not-contain-a-scaffold

반응형