Programming-[CrossPlatform]/Flutter

Flutter 기본-8. 로그인 페이지 만들어보기: TextField, TextEditingController, SingleChildScrollView

컴퓨터 탐험가 찰리 2023. 1. 20. 19:27
728x90
반응형

Youtube 코딩셰프님의 강의를 요약 정리한 글이다. dart 언어나 이론 부분은 자바와 유사하여 대부분 제외하였고, flutter 기초 위주로 정리한다.

https://www.youtube.com/@codingchef

 

코딩셰프

향후 대세가 될 플러터를 단계별로 맛있게 학습하실 수 있습니다!

www.youtube.com

 


 

이번 강의에서는 배웠던 이론적인 부분들을 바탕으로 간단한 로그인, 주사위 놀이 페이지를 만들어본다. 코드를 보고 따라해보면서 각종 위젯이나 코드 작성 방식에 대해 좀 더 익숙해지라는 의도인 것 같다.

 

프로젝트 기본 툴은 코딩셰프 깃허브 페이지에서 다운로드 받으면 된다.

https://github.com/icodingchef/login_dice-master

 

GitHub - icodingchef/login_dice-master: Final version

Final version. Contribute to icodingchef/login_dice-master development by creating an account on GitHub.

github.com

 

 

1. 로그인 페이지

아래 코드는 로그인 페이지의 기본 구성이다. 앞서 배운 것처럼 State<LogIn> 타입의 위젯을 구성하고 createState() 메서드로 상태가 변함에 따라 rebuild가 일어날 수 있도록 구성하였다.

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
  _LogInState createState() => _LogInState();
}

class _LogInState extends State<LogIn> {

 

* Build failed due to use of deprecated Android v1 embedding.

혹시 flutter v1이라 정상적인 작동이 안된다고 하면 아래 링크 글을 참조하면 된다. 요약하자면 .android 폴더를 지우고 터미널에서 flutter create . 명령어를 쳐주면 된다는 것이다. 나는 이외에도 프로젝트의 이름에 하이픈이 있어서(login_dice-master) 하이픈을 언더바로 바꿔주고 명령어를 실행했다.

 

https://stackoverflow.com/questions/71492645/flutter-build-failed-due-to-use-of-deprecated-android-v1-embedding

 

 

앞서 배운 내용대로 Scaffold의 body 부분에 Column/Center/Image로 이어지는 구성을 해주면 된다. 이후 자세한 스타일 설정은 그냥 배운대로 하면 된다. 이제부터는 새로 배운 내용이나 위젯들에 대해서만 간략히 정리한다.

 

 

Form과 Theme

Form

사용자의 로그인 정보를 받기 위해서 Form 위젯을 사용한다. 이것은 웹 개발에서와 마찬가지로 특정 데이터들을 제출하기 위한 양식용 위젯이라고 생각하면 된다.

 

Theme

Theme은 애플리케이션의 전체적인 색깔이나 디자인 등을 통일성 있게 관리하기 위한 위젯이다. data 속성값은 아래 사진에서 보듯이 Theme 안에서 데이터가 입력되는 양식을 결정한다. color, typography(문자 형식)을 지정하는 것이다. 그리고 child 속성에 실제 들어갈 데이터를 입력해준다.

 

inputDecorationTheme

그 중에서도 inputDecorationTheme 위젯은 사용자의 input을 받는 부분을 관리하는 위젯이다. labelStyle 값으로 입력창 위쪽에 안내문처럼 표시되는 label의 속성값을 지정해주었다.

 

Container/Column/TextField, keyboardType, obscureText

Theme 위젯 안에 inputbox를 넣기 위해서 Container 위젯을 사용했다. 기본 4편에서 배운대로 Container 위젯은 화면상 남은 공간에서 최대한의 크기를 차지하려 한다. 이 부분에서 마지막에 TextField내 keyboardType을 설정했는데, 이것은 email 값등으로 사용자가 입력하는 값들의 형식을 설정해줄 수 있다. 만약 email로 설정한다면 입력 시 올라오는 키보드에 @문자가 포함되는 등 키보드 입력 상의 편의를 제공한다.

 

비밀번호는 입력 시 보이지 않게하기 위해서 obscureText 속성값을 줄 수 있다.

 

 

 

 

SingleChildScrollView

 

SingleChildScrollView

form으로 작성된 TextField에 값을 입력할려고 하면, 키보드가 팝업되면서 비밀번호 창을 가리며 Bottom overflowed 에러가 뜬다. 그리고 일반적인 핸드폰 사용 시처럼 위 입력화면을 스크롤할려고해도 스크롤이 안된다. 스크롤 기능을 적용하려면 기존 위젯을 스크롤이 가능한 위젯으로 Wrapping 해줘야한다.

 

기존 body 부분을 SingleChildScrollView로 감싼 후 테스트 해보면, 스크롤이 가능하기 때문에 ID 입력 부분을 누르면 애초에 키보드가 팝업되면서 비밀번호 창이 보이도록 스크롤이 적용되며, body 쪽에서도 스크롤이 가능한 것을 확인할 수 있다.

 

 

 

 

ButtonTheme, onPressed activation

 

하단에 button을 추가한다. ElevatedButton 및 arrow_forward Icon을 추가하면 된다. Form 처럼 앱 전체적으로 테마를 맞추기 위해서 ButtonTheme 위젯을 사용한다. 

 

 

 

Icon에 Colors.orangeAccent를 적용했는데도 회색으로 보이는 것은 메서드를 지정하지 않았기 때문이다. 버튼은 onPressed 메서드를 지정하지 않으면 backgroundColor가 활성화되지 않는다.

 

 

 

 

TextEditingController

ID, PW 입력값 필드에 TextEditingController를 적용하여 사용자의 text, selection 입력값을 감지하고 그에 맞게 동적인 업데이트를 할 수 있도록 해준다. 이 앱에서는 입력값을 바탕으로 Button이 눌러졌을 때 다른 페이지(dice game page)로 이동하기 위해서 TextEditingController를 적용한다.

 

_LogInState 위젯에 TextEditingController를 만든다. 원래는 단순히 controller를 선언만 하는 것이 아니라 계속해서 사용자의 입력값을 감시할 필요가 없는 경우 dispose method를 따로 작성해주어야 한다. controller의 사용이 끝나면 폐기해줘야 resource의 낭비를 막을 수 있다. 여기서는 간단한 테스트용 앱이므로 따로 작성하지는 않는다고 한다.

 

flutter 공식 페이지에서 보면, dispose 메서드를 override 하는 것을 볼 수 있다. StatefulWidget의 메서드로 등록되어 있다.

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

다시 돌아와서, ID, PW 입력용 TextField의 controller 인자값으로 TextController 위젯을 적용한다. 아래 우측 사진에서 확인할 수 있듯, TextField에서는 controller 파라미터가 선언되어 있다.

 

이제 Button의 onPressed 메서드에 controller.text를 이용하여 분기처리 해주면 된다. if문 내에 있는 Dice 위젯은 향후 따로 만들어서 처리해줄 것이다. 그리고 else if문에 걸리면 ID나 PW가 맞지 않다는 안내문을 SnackBar로 띄워줄 것이다. 그럴러면 입력값에 따라 rebuild를 해줘야하므로 body 부분을 Builder로 한번 감싸줘야한다.

 

ScaffoldMessenger.of(context).showSnackBar

이제 조건 분기문에 들어갈 showSnackBar 메서드를 따로 작성한다. 이전에 배운대로 ScaffoldMessenger.of(context).showSnackBar 메서드를 사용하면 된다. 지연시간을 주고 싶을 때는 Duration 위젯을 사용하면 된다는 것도 기억하자.

이제 showSnackBar를 분기문들에 적용하고, dice.dart 파일을 import 해오면 로그인 페이지는 완성이다.

 

 

 

 

728x90
반응형