본문 바로가기

Flutter/App Making Learn

간단한 로그인 화면 만들기

간단한 로그인 화면


가장 윗줄 부터 천천히 하나씩 제가 이해한대로 풀어보겠습니다.

틀린게 많을 예정입니다..

import 'package:flutter/material.dart';

flutter/material.dart 패키지를 변환하여 현재 시트에 적용시키겠다는 뜻.


void main() {

  runApp(MyApp());
}

코드의 메인바디. runApp이란 함수에 MyApp을 실행하겠다 선언합니다.


class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

객체지향 사용. class란 객체에 MyApp이란 이름 부여. StatelessWidget의 주요 역할은 간단한 UI의 일부 렌더링 및 상시 표시, 내부상태 불변성 보장,(오류 줄여줌) 상태가 없기 때문에 재 렌더링 될 필요가 없어 앱 성능향상 및 메모리 사용량을 줄여주는데 사용합니다.

const를 사용하여 MyApp이란 객체를 변수에서 상수로 변형하여 값을 변동할수 없다고 지정해줍니다.


@override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,

@override로 하위클래스에서 변경을함. 빌드라는 함수파라미터 안에 위젯트리에서의 위치를 알수 있게 해주는 함수를 넣음. 매터리얼앱으로 반환을 해주며.

debugShowCheckedModeBanner: false 는 단순히 시뮬레이터를 가동할때에 디버그 모드 표기입니다.

false 일때
true 일때


theme: ThemeData(
        useMaterial3: false),
Material Theme

는 현재 flutter 3.16 이상 버전부터 기본 테마가 Material3로 변경되어서 상단 바 디자인이 흰색 배경이 됐음.
그것을 Material2 테마로 변경해주는 코드.


home: Scaffold(
        appBar: AppBar(
          title: Text(
            "Donations",
            style: TextStyle(fontSize: 28),
          ),
          centerTitle: true,
        ),
전체적인 App구성, Top Bar

home란 함수에 Scaffold란 함수를 선언하고 이 Scaffold는 전반적인 앱의 구조를 쉽게 만들수 있게 도와줍니다.

건설 현장에서 볼수 있는 스캐폴드 출처 : https://civilstring.com/types-of-scaffolding-and-parts-of-scaffolding/

상단바인 AppBar를 선언해주고 그 안에 글을 넣을수 있는 title: text를 사용하여 "Donations"라는 이름을 직접 입력하였고,

style: TextStyle(fontSize: 28)은 말 그대로 "Donations"의 폰트 크기를 지칭합니다.

📍centerTitle: true 가 개인적으로 굉장히 중요하다 느낀점이 IOS시뮬레이터를 가동했을때는 문제 없이 문자열이 가운데 정렬이 되지만, android 시뮬레이터를 가동하였을때는 자동적으로 왼쪽으로 문자열이 정렬되기 때문에 IOS,android 둘다 일치시켜 앱을 정리하려면 꼭 적어줘야하는 함수입니다.


body: SingleChildScrollView(
          child: Padding(
            padding: const EdgeInsets.all(30.0),
            child: Column(
본격적으로 사용자가 보고, 사용하는 것들

본격적인 body의 시작. SingleChildScrollView는 단순히 보면 스크롤을 할 수 있게 해주는 기능입니다. 이미지가 크던 어떠한 상황이건 TextField에 입력하려 했을때 아래에서 키보드가 올라와 보이지 않을때 반드시 필요한 코드이며, 바디에 선언한 이유는 AppBar(상단바)는 전혀 움직일 필요가 없기 때문입니다.

child: Padding : const EdgeInsets.all 은 body 자체에 보이지 않는 여백을 주는것이다. 정말 우리가 입는 패딩을 생각하면 된다. const를 주어 변하지 않는 값으로 사방 전체에 30의 값만 여백을 준다는 뜻이다. 현재 아래의 Email과 PassWord란이 이 패딩에 종속되어 있습니다.

여기서 EdgeInsets.all 은 only로 변경하여 파라미터 안에 top, bottom, left, right 를 넣어 개별적으로 변경이 가능합니다.

📍child : Column 은 위젯들을 가로방향 즉 아래방향으로 나열하겠다는 뜻입니다. 자주 쓰일것 같아 기억해두는 중.


children: [
                Padding(
                  padding: const EdgeInsets.all(30.0),
                  child: Image.network(
                    "https://i.ibb.co/CwzHq4z/trans-logo-512.png",
                    width: 81,
                  ),
                ),
Image file

padding : 외곽 여백의 정도는 30이며, 이것은 아래 png파일의 값입니다.

child: Image.network("https://~.png", width: 81) 은 저 고양이 사진을 사이트에서 불러온 것이며 크기는 81만큼 조절해두어 적절한 크기를 맞춰 넣었습니다.


TextField(
                  decoration: InputDecoration(labelText: "E-Mail"),
                ),
                TextField(
                  obscureText: true,
                  decoration: InputDecoration(labelText: "PassWord"),
                ),
TextBox

decoraion 함수는 TextBox를 변경,디자인 할수 있는 함수이며 그림자, 기울기, 텍스트, 색 등을 넣을수 있다.

📍중요한건 아래의 obscureText: true 이것은 일반적으로 PassWord를 입력할때 실제 Text가 아닌 ****식으로 가려주는 코드임으로 기억해두면 좋을것 같다.


Container(
                  width: double.infinity,
                  margin: const EdgeInsets.only(top: 10.0, bottom: 10),
                  child: ElevatedButton(
                    onPressed: () {},
                    child: Text("Login"),
                  ),
                ),
                Container(
                  width: double.infinity,
                  child: ElevatedButton(
                    onPressed: () {},
                    child: Text("Sign Up"),
                  ),
                ),
Login, Sign Up button

기본적으로 ElevatedButton으로 만들어졌으며 자체 width값이 없기 때문에 부모의 크기를 조절해주어야 합니다.

📍width: 200 처럼 값을 지정해줄순 있지만, 각기 다른 폭을 가지고 있는 디바이스의 폭을 내가 스스로 정했다간 통일성도 없고 불편을 야기할수 있기 때문에 width: double.infinity를 해주어 바디 패딩범위 까지 늘릴수 있다. 이렇게 되면 디바이스를 로테이션 하였을때도 문제가 없는것 같았습니다.

margin의 같은 경우에는 Container의 바깥영역에 여백을 줄때 사용됩니다.


import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        useMaterial3: false,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text(
            "Donations",
            style: TextStyle(fontSize: 28),
          ),
          centerTitle: true,
        ),
        body: SingleChildScrollView(
          child: Padding(
            padding: const EdgeInsets.all(30.0),
            child: Column(
              children: [
                Padding(
                  padding: const EdgeInsets.all(30.0),
                  child: Image.network(
                    "https://i.ibb.co/CwzHq4z/trans-logo-512.png",
                    width: 81,
                  ),
                ),
                TextField(
                  decoration: InputDecoration(labelText: "E-Mail"),
                ),
                TextField(
                  obscureText: true,
                  decoration: InputDecoration(labelText: "PassWord"),
                ),
                Container(
                  width: double.infinity,
                  margin: const EdgeInsets.only(top: 10.0, bottom: 10),
                  child: ElevatedButton(
                    onPressed: () {},
                    child: Text("Login"),
                  ),
                ),
                Container(
                  width: double.infinity,
                  child: ElevatedButton(
                    onPressed: () {},
                    child: Text("Sign Up"),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}