DevBoi

[Flutter] 간단한 로그인 화면 구현 본문

[Mobile]/[Flutter]

[Flutter] 간단한 로그인 화면 구현

HiSmith 2023. 1. 8. 20:55
반응형

간단한 프로젝트를 진행해보자

아무리 이론을 빠삭하게 해도 결국은 직접 해보지않으면 ... 금방 까먹는다 ㅎㅎ

주말은 앱공부를 하고, 평일에는 인프라 자바 스프링 공부를 하니까...

일단 해보자

 

main.dart의 파일 내용이다.

 

MyApp이라는 class의 내용을 적어놓고, MaterialApp을 return 한다.

title은 dice game으로 두고, Login()을 홈으로 지정하여, return 한다.

 

해당 하단의 Login 클래스이다.

해당 클래스는 Scaffold를 return하고 Login이라는 텍스트를 타이틀로 한다.

그 Login appbar와 IconButton그리고 해당 하위의 action에 대한 함수 선언까지만 해놓는다.

 

 

StateLesswight부분에서 노란 색 전구 버튼을 누르면

자동으로 StateFulwidget으로 convert해주는 기능이 있다.

이 기능을 누르면 소스가 자동으로 해당 내용으로 컨버팅 된다는 장점이 있다.

컨버팅 된 Login 클래스이다.

 

 

추가로 Scaffold에 body를 추가시켜준다. 

해당 추가된 body에서는 컬럼을 children으로 두고, 해당 이미지를 둔다

속성은 Center로 두고서 진행한다.

여기서 Asset 이미지를 추가하는데 이때 Asset 이미지를 추가하려면 pubspec.yaml에 아래와 같이 추가해줘야 이미지를 인식한다.

 

 

이렇게 되면 아래와 같이 빌드된 모습을 볼수 있다.

좀 커서, 높이랑 길이를 추가로 속성으로 주었다.

 

이제 로그인화면에서 남은 것이 있다.

바로, 아이디랑 비밀번호를 입력하는 곳이다. 흔히 말해서 폼을 추가해야한다.

일단 다시 사진을 바꾸고, 이 폼을 추가해보자

 

 

일단 만든 화면이다.

 

그리고 해당 총 소스를 한번 살펴보자

전체 정리겸 

Myapp 안에는 Login 을 home으로 부른다.

로그인 안에는 Scaffold를 리턴하고

그 하위에는 AppBar를 등록

title 에는 Login,

Icon Button 2개 (메뉴, Search 버튼 을 둔다. 눌렀을떄는 반응이없다.)

이부분에 해당 된다.

 

추가로 Body에는 아래의 내용이 있다.

Column으로 Widget들을 자식으로 둔다.

또한 해당 자식 리스트는 아래와 같다.

센터라는 곳에 Image를 둔다.

 

또한 센터 하위에는 Form으로 데이터를 넣을수있는 곳을 둔다.

Form을 살펴보자

Form하위에는 주요컬러, input 테마, input 테마의 텍스트 스타일, 컬러등을 지정한다.

또한 해당 Form의 하위에는 또하나의 컨테이너를 둔다.

 

길어보이지만 별거 없다.

TextField를 두개 두고, 그 안에서 label을 붙이고, keyboardType을 둔다.

또한 하위 버튼 테마로 다음으로 눌렀을때 뭔가 액션을 할 버튼

총 컨테이너에는 3개의 위젯이 담기게 된다.

 

근데 하나의 의문은 이런 위젯들을 사용하고 선언할때 직관적이고 좋긴하지만

하나씩 찾아가면서 아님 외워서 해야하나?

답은 아니다.

나는 어떤걸 써야 할지만 알게된다면

에를 들어서, ButtonTheme를 써야지~ 하고 기억은 당연히 할테고 그러면

 

https://api.flutter.dev/flutter/widgets/SizedBox-class.html

 

SizedBox class - widgets library - Dart API

A box with a specified size. If given a child, this widget forces it to have a specific width and/or height. These values will be ignored if this widget's parent does not permit them. For example, this happens if the parent is the screen (forces the child

api.flutter.dev

 

그냥 여기에서 하나씩 보면서 손에 익을때까지 찾아보면된다.

더 좋고 정리 잘되어있는 곳을 보면...정리해놔야겠다 ㅋ

 

 

무튼 이렇게 간단하게 화면 구현은 마치도록하자

 

 

<전체 소스이다.>

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {

    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: "dice game",
      home: Login(),
    );
  }
}

class Login extends StatefulWidget{
  @override
  State<Login> createState() => _LoginState();
}

class _LoginState extends State<Login> {
  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        title: Text("Login"),
        backgroundColor: Colors.redAccent,
        centerTitle: true,
        leading: IconButton(
          icon: Icon(Icons.menu),
          onPressed: (){},
        ),
      actions:<Widget> [
        IconButton(
          icon: Icon(Icons.search),
          onPressed: (){},
        )
      ],
      ),
      body:
      SingleChildScrollView(
        child: Column(
          children:  <Widget>[
            Center(child: Image(
               image: AssetImage('image/sunny.jpg'),width: 150,height: 150,
            ),
            ),
            Form(child: Theme(data: ThemeData(
              primaryColor: Colors.teal,
              inputDecorationTheme: InputDecorationTheme(
                labelStyle: TextStyle(
                  color: Colors.teal,
                  fontSize: 15.0
                )
              )
            ), child: Container(
              padding: EdgeInsets.all(40.0),
               child: Column(
                 children: <Widget>[
                   TextField(
                     decoration: InputDecoration(
                       labelText: 'enter id'
                     ),
                     keyboardType: TextInputType.emailAddress,
                   ),
                   TextField(
                     decoration: InputDecoration(
                         labelText: 'enter password'
                     ),
                     keyboardType: TextInputType.text,
                     obscureText: true,
                   ),
                   SizedBox(height: 40.0, ),
                   ButtonTheme(
                     minWidth: 100.0,
                     height: 50.0,
                       child: MaterialButton(
                        color: Colors.orangeAccent,
                         child:
                         Icon(
                           Icons.arrow_forward,
                           color: Colors.black,
                           size: 35.0,
                         ),
                         onPressed: null,
                       )
                   )
                 ],
               ),
            )))
          ],
        ),
      ),
    );
  }
}


반응형