Material

박지훈·2023년 8월 2일
1

Widget & Package

목록 보기
2/4
post-thumbnail

Material

플러터를 접하고 매번 사용하는 위젯이지만 무엇인지 정확히는 알지못하고 "그냥 그렇게 쓴다"로만 알고 있던 개념인 Material.
근데 이 Material이 위젯으로도 있고 디자인의 이름 앞에도 붙는다.

  • Material()
  • MaterialApp()
  • Material Design

그냥 플러터에서는 구글Material Design을 주로 사용한다는 정도로 알고 있고, 애플에서는 Cupertino Design을 따른 다는 거 정도?

💡 TMI

  • Material의 사전적 의미는 물질, 재료라는 의미로, Material Design이라고 이름 지은 이유는, 디지털 환경의 인터페이스가 실제 물질의 질감과 특성을 가지도록 디자인되어야 한다는 구글의 철학에 따라 지었다.
  • 반면에 Cupertino는 미국 캘리포니아 주의 도시 이름이며, 애플(Apple Inc.)의 본사가 위치한 곳이다. 즉, Cupertino Design은 본사가 위치한 도시의 이름을 따온 것이다.

🤣 구글과 애플을 잘 모르지만 왠지 작명센스가 각 회사의 이미지에 잘 어울린다.

그래서 Material 위젯이 뭔데?

Material Design"Material" 개념을 구현한 것이다. 물리적인 공간에서 볼 수 있는 종이나 잉크와 같은 물질을 모방하여, 실제 생활에서 볼 수 있는 그림자, 곡률, 빛의 반사 등의 효과를 표현한다.

  • InkWell이나 Container 같은 다른 위젯들을 둘러싸는 역할을 하며, 그 위에 표시되는 위젯에 입체감을 제공하거나 터치 피드백 등을 가능하게 한다. 예를 들어, Material 위젯을 사용하면 버튼 위에 잉크 스플래시(Ink splash) 효과를 추가할 수 있다.

기본적으로, Material 위젯은 앱에서 시각적 요소에 깊이(depth)와 텍스처를 추가하는 데 사용된다.

  • 실제로, Material 위젯을 들여다보면, 전부 시각적 요소에 관한 파라미터들이 존재한다.

  • 간단한 예제
Material(
          // 파랑색으로 지정
          color: Colors.blue,
          // 그림자를 5만큼 지정
          elevation: 5.0,
          // 모서리를 16만큼 둥글게
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(
              16.0,
            ),
          ),
          // Material로 감싼 아래 컨테이너에 적용된다
          child: Container(
            width: 100,
            height: 100,
          ),
        ),

위 코드에서 보면 Material 위젯에서 준 속성들이 전부 child에 적용되어서 테두리가 둥근 파란색 사각형 컨테이너가 생긴다.

그럼 MaterialApp 위젯은?

Flutter 앱에 Material Design을 적용하려는 개발자에게 유용한 여러 기능과 설정을 제공한다. MaterialApp 위젯은 일반적으로 Flutter 앱의 최상위 레벨에 위치하며, 앱의 테마, 라우팅, 지역화 등의 기본 설정을 제공한다.

  1. 테마링: 앱 전체에 적용될 테마를 설정할 수 있다. 이 테마는 앱의 모든 위젯에서 접근하고 사용할 수 있으며, 색상, 타이포그래피, 버튼 스타일 등 앱의 전반적인 모양을 결정하는 데 사용된다.
  2. 라우팅: 앱 내의 페이지 이동을 관리하는 라우팅 기능을 제공한다.
  3. 지역화: 여러 언어 및 로케일을 지원하는 앱을 쉽게 만들 수 있다.
  4. 접근성: 화면 판독기, 대체 텍스트, 대비 높은 색상 등과 같은 접근성 기능을 제공합니다.

MaterialApp 위젯의 테마링

이런 속성 중, 그중 현재까지 가장 많이 봐온건 테마링 부분이다.
보통 테마링을 할 때 MaterialApp()theme 파라미터에 ThemeData() 안에서 지정해주는데 아래의 예시와 같다.

MaterialApp(
      theme: ThemeData(
        // 앱의 기본 팔레트 색상을 red로 변경. 앱바, 플로팅 액션 버튼의 주색상 결정
        primarySwatch: Colors.red,
      ),

ThemeData()의 몇가지 주요 속성

  • brightness: 앱의 전체적인 밝기 모드를 결정.
  • primarySwatch: 앱의 기본 색상 팔레트를 결정.
  • primaryColor: 앱의 기본 색상을 결정한다.

    💡 primarySwatch vs primaryColor

    primarySwatch: 기본 팔레트 색상 설정이라서 Colors.red[400]와 같은 단일 색상 설정 불가능. 스위치의 활성화 색상이나 프로그레스 인디케이터의 색상 등을 결정.
    primaryColor: 주 색상을 설정하는 데 사용되며, 주로 앱 바(AppBar)나 플로팅 액션 버튼(Floating Action Button)의 배경색으로 사용된다. 이 속성은 단일 색상(Color) 값을 사용한다.

  • accentColor: 앱의 보조 색상을 설정한다. 이 색상은 선택된 위젯, 플로팅 액션 버튼(아이콘), 슬라이더 트랙 등에 주로 사용된다.
  • canvasColor: 기본 배경 색상을 설정한다.
  • scaffoldBackgroundColor: Scaffold 위젯의 기본 배경 색상을 설정한다.
  • textTheme: 앱에서 사용되는 텍스트 스타일을 설정한다. TextTheme 객체를 사용하여 제목, 본문 등 다양한 텍스트 스타일을 설정할 수 있다.
  • buttonTheme: 앱의 모든 버튼 스타일을 설정한다. ButtonThemeData 객체를 사용하여 버튼의 색상, 테두리 두께, 모양 등을 설정할 수 있습니다.
  • iconTheme: 앱의 모든 아이콘 스타일을 설정한다. IconThemeData 객체를 사용하여 아이콘의 색상, 크기, 불투명도 등을 설정할 수 있다.

설정된 테마는 앱의 모든 페이지와 위젯에서 사용할 수 있다.

HOW? 👉 Theme.of(context)를 사용해서 앱의 테마 데이터에 접근할 수 있다.

.of(context)에 대해서는 다음에 시간이 되면 또 한 번 자세하게 다루도록 하고 링크를 남기겠다.

MaterialApp 위젯의 라우팅

라우팅 또한 많이 들어본 단어이다. 아무래도 앱은 여러 화면들로 구성되어 있으니까 라우팅도 분명 중요한 개념일 것 같다.

라우팅(Routing)

  • 앱의 여러 화면(페이지) 간의 전환을 관리하는 메커니즘을 말한다. 웹 브라우저에서 URL을 통해 페이지를 이동하는 것과 비슷하게, Flutter 앱에서도 라우팅을 통해 화면을 이동하게 된다.
  • Flutter에서는 MaterialApp 위젯의 routes 또는 onGenerateRoute 속성을 이용하여 라우팅을 설정할 수 있다. routes는 경로 이름(문자열)을 특정 위젯 생성 함수에 매핑하는 맵(Map)이며, onGenerateRoute는 더 복잡한 라우팅 로직을 처리하기 위한 함수이다.

아래는 간단한 예시이다.

MaterialApp(
  initialRoute: '/', // 앱이 시작될 때 사용할 초기 경로 이름을 설정
  routes: {
    '/': (context) => HomePage(), // '/' 경로로 이동하면 HomePage 위젯을 표시
    '/setting': (context) => SettingScreen(), // '/setting' 경로로 이동하면 SettingScreen 위젯을 표시
  },
)

또한 화면을 전환할 때는 Navigator 클래스의 pushNamed 또는 pop 메서드를 사용하여 라우트를 스택에 추가하거나 제거한다.

  1. .pushNamed를 사용해서 SettingScreen으로 이동하는 예시
ElevatedButton(
  child: Text('Go to Setting'),
  onPressed: () {
    Navigator.pushNamed(context, '/setting');
  },
)
  1. .push를 사용해서 SettingScreen으로 이동하는 예시
ElevatedButton(
  child: Text('Go to Setting'),
  onPressed: () {
    Navigator.push(
      context,
      MaterialPageRoute(builder: (context) => SettingScreen()),
    );
  },
)

💡 MaterialPageRoute, PageRouteBuilder

  • .push 메소드를 사용하면서 context 다음에 MaterialPageRoute를 넣어주게 되면 material design 스타일의 화면 전환 효과를 가지게 된다.
  • PageRouteBuilderMaterialPageRoute 자리에 넣어주면, 사용자 정의 화면 전환을 구현할 수 있게 된다.
Navigator.push(
  context,
  PageRouteBuilder(
  	// 화면에 실제로 표시될 위젯(화면 이동할 위젯)
    pageBuilder: (context, animation, secondaryAnimation) => SettingScreen(),
    // 화면 전환효과 지정
    transitionsBuilder: (context, animation, secondaryAnimation, child) {
      // 불투명도를 애니메이션으로 조절하여 페이드 인/아웃
      return FadeTransition(
      	// 불투명도를 0애서 1사이 값으로 조절
        opacity: animation,
        child: child,
      );
    },
  ),
);
  1. .pop을 사용해서 이전화면으로 돌아가는 예시
ElevatedButton(
  child: Text('Go back'),
  onPressed: () {
    Navigator.pop(context);
  },
)

페이지를 이동하는 건 기본적으로 navigation stack에 쌓아서 다음 화면을 보여주는 것이다!

  • 그래서 쌓지 않고 이동하는 방법이 필요할까봐 👉 .pushReplacement
Navigator.pushReplacement(
  context,
  MaterialPageRoute(builder: (context) => SettingScreen()),
);

요약

Material Design은 디자인 철학이나 가이드라인, MaterialApp은 그 철학을 Flutter 앱에 적용하기 위한 위젯, Material은 실제 물질을 디지털 UI로 표현하기 위한 위젯이다.✨

profile
Flutter 개발자가 되어보자!

0개의 댓글