728x90
반응형
MaterialApp은 Flutter 애플리케이션의 루트 위젯으로, 기본 설정 및 전역 상태를 관리하는 핵심 위젯입니다. MaterialApp을 통해 앱의 테마, 라우팅, 로컬화 등 다양한 설정을 관리할 수 있는데, 이건 주로 변경되는 경우가 적기 때문에 StatelessWidget으로 많이들 씁니다.(물론 StatefulWidget으로 쓴다고 문제가 생기는 건 아님, 에디터에서 convert해주면 정상 작동함)
하지만, 그럼에도 MaterialApp을 statefulwidget으로 쓰면 좋은 경우가 있는데요.
1. 동적 설정 변경
사용자가 앱 내에서 테마(라이트 모드/다크 모드/색상 테마)를 변경할 수 있도록 하려는 경우와 + 다국어 지원 등 동적으로 설정을 변경해야하는 경우 MaterialApp을 StatefulWidget으로 만들어 상태 관리가 가능합니다.
더보기
mport 'package:flutter/material.dart';
void main() {
runApp(const AppState());
}
class AppState extends StatefulWidget {
const AppState({super.key});
@override
_AppStateState createState() => _AppStateState();
}
class _AppStateState extends State<AppState> {
int _selectedThemeIndex = 0;
final List<ThemeData> _themes = [
ThemeData.light(),
ThemeData.dark(),
ThemeData(
primarySwatch: Colors.blue,
primaryColor: Colors.blue,
colorScheme: ColorScheme.fromSwatch(primarySwatch: Colors.blue)
.copyWith(secondary: Colors.blueAccent),
),
ThemeData(
primarySwatch: Colors.green,
primaryColor: Colors.green,
colorScheme: ColorScheme.fromSwatch(primarySwatch: Colors.green)
.copyWith(secondary: Colors.greenAccent),
),
ThemeData(
primarySwatch: Colors.red,
primaryColor: Colors.red,
colorScheme: ColorScheme.fromSwatch(primarySwatch: Colors.red)
.copyWith(secondary: Colors.redAccent),
),
];
void _selectTheme(int index) {
setState(() {
_selectedThemeIndex = index;
});
}
@override
Widget build(BuildContext context) {
return MyApp(
theme: _themes[_selectedThemeIndex],
selectTheme: _selectTheme,
selectedThemeIndex: _selectedThemeIndex,
);
}
}
class MyApp extends StatelessWidget {
final ThemeData theme;
final Function(int) selectTheme;
final int selectedThemeIndex;
const MyApp({
super.key,
required this.theme,
required this.selectTheme,
required this.selectedThemeIndex,
});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: theme,
home: MyHomePage(
selectTheme: selectTheme,
selectedThemeIndex: selectedThemeIndex,
),
);
}
}
class MyHomePage extends StatelessWidget {
final Function(int) selectTheme;
final int selectedThemeIndex;
const MyHomePage({
super.key,
required this.selectTheme,
required this.selectedThemeIndex,
});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Home Page'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ToggleButtons(
isSelected:
List.generate(5, (index) => index == selectedThemeIndex),
onPressed: (index) {
selectTheme(index);
},
children: const [
Icon(Icons.wb_sunny),
Icon(Icons.nightlight_round),
Icon(Icons.circle, color: Colors.blue),
Icon(Icons.circle, color: Colors.green),
Icon(Icons.circle, color: Colors.red),
],
),
],
),
),
);
}
}
2. 동적 라우팅 및 조건부 네비게이션
사용자 상태나 앱의 특정 조건에 따라 동적으로 라우팅 및 네비게이션을 처리해야 할 때 StatefulWidget을 쓰면 유용합니다. MaterialApp에서 home 속성에 3항 연산자 쓰면 편하게 쓸 수 있겠죠?
더보기
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool _isUserLoggedIn = false;
void _login() {
setState(() {
_isUserLoggedIn = true;
});
}
void _logout() {
setState(() {
_isUserLoggedIn = false;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Dynamic Routing Example',
home: _isUserLoggedIn ? HomeScreen(logout: _logout) : LoginScreen(login: _login),
);
}
}
class LoginScreen extends StatelessWidget {
final VoidCallback login;
LoginScreen({required this.login});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Login'),
),
body: Center(
child: ElevatedButton(
onPressed: login,
child: Text('Login'),
),
),
);
}
}
class HomeScreen extends StatelessWidget {
final VoidCallback logout;
HomeScreen({required this.logout});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home'),
),
body: Center(
child: ElevatedButton(
onPressed: logout,
child: Text('Logout'),
),
),
);
}
}
이상입니다.
읽어주셔서 감사합니다.
728x90
반응형
'Flutter' 카테고리의 다른 글
[Flutter] 공공데이터 api 활용해 xml 데이터 가져오기 (0) | 2025.01.29 |
---|---|
[Flutter] Bottom Navigation Bar 작동 방식 (0) | 2025.01.29 |
[Flutter] 공공 데이터 활용해서 앱 만들기 - api key 관련 문제 (0) | 2025.01.24 |
[Flutter] Shared preferences를 사용해서 좋아요 버튼 구현하기 (0) | 2025.01.24 |
[Flutter] Firebase Firestore에서 데이터 가져오는 두 가지 방법 (0) | 2025.01.24 |