플러터를 접하고 매번 사용하는 위젯이지만 무엇인지 정확히는 알지못하고 "그냥 그렇게 쓴다"로만 알고 있던 개념인 Material.
근데 이 Material
이 위젯으로도 있고 디자인의 이름 앞에도 붙는다.
Material()
MaterialApp()
Material Design
그냥 플러터에서는 구글의 Material Design을 주로 사용한다는 정도로 알고 있고, 애플에서는 Cupertino Design을 따른 다는 거 정도?
💡 TMI
- Material의 사전적 의미는 물질, 재료라는 의미로, Material Design이라고 이름 지은 이유는, 디지털 환경의 인터페이스가 실제 물질의 질감과 특성을 가지도록 디자인되어야 한다는 구글의 철학에 따라 지었다.
- 반면에 Cupertino는 미국 캘리포니아 주의 도시 이름이며, 애플(Apple Inc.)의 본사가 위치한 곳이다. 즉, Cupertino Design은 본사가 위치한 도시의 이름을 따온 것이다.
🤣 구글과 애플을 잘 모르지만 왠지 작명센스가 각 회사의 이미지에 잘 어울린다.
Material Design의 "Material" 개념을 구현한 것이다. 물리적인 공간에서 볼 수 있는 종이나 잉크와 같은 물질을 모방하여, 실제 생활에서 볼 수 있는 그림자, 곡률, 빛의 반사 등의 효과를 표현한다.
InkWell
이나 Container
같은 다른 위젯들을 둘러싸는 역할을 하며, 그 위에 표시되는 위젯에 입체감을 제공하거나 터치 피드백 등을 가능하게 한다. 예를 들어, Material
위젯을 사용하면 버튼 위에 잉크 스플래시(Ink splash) 효과를 추가할 수 있다.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
에 적용되어서 테두리가 둥근 파란색 사각형 컨테이너가 생긴다.
Flutter 앱에 Material Design을 적용하려는 개발자에게 유용한 여러 기능과 설정을 제공한다. MaterialApp 위젯은 일반적으로 Flutter 앱의 최상위 레벨에 위치하며, 앱의 테마, 라우팅, 지역화 등의 기본 설정을 제공한다.
이런 속성 중, 그중 현재까지 가장 많이 봐온건 테마링 부분이다.
보통 테마링을 할 때 MaterialApp()
의 theme
파라미터에 ThemeData()
안에서 지정해주는데 아래의 예시와 같다.
MaterialApp(
theme: ThemeData(
// 앱의 기본 팔레트 색상을 red로 변경. 앱바, 플로팅 액션 버튼의 주색상 결정
primarySwatch: Colors.red,
),
💡 primarySwatch vs primaryColor
primarySwatch: 기본 팔레트 색상 설정이라서
Colors.red[400]
와 같은 단일 색상 설정 불가능. 스위치의 활성화 색상이나 프로그레스 인디케이터의 색상 등을 결정.
primaryColor: 주 색상을 설정하는 데 사용되며, 주로 앱 바(AppBar)나 플로팅 액션 버튼(Floating Action Button)의 배경색으로 사용된다. 이 속성은 단일 색상(Color) 값을 사용한다.
Scaffold
위젯의 기본 배경 색상을 설정한다.TextTheme
객체를 사용하여 제목, 본문 등 다양한 텍스트 스타일을 설정할 수 있다.ButtonThemeData
객체를 사용하여 버튼의 색상, 테두리 두께, 모양 등을 설정할 수 있습니다.IconThemeData
객체를 사용하여 아이콘의 색상, 크기, 불투명도 등을 설정할 수 있다.HOW? 👉 Theme.of(context)
를 사용해서 앱의 테마 데이터에 접근할 수 있다.
.of(context)
에 대해서는 다음에 시간이 되면 또 한 번 자세하게 다루도록 하고 링크를 남기겠다.
라우팅 또한 많이 들어본 단어이다. 아무래도 앱은 여러 화면들로 구성되어 있으니까 라우팅도 분명 중요한 개념일 것 같다.
MaterialApp
위젯의 routes
또는 onGenerateRoute
속성을 이용하여 라우팅을 설정할 수 있다. routes
는 경로 이름(문자열)을 특정 위젯 생성 함수에 매핑하는 맵(Map)이며, onGenerateRoute
는 더 복잡한 라우팅 로직을 처리하기 위한 함수이다.아래는 간단한 예시이다.
MaterialApp(
initialRoute: '/', // 앱이 시작될 때 사용할 초기 경로 이름을 설정
routes: {
'/': (context) => HomePage(), // '/' 경로로 이동하면 HomePage 위젯을 표시
'/setting': (context) => SettingScreen(), // '/setting' 경로로 이동하면 SettingScreen 위젯을 표시
},
)
또한 화면을 전환할 때는 Navigator
클래스의 pushNamed
또는 pop
메서드를 사용하여 라우트를 스택에 추가하거나 제거한다.
.pushNamed
를 사용해서 SettingScreen
으로 이동하는 예시ElevatedButton(
child: Text('Go to Setting'),
onPressed: () {
Navigator.pushNamed(context, '/setting');
},
)
.push
를 사용해서 SettingScreen
으로 이동하는 예시ElevatedButton(
child: Text('Go to Setting'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SettingScreen()),
);
},
)
💡 MaterialPageRoute, PageRouteBuilder
.push
메소드를 사용하면서context
다음에MaterialPageRoute
를 넣어주게 되면 material design 스타일의 화면 전환 효과를 가지게 된다.PageRouteBuilder
를MaterialPageRoute
자리에 넣어주면, 사용자 정의 화면 전환을 구현할 수 있게 된다.Navigator.push( context, PageRouteBuilder( // 화면에 실제로 표시될 위젯(화면 이동할 위젯) pageBuilder: (context, animation, secondaryAnimation) => SettingScreen(), // 화면 전환효과 지정 transitionsBuilder: (context, animation, secondaryAnimation, child) { // 불투명도를 애니메이션으로 조절하여 페이드 인/아웃 return FadeTransition( // 불투명도를 0애서 1사이 값으로 조절 opacity: animation, child: child, ); }, ), );
.pop
을 사용해서 이전화면으로 돌아가는 예시ElevatedButton(
child: Text('Go back'),
onPressed: () {
Navigator.pop(context);
},
)
.pushReplacement
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => SettingScreen()),
);
✨Material Design
은 디자인 철학이나 가이드라인, MaterialApp
은 그 철학을 Flutter 앱에 적용하기 위한 위젯, Material
은 실제 물질을 디지털 UI로 표현하기 위한 위젯이다.✨