[Flutter] BuildContext의 사용

Restl2seung·2022년 5월 23일
0

BuildContext는 Widget Tree상 Widget의 위치 정보를 담고 있는 Object이다.

그럼 Widget Tree상 Widget의 위치 정보를 알아서 우리는 무엇을 할 수 있을까?

Theme

지정된 context의 Theme 정보는 가져올 수 있다.

Theme.of(context).primaryColor
Theme.of(context).textTheme.bodySmall

Dialog

Dialog 를 보여줄 때 사용.

  showDialog(
      context: context,
      builder: (_) {
        return AlertDialog(
          title: Text('Dialog test'),
        );
      },
    );

SnackBar

SnackBar를 보여줄때 사용

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

SnackBar 의 경우 Scaffold.of(context) 를 통해 Context에 접근한다.
이때 context 사용에 유의해야한다. 아래는 잘못 Scaffold.of(context) 사용했을 때와 올바르게 사용하는 방법이다.

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) { // ===A=== 해당 Context는 MyHomePage의 Context 입니다. 아래 Scaffold 의 Context를 포함하고 있지 않습니다.
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
          // 에러가 나는 플랫버튼
          // 아래 Scaffold.of(context) 뜻은 위젯 트리상 가장 가까운 Scaffold 위젯의 context를 찾아서 반환해줘 라는 뜻이다.
          // 하지만 A 부분을 보면 MyHomePage에서 떨어진 Context만을 명시해 놓았다. 
          // 즉 A 부분을 아래부터 사용된 위젯들의 Context는 각자 자신의 Conttext를 알지 못한다.
          // 그렇기에 에러가 발생한다.
             FlatButton(
                  onPressed: () {
                    Scaffold.of(context).showSnackBar(SnackBar(content: Text('에러')));
                  },
                  child: Text('에러!'),
              ),
            // 정상 작동하는 플랫버튼
            // Builder 를 통해 context를 명시하여 현재 Builder의 부모가 되는 위젯들의 Context를 인지할 수 있다.
            // Scaffold 역시 부모 위젯중 하나이기 때문에 에러가 나지 않고 정상 작동된다.
            Builder(builder: (context) {
              return FlatButton(
                  onPressed: () {
                    Scaffold.of(context)
                        .showSnackBar(SnackBar(content: Text('안녕')));
                  },
                  child: Text('눌러주세요!'));
            }),
            
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

context를 이해하는 가장 빠르 방법은 context를 어디서 어떻게 사용되는지를 직접 경험해보는게 제일 빠른것 같다.

0개의 댓글