안녕하세요! 오늘은 Flutter를 활용하여 간단한 로그인 화면을 구현하는 방법을 공유하려 합니다.
이 프로젝트는 Flutter를 처음 배우는 분들도 쉽게 따라할 수 있도록 구성되어 있습니다.
기본적인 UI 구성부터 네비게이션까지 한 번에 익힐 수 있었습니다.
프로젝트 소개
Flutter를 사용하여 로그인 화면과 홈 화면을 구현합니다.
- StatelessWidget과 StatefulWidget의 사용법.
- TextFormField를 활용한 입력 폼 구성.
- Navigator를 사용한 화면 전환.
- Material Design을 활용한 UI 구성.
주요 기능
- 이메일 및 비밀번호 입력 폼.
- 입력 데이터의 유효성 검사 및 저장.
- 로그인 버튼 클릭 시 홈 화면으로 전환.
프로젝트 파일 구조
1. pubspec.yaml 설정
pubspec.yaml 파일은 프로젝트의 의존성과 자원을 관리합니다.
필요한 의존성을 추가하고, assets 폴더의 로고 이미지를 등록합니다.
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.8
flutter_svg: ^2.0.17
flutter:
uses-material-design: true
assets:
- assets/logo.svg
2. 전역 상수 관리 (size.dart)
여백, 크기 등을 상수로 정의하여 프로젝트 전반에서 일관되게 사용할 수 있도록 합니다.
const double smallGap = 5.0;
const double mediumGap = 10.0;
const double largeGap = 20.0;
const double xlargeGap = 100.0;
3. 메인 진입점 (main.dart)
MaterialApp을 구성하고, 초기 화면(LoginPage)과 화면 전환(HomePage)을 설정합니다.
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
textButtonTheme: TextButtonThemeData(
style: TextButton.styleFrom(
backgroundColor: Colors.black,
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
),
minimumSize: Size(400, 60),
),
),
),
initialRoute: '/login',
routes: {
'/login': (context) => LoginPage(),
'/home': (context) => HomePage(),
},
);
}
}
4. 컴포넌트 제작
(1) 텍스트 입력 필드 (custom_form_text_field.dart)
class CustomTextFormField extends StatelessWidget {
final String label;
final FormFieldSetter<String>? onSaved;
const CustomTextFormField(this.label, this.onSaved);
@override
Widget build(BuildContext context) {
return TextFormField(
decoration: InputDecoration(
labelText: label,
border: OutlineInputBorder(),
),
validator: (value) {
if (value == null || value.isEmpty) {
return '${label}을 입력하세요';
}
return null;
},
onSaved: onSaved,
);
}
}
(2) 입력 폼 제작 (custom_form.dart)
class CustomForm extends StatelessWidget {
final _formKey = GlobalKey<FormState>();
String _email = '';
String _password = '';
@override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
children: [
CustomTextFormField('Email', (value) {
_email = value ?? '';
}),
SizedBox(height: mediumGap),
CustomTextFormField('Password', (value) {
_password = value ?? '';
}),
SizedBox(height: largeGap),
TextButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
Navigator.pushNamed(context, '/home');
}
},
child: Text('Login'),
),
],
),
);
}
}
5. 페이지 구성
(1) 로그인 페이지 (login_page.dart)
class LoginPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: ListView(
children: [
SizedBox(height: xlargeGap),
Logo('Login'),
SizedBox(height: largeGap),
CustomForm(),
],
),
),
);
}
}
(2) 홈 페이지 (home_page.dart) - 로그인 후 이동하게 될 화면
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Column(
children: [
SizedBox(height: xlargeGap),
Logo('Care Soft'),
SizedBox(height: largeGap),
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Get Started'),
),
],
),
),
);
}
}
완성 화면
이번 프로젝트를 통해 Flutter에서 로그인 화면을 구현하는 방법과 효율적인 컴포넌트 사용법을 배웠습니다.
이런 구조를 활용하면 앱 개발 속도를 높이고 유지보수성을 크게 향상시킬 수 있습니다.
다음에도 유용한 Flutter 실습 프로젝트로 찾아오겠습니다!
아래의 문헌을 참고하여 작성된 포스팅입니다.
최주호, 김근호, 이지원(공저) 『만들면서 배우는 플러터 앱 프로그래밍』, 앤써북, 2023.
'Flutter' 카테고리의 다른 글
[Flutter] Callback 함수 - 자식 위젯 이벤트 처리 (1) | 2025.01.15 |
---|---|
[Flutter] 연습하기 5 - Flutter shopping cart app (1) | 2025.01.14 |
[Flutter] 플러터 Stack 위젯 (0) | 2025.01.10 |
[Flutter] 연습하기3 - Flutter profile app (0) | 2025.01.10 |
[Flutter] 플러터의 스크롤 위젯을 알아보자 (0) | 2025.01.08 |