본문 바로가기
mobile/flutter

[flutter] Scaffold.of() called with a context that does not contain a Scaffold. 해결방법과 Copy to clipboard on tap

by moonsiri 2021. 2. 6.
728x90
반응형

Text를 탭하면 해당 Text를 클립보드에 복사하면서 스낵바를 출력하려고 합니다.

 

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class CopyScreen extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return CopyStateScreen();
  }
}


class CopyStateScreen extends State<CopyScreen> {
  String code = '007';
  
  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () {
        return Future(() => false);
      },
      child: Scaffold(
        body: ListView(
          children: [
            Container(
              child: InkWell(
                child: Text('코드 : $code'),
                onTap: () {
                  Clipboard.setData(new ClipboardData(text: '$code'));
                  Scaffold.of(context).showSnackBar((SnackBar(content:Text('복사됨')));
                }
              )
            ),
          ],
        )
      ),
    );
  }
}

 

 

그런데 실행해보니 아래와 같은 오류가 발생하였습니다.

Scaffold.of() called with a context that does not contain a Scaffold.

 

Scaffold.of(context)를 이용하면 해당 context의 Scaffold에 접근하여 스낵바를 출력할 수 있는데, 위 소스에서는 ScaffoldSacffold를 참조하는 형태이기 때문에 에러가 발생하는 것 같습니다.

그래서 Scaffold를 참조하는 Key를 이용해서 스낵바를 출력하는 방식으로 변경하였습니다.

 

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class CopyScreen extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return CopyStateScreen();
  }
}

class CopyStateScreen extends State<CopyScreen> {
  final scaffoldKey = GlobalKey<ScaffoldState>();	// Scaffold에 주입할 key 발급
  String code = '007';

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () {
        return Future(() => false);
      },
      child: Scaffold(
        key: scaffoldKey,	// Scaffold에 key 주입
        body: ListView(
          children: [
            Container(
              child: InkWell(
                child: Text('코드 : $code'),
                onTap: () {
                  Clipboard.setData(new ClipboardData(text: '$code'));
                  scaffoldKey.currentState.hideCurrentSnackBar();   // 연속 tap 방지
                  scaffoldKey.currentState.showSnackBar(SnackBar(content:Text('복사됨')));
                }
              )
            ),
          ],
        )
      ),
    );
  }
}

 

GlobalKey<ScaffoldState>()를 통해 Sacffold에 주입할 key를 발급하여 Scaffold의 key 속성에 주입하고sscaffoldKey.currentState를 이용하여 스낵바를 출력합니다.

연속으로 Tap 할 경우 스낵바가 딜레이 되는 것을 방지하기 위해 스낵바를 출력하기 전에 hideCurrentSnackBar를 사용하여 스낵바를 닫아줍니다.

728x90
반응형

댓글