노엘의 샴슈

[1] Flutter 간단한 예제 : 로그인 페이지 만들기 본문

Programming/APP

[1] Flutter 간단한 예제 : 로그인 페이지 만들기

알 수 없는 사용자 2023. 7. 12. 14:47

예제) 만들어볼 것 : 간단한 로그인 페이지

 

 

1. 프로젝트 파일 만들기

더보기

1) Flutter 프로젝트 만들기

  • flutter 프로젝트를 만들 폴더를 만든다 : 경로에 절대 한글이 들어가면 안됨!! 
  • VSCode 실행 
  • View > Command Palette (Ctrl + Shift + p) > flutter 입력하고 아래 뜨는 Flutter: New Project 선택
  • Application 선택
  • 폴더 경로 선택
  • 프로젝트 명 입력
    ▫️main.dart : 코딩할 파일
    ▫️pubspect.yaml : 라이브러리 및 설정할 파일

 

2) VSCode Dart 세팅

  • View > Command Palette
  • dart recommend 입력하면 아래 뜨는 Dart: Use Recommended Settings 선택

 

3) Emulator 실행

  • View > Command Palette
  • launch 입력하면 아래 뜨는 Flutter: Launch Emulator 선택
  • Pixel 2 API 29 (android) 선택

 

4) 코드 실행

  • VSCode 우측 상단에 v 버튼 누르고 Run without Debugging 선택 (속도가 더 빠름)

 

2. 기본 시작, 디버그 배너 없애주기 

더보기

이 상태에서 debugShowCheckedModeBanner: false, 를 추가해 오른쪽 상단에 보이는 배너를 없애줄 수 있다. 

 

3. Scaffold & 리펙터

더보기
  • Scaffold : 화면 디자인 구조를 만들어주는 위젯.
Scaffold(
	appBar: 다른 위젯,
	body: 다른 위젯,
	bottomNavigationBar: 다른 위젯,
	floatingActionButton: 다른 위젯,
),
  • 자동완성 단축키 : ctrl + Space 
  • 리펙터 단축키 : ctrl + Shift + R 
    : 전구 아이콘, 위젯을 다른 위젯으로 감싸거나 추출할 수 있도록 도와주는 기능

 

 

4. appBar + Text

더보기
  • appBar() : 상단바 부분에 text를 넣어보자. 
  • Text() : Text(String), style: TextStyle()로 속성을 줄 수 있다. 
Text(
     'Noelle',
     style: TextStyle(
     fontSize: 40,
     fontWeight: FontWeight.Bold,
     color: Colors.black,
     ),
),
  • AppBar() 안에 centerTitle: true로 가운데 정렬해주고 
  • title: 속성에는 Text로 내용과 스타일을 지정해줌

 

 

5. TextField & Column

더보기
  • TextField() 로 입력을 받을 수 있는 창을 만들어준다. 
    decoration 속성에 InputDecoration()을 넣고
    labelText 속성에 표시할 내용 ID를 넣어준다. 

 

  • Column() 으로 입력창 추가해주기!
    Column 위젯은 세로 방향으로 위젯을 나열할 때 쓴다. 
Column(
  children: [ // 자식 위젯들
    Text("위젯1"),
    Text("위젯2"),
  ],
),
  • 리펙터를 눌러주고 Wrap with Column을 눌러 칼럼으로 감싸주기를 선택하면 오른쪽처럼 Column이 생긴다. 
  • 이제 Column이 있으니 TextField를 복사해주고, 비밀번호 칸은 내용이 보이지 않도록 
    obscureText: true, 도 추가해준다. 

 

6. Button & Container & margin

더보기
  • Button() : 클릭 이벤트를 받는 다양한 Button들 
  • onPressed: () {} 눌렀을 때 어떤 실행을 할지 지정하는 함수인데 꼭 필수로 들어가야 한다. 
// 위로 올라와 있는 듯한 버튼
ElevatedButton(
  onPressed: () {},
  child: Text('Elevated Button'),
),

// 텍스트 버튼
TextButton(
  onPressed: () {},
  child: Text('Text Button'),
),

// 아이콘 버튼
IconButton(
  onPressed: () {},
  icon: Icon(Icons.add),
),

 

  • Container : 담는 통. Button 위젯은 width 속성이 없기 때문에 위에 하나의 부모 위젯을 만들어서 부모위젯의 width값을 통해 크기를 조절해준다. 
    ➡️ 리펙터를 이용해 Container에 담아준다. 

 

  • width 값을 폭 전체로 하고 싶으면 width: double.infinity,로 입력해주면 된다. 
  • 로그인버튼 위로 여백을 좀 주기 위해 margin을 추가했다. 
    Padding: 안쪽 여백
    Border: 경계선
    margin: 바깥쪽 여백

 

 

7. Padding

더보기
  • Padding 위젯은 안쪽 여백을 추가할 수 있다. 
  • 마찬가지로 리펙터로 Wrap with Padding을 선택해준다. 
  • padding: const EdgeInsets.all(16.0), 모든 방향으로 안쪽여백 16만큼을 추가했다. 
  • 입력창을 테두리 형식으로 바꾸고 둘 사이의 간격을 추가했다. 

 

8. Image & SingleChildScrollView

더보기
  • Image.network("URL"), 로 이미지를 추가해줄 수 있다. 
  • 지금은 스크롤이 가능하지 않기 때문에 이런식으로 에뮬레이터에서 사진이 짤린다고 알려준다. 
  • 마찬가지로 리펙터를 이용해서 Padding 위젯을 빈 위젯으로 감싸주고 그다음에 스크롤을 할 수 있도록 
    위젯 이름을 SingleChildScrollView로 바꿔준다. 
  • 사진 크기는 그대로 갈건데 입력창이랑 여백이 부족해서 Padding으로 감싸주고 여백을 아래쪽만 추가했다. 

 

완성 코드

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,
      home: Scaffold(
        appBar: AppBar(
          centerTitle: true,
          title: Text(
            'Noelle Champschu',
            style: TextStyle(
              fontSize: 25,
              fontWeight: FontWeight.bold,
              color: Colors.yellowAccent,
            ),
          ),
        ),
        body: SingleChildScrollView(
          child: Padding(
            padding: const EdgeInsets.all(16.0),
            child: Column(
              children: [
                Padding(
                  padding: const EdgeInsets.only(bottom: 20),
                  child: Image.network(
                      "https://1.gall-img.com/hygall/files/attach/images/82/900/669/046/34ec9728e96ec13455a66c42951c04cd.JPG"),
                ),
                TextField(
                  decoration: InputDecoration(
                    labelText: "ID",
                    border: const OutlineInputBorder(),
                  ),
                ),
                Container(
                  margin: EdgeInsets.only(top: 10),
                  child: TextField(
                    obscureText: true,
                    decoration: InputDecoration(
                      labelText: "Password",
                      border: const OutlineInputBorder(),
                    ),
                  ),
                ),
                Container(
                  width: double.infinity,
                  margin: EdgeInsets.only(top: 24),
                  child: ElevatedButton(
                    onPressed: () {},
                    child: Text('login'),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}