본문 바로가기
Study/Flutter

[Flutter] BuildContext와 활용법

Flutter 위젯마다 Build method에 인자로 사용되는 BuildContext는 무엇인지 어떤 역할을 하는지에 대해서 알아보자!

 

1. BuildContext란?

Flutter에서 BuildContext는 위젯 트리에서 현재 위젯의 위치와 레이아웃 정보 등을 포함하는 객체입니다.

모든 화면 위젯은 빌드시 BuildContext를 매개 변수로 받습니다.

이를 통해 현재 위젯이 속한 위젯 트리에 대한 정보를 얻을 수 있으며,

이를 사용하여 다른 위젯과 상호작용하거나 레이아웃을 변경할 수 있습니다.

또한, BuildContext는 Flutter 프레임워크에서 다양한 기능을 수행하는 데 사용됩니다.

 

예를 들어, BuildContext를 통해 Theme 또는 MediaQuery와 같은 위젯 트리에서 전역적으로 사용되는 위젯을 참조할 수 있습니다.

위젯을 생성하거나 다룰 때, BuildContext는 매우 중요한 개념이며, 모든 위젯에서 이를 사용하게 됩니다.

 

2. BuildContext 사용

BuildContext는 Flutter에서 UI를 빌드하는 데 필요한 정보를 포함하는 클래스입니다.

다음과 같은 방법으로 BuildContext를 활용할 수 있습니다.

1. Navigator

BuildContext`를 사용하여 Widget Tree에서 데이터를 전달할 수 있습니다. 
예를 들어, `Navigator`를 사용하여 새로운 화면으로 이동할 때 데이터를 전달하고자 할 때, 
`Navigator.push` 메서드에서 다음과 같이 `BuildContext`를 필수적으로 전달하여 위젯트리를 구성하는데 사용됩니다.

Navigator.push(
  context,
  MaterialPageRoute(
    builder: (context) => NewScreen(data: 'Hello World!'),
  ),
);

페이지 라우트에 전달된 BuildContext를 통해 위젯트리에 새로운 위젯을 추가하여 정보를 가지게 됩니다. 

class NewScreen extends StatelessWidget {
  final String data;

  NewScreen({required this.data});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('New Screen'),
      ),
      body: Center(
        child: Text(data),
      ),
    );
  }
}

 

 

2. Theme 데이터 가져오기

BuildContext`를 사용하여 현재 테마 데이터에 액세스할 수 있습니다. 

예를 들어, `Theme.of` 메서드를 사용하여 현재 테마의 색상, 폰트 등을 가져올 수 있습니다.

final ThemeData theme = Theme.of(context);
final Color primaryColor = theme.primaryColor;
final TextStyle textStyle = theme.textTheme.headline1!;

 

 

3. MediaQuery 가져오기

BuildContext`를 사용하여 현재 미디어 쿼리에 액세스할 수 있습니다. 

예를 들어, 디바이스의 화면 크기, 방향 등을 가져올 수 있습니다. MediaQuery는 현재 위젯 트리에서 사용 가능한 미디어 정보를 제공하는 Flutter 클래스입니다. 이 클래스는 BuildContext 객체를 매개 변수로 받아 현재 미디어 쿼리 정보를 제공합니다. MediaQuery 클래스는 size, orientation, platformBrightness 등과 같은 다양한 정보를 제공합니다.

예를 들어, MediaQuery.of(context) 메소드를 사용하여 현재 디바이스의 높이와 너비를 알 수 있습니다.

이를 사용하여 위젯의 크기를 동적으로 설정하거나, 화면 비율에 따라 레이아웃을 조정할 수 있습니다.

final MediaQueryData mediaQuery = MediaQuery.of(context);
final Size screenSize = mediaQuery.size;
final bool isPortrait = mediaQuery.orientation == Orientation.portrait;

 

 

5.  MediaQuery와 다크모드 설정

MediaQuery brightness 속성을 통해 현재 사용자가 디바이스의 밝기를 어떻게 설정했는지를 알려줍니다.

또한 MediaQueryData 클래스의 platformBrightness 속성은 플랫폼의 기본 테마 모드를 나타내며, 이를 통해 앱에서 테마를 변경할 수도 있습니다.

따라서 MediaQuery는 위젯이 현재 렌더링되고 있는 화면과 디바이스의 특성에 따라 동적으로 동작하도록 만드는 데 매우 유용합니다.

Flutter에서 platformBrightness를 사용하여 어두운 테마 모드를 감지하고 앱 전체 테마를 변경하는 코드는 다음과 같습니다:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {

    final Brightness brightnessValue = MediaQuery.of(context).platformBrightness;
    bool isDark = brightnessValue == Brightness.dark;

    return MaterialApp(
      title: 'My App',
      theme: isDark ? ThemeData.dark() : ThemeData.light(),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('My Home Page'),
      ),
      body: Center(
        child: Text('Hello World!'),
      ),
    );
  }
}

 

위 코드에서는 MediaQuery.of(context).platformBrightness를 사용하여

현재 디바이스의 기본 테마 모드가 어두운 색상 테마 모드인지 여부를 확인합니다.

그런 다음, isDark 변수를 사용하여 현재 테마 모드가 어두운 색상 테마 모드인지 확인합니다.

theme 속성에서는 isDark 변수를 사용하여 ThemeData의 dark() 또는 light() 메서드를 호출하여 전체 앱 테마를 자동으로 변경합니다.

이렇게 하면 Flutter 앱에서 플랫폼의 기본 테마 모드에 맞추어 자동으로 테마를 변경할 수 있습니다.

 

눈에 익었지만, 명확하지 않은 정의를 가지고 사용하던 클래스에 대해서 파해쳐 보았습니다.