[Flutter] 블로그 만들기 - 로그인 UI 구성

2025. 2. 8. 19:47·Flutter/App
728x90

이번 글에서는 로그인 UI를 구성하고, 이를 위한 위젯들을 정리해보겠습니다.
디자인 시안을 확인한 후, 필요한 위젯을 만들고 LoginPage와 LoginBody를 구성하겠습니다.


UI에 사용될 파일

 

 

디자인 시안


1. 프로젝트에 assets 폴더 및 이미지 추가

로그인 화면에서 로고 및 기타 이미지 파일을 사용하기 위해 assets/ 폴더를 추가하고, 이미지 파일을 프로젝트에 포함해야 합니다.
Flutter에서는 pubspec.yaml 파일에서 assets 폴더 및 이미지 파일을 등록해야 이를 사용할 수 있습니다.

  # To add assets to your application, add an assets section, like this:
  assets:
    - assets/
  #   - images/a_dot_ham.jpeg

📌설명

  • - assets/ → assets 폴더 자체를 등록하여 내부 파일 사용 가능.
  • - assets/logo.svg → 로고 파일 개별 등록 (SVG 이미지 사용 가능).
  • - images/a_dot_ham.jpeg → 다른 이미지 파일 추가 예시.

👉 이렇게 설정하면 프로젝트에서 assets/ 폴더 내의 로고 및 기타 이미지 파일을 불러와 사용할 수 있습니다.
이제 assets/logo.svg를 활용하여 로그인 화면에 로고를 표시할 수 있습니다.


2. 로그인 UI를 위한 공통 위젯 만들기

로그인 화면에서는 여러 번 재사용되는 요소(예: 입력 필드, 버튼, 로고 등)가 많기 때문에 이를 위젯으로 분리하면 유지보수가 쉽습니다.
우선 로그인 UI에서 사용될 공통 위젯을 먼저 만들어보겠습니다.


 -  앱 로고 (CustomLogo)

로그인 화면의 로고 및 앱 이름을 표시하는 위젯입니다.
SVG 형식의 로고 이미지를 불러오고, 앱 이름을 텍스트 스타일링하여 보여줍니다.

 

📌 파일 위치: ui/widgets/custom_logo.dart

import 'package:class_f_story/_core/constants/size.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';

class CustomLogo extends StatelessWidget {
  final String title;

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

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        const SizedBox(height: xlargeGap),
        SvgPicture.asset(
          'assets/logo.svg', // assets 폴더에 로고 이미지 필요
          width: 70,
          height: 70,
        ),
        Text(
          title,
          style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold),
        ),
        const SizedBox(height: largeGap),
      ],
    );
  }
}

📌 설명

  • SvgPicture.asset('assets/logo.svg'): assets/ 폴더에서 로고를 불러옴.
  • Text(title): 앱 이름을 표시.
  • SizedBox(height: xlargeGap): 로고와 텍스트 사이에 적절한 간격을 추가

 -  로그인 입력 필드 (CustomAuthTextFormField)

사용자명 및 비밀번호 입력을 위한 커스텀 TextFormField 위젯입니다.
각 필드에는 라벨, 입력 필드, 테두리 스타일을 적용했습니다.

 

📌 파일 위치: ui/widgets/custom_auth_text_form_field.dart

import 'package:class_f_story/_core/constants/size.dart';
import 'package:flutter/material.dart';

class CustomAuthTextFormField extends StatelessWidget {
  final String text;
  final bool obscureText;
  final TextEditingController controller;

  const CustomAuthTextFormField({
    required this.text,
    this.obscureText = false,
    required this.controller,
    super.key,
  });

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(text),
        const SizedBox(height: smallGap),
        TextFormField(
          controller: controller,
          obscureText: obscureText,
          decoration: InputDecoration(
            hintText: 'Enter $text',
            enabledBorder: OutlineInputBorder(
              // 기본 TextFormField 설정한다.
              borderRadius: BorderRadius.circular(20.0),
            ),
            focusedBorder: OutlineInputBorder(
              // 손가락 터치시 활성화 된 디자인 설정
              borderRadius: BorderRadius.circular(20.0),
            ),
            errorBorder: OutlineInputBorder(
              // 유효설 검사 실패시 사용되는 디자인 설정
              borderRadius: BorderRadius.circular(20.0),
            ),
            focusedErrorBorder: OutlineInputBorder(
              // 에러가 발생 후 손가락을 터치 했을 때 디자인 설정
              borderRadius: BorderRadius.circular(20.0),
            ),
          ),
        ),
      ],
    );
  }
}

📌 설명

  • Text(text): 입력 필드 위에 라벨을 표시.
  • TextFormField: 실제로 입력할 수 있는 필드.
  • obscureText: 비밀번호 입력 시 true로 설정하면 입력 내용이 숨겨짐.

 -  로그인 버튼 (CustomElevatedButton)

로그인 버튼을 위한 ElevatedButton 위젯입니다.

 

📌 파일 위치: ui/widgets/custom_elevated_button.dart

import 'package:flutter/material.dart';

class CustomElevatedButton extends StatelessWidget {
  final String text;
  // final Function(String) click;
  final click;

  const CustomElevatedButton({
    required this.text,
    required this.click,
    super.key,
  });

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      style: ElevatedButton.styleFrom(
          minimumSize: Size(double.infinity, 50),
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(20.0),
          ),
          backgroundColor: Colors.white12),
      onPressed: click,
      child: Text('$text'),
    );
  }
}

📌 설명

  • onPressed: click: 버튼 클릭 시 실행할 함수를 받음.
  • backgroundColor: Colors.white12: 버튼의 기본 색상을 지정.

-  회원가입으로 이동 버튼 (CustomTextButton)

회원가입 페이지로 이동할 때 사용하는 텍스트 버튼입니다.

 

📌 파일 위치: ui/widgets/custom_text_button.dart

import 'package:flutter/material.dart';

class CustomTextButton extends StatelessWidget {
  final String text;
  // 내장 되어 있어 있는 데이터 타입
  final VoidCallback click;

  CustomTextButton({
    required this.text,
    required this.click,
    super.key,
  });

  @override
  Widget build(BuildContext context) {
    return TextButton(
      onPressed: click,
      child: Text(
        text,
        style: TextStyle(
          color: Colors.black87,
          decoration: TextDecoration.underline,
        ),
      ),
    );
  }
}

 

📌 설명

  • TextButton: 일반 버튼이 아닌 텍스트 버튼을 사용하여 회원가입 링크처럼 보이게 함.
  • decoration: TextDecoration.underline: 밑줄 효과를 추가.

 


3. 로그인 화면 구성

이제 위에서 만든 공통 위젯을 활용해 로그인 화면을 구성하겠습니다.


 -  로그인 페이지 (LoginPage)

📌 파일 위치: ui/pages/auth/login_page.dart

import 'package:class_f_story/ui/pages/auth/login_page/widgets/login_body.dart';
import 'package:flutter/material.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: LoginBody(),
    );
  }
}

📌 설명

  • Scaffold의 body에 LoginBody()를 배치.

-  로그인 화면 본문 (LoginBody)

📌 파일 위치: ui/pages/auth/login_page/widgets/login_body.dart

import 'package:class_f_story/_core/constants/size.dart';
import 'package:class_f_story/ui/widgets/custom_auth_text_form_field.dart';
import 'package:class_f_story/ui/widgets/custom_elevated_button.dart';
import 'package:class_f_story/ui/widgets/custom_logo.dart';
import 'package:class_f_story/ui/widgets/custom_text_button.dart';
import 'package:flutter/material.dart';

class LoginBody extends StatelessWidget {
  final _usernameController = TextEditingController();
  final _passwordController = TextEditingController();

  LoginBody({super.key});

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: ListView(
        children: [
          CustomLogo('f-story'),
          CustomAuthTextFormField(
            text: 'Username',
            controller: _usernameController,
          ),
          const SizedBox(height: largeGap),
          CustomAuthTextFormField(
            text: 'Password',
            controller: _passwordController,
          ),
          const SizedBox(height: largeGap),
          CustomElevatedButton(
            text: '로그인',
            click: () {
              String temp1 = _usernameController.text.trim();
              String temp2 = _passwordController.text.trim();
              // TODO - 로그인 처리
              // 뷰 모델에 있는 기능인 로그인 행위를 만들어 줄 예정
            },
          ),
          CustomTextButton(
            text: '회원가입 페이지로 이동',
            click: () {
              Navigator.pushNamed(context, '/join');
            },
          ),
        ],
      ),
    );
  }
}

-  사용자 세션 관리 (SessionUser)

로그인된 사용자의 정보를 저장할 모델을 생성합니다.

 

📌 파일 위치: data/model/session_user.dart

class SessionUser {
  int? id;
  String? username;
  String? accessToken;
  bool? isLogin;

  SessionUser({
    required this.id,
    required this.username,
    required this.accessToken,
    required this.isLogin,
  });
}

5. 마무리

✅ 정리

  • assets/ 폴더 설정 및 로고 추가
  • 공통 위젯 (CustomLogo, CustomAuthTextFormField, CustomElevatedButton, CustomTextButton) 구현
  • 로그인 화면 (LoginPage, LoginBody) 구성
  • 사용자 세션 (SessionUser) 모델 정의

다음 글에서는 Dio 클래스 선언 및 UserRepository 구현 해보겠습니다! 🚀

 

프로젝트 기본 설정이 궁금하다면??

 

[Flutter] 블로그 만들기 (기본 프로젝트 설정)

Flutter로 블로그 앱을 만들기 위한 기본 프로젝트 설정을 정리한 글입니다. 필요한 라이브러리, 테마 설정, 네비게이션 및 기본 페이지 구조까지 포함되어 있습니다.1. 프로젝트에 필요한 라이브

seohong.tistory.com

 

'Flutter > App' 카테고리의 다른 글

[Flutter] 블로그 만들기 - 로그인 기능 구현 (상태관리 및 예외처리)  (0) 2025.02.09
"[Flutter] 블로그 만들기 - 서버 통신의 모든 것 (Dio 활용)  (0) 2025.02.09
[Flutter] 블로그 만들기 - 기본 프로젝트 설정  (1) 2025.02.08
[Flutter] 상태 관리 앱 만들기 (라이브러리 사용)  (0) 2025.02.05
[Flutter]상태 관리 앱 만들기 (nheritedWidget 사용)  (0) 2025.02.03
'Flutter/App' 카테고리의 다른 글
  • [Flutter] 블로그 만들기 - 로그인 기능 구현 (상태관리 및 예외처리)
  • "[Flutter] 블로그 만들기 - 서버 통신의 모든 것 (Dio 활용)
  • [Flutter] 블로그 만들기 - 기본 프로젝트 설정
  • [Flutter] 상태 관리 앱 만들기 (라이브러리 사용)
공돌이 출신 개발자
공돌이 출신 개발자
공돌이 출신 개발자입니다
  • 공돌이 출신 개발자
    공돌이 출신 개발자
    공돌이 출신 개발자
  • 전체
    오늘
    어제
    • 분류 전체보기 (124)
      • Database (0)
        • SQL (0)
        • 1일 1쿼리 (9)
      • Flutter (40)
        • Dart 언어 (18)
        • App (22)
      • Git (0)
      • Http 기초 지식 (14)
      • HTML5 & CSS3 (0)
      • Java (33)
      • JSP (0)
      • JavaScript (0)
      • Linux (0)
      • MSA (0)
      • Project (0)
      • React (0)
      • Spring (19)
      • 설치 메뉴얼 (1)
      • [Flutter] 프로젝트 (눈길) (8)
        • 작업일지 (8)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • GitHub
  • 공지사항

  • 인기 글

  • 태그

    데이터
    android studio
    회원가입
    JAVA 기초
    공부
    SQLD
    메서드
    Java
    Android
    SQL
    코딩
    안드로이드 앱 개발
    클래스
    flutter
    블로그 만들기
    플러터
    앱 개발
    앱개발
    HTTP
    1일1쿼리
    jsp
    안드로이드
    개발
    객체지향
    로그인
    프로그래밍
    프로젝트
    객체
    dart
    spring boot
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
공돌이 출신 개발자
[Flutter] 블로그 만들기 - 로그인 UI 구성
상단으로

티스토리툴바