Flutter

로그인 앱 만들기

whs5758 2025. 8. 19. 16:28

 

components/custom_form.dart
import 'package:class_login/components/custom_text_form_field.dart';
import 'package:class_login/size.dart';
import 'package:flutter/material.dart';

class CustomForm extends StatelessWidget {
  // Form 태그에서 사용하는 키 값을 설정해야 한다.
  final _formKey = GlobalKey<FormState>(); // 글로벌 키

  CustomForm({super.key});

  @override
  Widget build(BuildContext context) {
    return Form(
      // key 라는 속성에 연결을 해 주어야 한다.
      // 글로벌 key를 form 태그에 연결하면 key로 form의 상태를 관리할 수 있다.
      key: _formKey,
      child: Column(
        children: [
          CustomTextFormField("Email"),
          SizedBox(height: medium_gap),
          CustomTextFormField("Password"),
          SizedBox(height: large_gap),
          TextButton(
            onPressed: () {
              if (_formKey.currentState!.validate()) {
                // 앱의 화면을 전환 시키는 방법
                // 비동기 방식으로 통신 요청 --> 응답 --> 화면 이동(잘못된 아이디...)
                Navigator.pushNamed(context, "/home");
              }
            },
            child: Text("Login"),
          ),
        ],
      ),
    );
  }
}

 

components/custom_text_form_field.dart
import 'package:class_login/size.dart';
import 'package:flutter/material.dart';

class CustomTextFormField extends StatelessWidget {
  final String text;

  const CustomTextFormField(this.text, {super.key});

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(text),
        SizedBox(height: small_gap),
        TextFormField(
          validator: (value) =>
              value!.isEmpty ? "Please enter some text" : null,
          obscureText: text == "Password" ? true : false,
          decoration: InputDecoration(
            hintText: "Enter ${text}",
            // 기본 형태의 디자인
            enabledBorder:
                OutlineInputBorder(borderRadius: BorderRadius.circular(30)),
            // 손가락 터치 시 디자인
            focusedBorder:
                OutlineInputBorder(borderRadius: BorderRadius.circular(30)),
            // 에러 발생 시 디자인
            errorBorder:
                OutlineInputBorder(borderRadius: BorderRadius.circular(30)),
            // 에러 발생 후 손가락 터치 시 디자인
            focusedErrorBorder:
                OutlineInputBorder(borderRadius: BorderRadius.circular(30)),
          ),
        )
      ],
    );
  }
}

 

components/logo.dart
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';

class Logo extends StatelessWidget {
  final String title;

  const Logo(this.title, {super.key});

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        SvgPicture.asset(
          "assets/logo.svg",
          width: 70,
          height: 70,
        ),
        Text(
          title,
          style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold),
        ),
      ],
    );
  }
}

 

pages/home_page.dart
import 'package:flutter/material.dart';

import '../components/logo.dart';

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            SizedBox(height: 200),
            Logo("Care Soft"),
            SizedBox(height: 50),
            TextButton(
              onPressed: () {
                // 화면을 스택에서 제거
                Navigator.pop(context);
              },
              child: Text("Get Started"),
            )
          ],
        ),
      ),
    );
  }
}

 

pages/login_page.dart
import 'package:class_login/components/logo.dart';
import 'package:class_login/size.dart';
import 'package:flutter/material.dart';

import '../components/custom_form.dart';

class LoginPage extends StatelessWidget {
  const LoginPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: ListView(
          children: [
            SizedBox(height: xlarge_gap),
            Logo("Login"),
            SizedBox(height: large_gap),
            CustomForm(),
          ],
        ),
      ),
    );
  }
}

 

size.dart
// 논리적인 픽셀 단위 --> dpi - di : android
//                            - pt : iOS
const double small_gap = 5.0;
const double medium_gap = 10.0;
const double large_gap = 15.0;
const double xlarge_gap = 20.0;

 

main.dart
import 'package:class_login/pages/home_page.dart';
import 'package:class_login/pages/login_page.dart';
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      // 1. 테마 -- 텍스트 버튼 테마 설정
      theme: ThemeData(
        textButtonTheme: TextButtonThemeData(
          style: TextButton.styleFrom(
            backgroundColor: Colors.black,
            foregroundColor: Colors.white,
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(30),
            ),
            minimumSize: Size(400, 60),
          ),
        ),
      ),
      initialRoute: "/login",
      routes: {
        "/login": (context) => LoginPage(),
        "/home": (context) => HomePage(),
      },
    );
  }
}

 

 

 

'Flutter' 카테고리의 다른 글

스프링 부트 Base64 활용 (스프링, 플러터)  (0) 2025.08.19
쇼핑카트 앱 만들기  (0) 2025.08.19
프로필 앱 만들기  (1) 2025.08.18
레시피 앱 만들기  (0) 2025.08.18
스토어 앱 만들기  (1) 2025.08.18