본문 바로가기
관리자

Programming-[CrossPlatform]/Flutter

Flutter 기본-17. 채팅앱 - 로그인 Validation

728x90
반응형

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

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

 

코딩셰프

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

www.youtube.com

 

 

 

background image reference : https://wallpapercave.com/cartoon-chickens-wallpapers

 


 

 

1. ValueKey 적용

 

각 TextFormField 부분이 Key 값을 가지고 있지 않아서 Flutter가 같은 타입의 위젯들을 구분할 수 없는 상태이다. 그래서 위 영상처럼 SIGNUP에 작성된 내용이 LOGIN에도 그대로 남게 된다.

 

TextFormField - ValueKey(1)~ValueKey(5)로 모든 폼 필드에 밸류키를 적용한다. 이러면 Login/signup 이동이 일어나더라도 State가 엉키지 않는다.

 

TextFormField(
  key: ValueKey(5),
  decoration: InputDecoration(

 

 

2. Validation, Form 처리

 

Validator 적용

TextFormField의 validator 멤버 변수에 함수를 지정해주면 된다. validator는 value 값을 인자로 받게 되어있는데, 아무 값도 없을 수 있으므로 기본적으로 nullable하다. 유저가 무조건 어떤 값을 입력한다고 가정하고 맨 처음 작성한 value 뒤에 !를 붙여주었다. 그리고 검증 조건을 통과했을 때는 return null로 끝내주어야한다.

TextFormField(
  validator: (value){
    if(value!.isEmpty || value.length < 4){
      return 'Please enter at least 4 characters';
    }
    return null;
  },
  key: ValueKey(1),

 

email과 password 부분에도 validator를 적용해준다. 내용은 아래 코드와 같은데, 이후에 진행할 firebase의 인증 기능이 기본적으로 6자리 이상의 비밀번호를 요구하기 때문에 아래와 같은 조건을 지정해주었다.

validator: (value){
  if(value!.isEmpty || !value.contains('@')){
    return 'Please enter a valid email address';
  }
  return null;
},
validator: (value){
  if(value!.isEmpty || value.length < 6){
    return 'Password must be at least 6 characters long';
  }
  return null;
},

 

 

Form 저장

form의 validation을 위해서 TextFormField의 부모인 Form 위젯에 글로벌 키를 적용해야한다. State 클래스 안에 _formkey = GlobalKey<FormState>();를 생성한다.

class _LoginSignupScreenState extends State<LoginSignupScreen> {
  bool isSignupScreen = true;
  final _formkey = GlobalKey<FormState>();

 

그리고 SIGNUP, LOGIN을 위한 Form 위젯의 key 인자값으로 _formkey를 적용한다.

 

이제 Form 제출을 위한 메서드를 작성한다.

 

우선 State 쪽에 각 폼 필드에 입력될 값을 초기화할 userName, userEmail, userPassword를 설정해준다. 그리고 validation을 위해 _tryValidation 메서드를 생성한다. 여기서보면 _formkey.currentState를 받아와서 validatesave 메서드를 실행하는 것을 볼 수 있다. flutter에서 제공하는 기본 구조가 form의 key값을 기반으로 currentState를 불러온다음 처리한다는 것을 기억하자.

.validate()를 실행하면 각 TextFormField에 지정해둔 validate 함수가 실행되어 결과가 boolean으로 전달된다. 모든 폼 필드의 validator들이 null을 리턴하는지 검사하는 역할을 하는 것이다. 또한 .save()를 실행하면 아래에서 추가로 적용할 각 TextFormField에서의 onSaved에 지정해둔 함수가 실행된다. currentState값도 nullable하기 때문에 null check 처리를 해주었다.

class _LoginSignupScreenState extends State<LoginSignupScreen> {
  bool isSignupScreen = true;
  final _formkey = GlobalKey<FormState>();
  String userName = '';
  String userEmail = '';
  String userPassword = '';

  void _tryValidation(){
    final isValid = _formkey.currentState!.validate();
    if(isValid){
      _formkey.currentState!.save();
    }
  }

 

아래와 같이 onSaved를 validator를 적용할 때와 마찬가지로 각 위젯에 적용해주면 된다.

TextFormField(
  validator: (value){
    if(value!.isEmpty || value.length < 4){
      return 'Please enter at least 4 characters';
    }
    return null;
  },
  onSaved: (value){
    userName = value!;
  },

 

 

제출 버튼 처리

 

마지막으로 제출버튼을 눌렀을 때 _tryValidation 메서드가 실행되게 해서 validate, save가 실행되도록 해준다. 기존 제출 버튼을 감싸고 있던 Container에 GestureDector 위젯을 적용하고, onTap에 _tryValidaiton을 적용한다.

GestureDetector(
  onTap: () {
    _tryValidation();
  },
  child: Container(

 

이제 아무것도 입력하지 않은 채 submit 버튼을 눌러보면 각 필드에 설정한 validator가 작동하면서 에러메시지가 출력된다.

 

 

 

3. 에러메시지를 위한 UI 처리

 

에러 메시지에 의해 늘어나는 부분(오버 플로우), unfocus 기능을 추가한다.

 

오버플로우

오버플로우를 해결하기 위해 컨테이너의 높이를 늘리고, 버튼의 위치를 아래로 내릴 수도 있겠지만 그럼 팝업된 키보드에 의해서 입력 필드 자체가 가려져 버린다. 따라서 키보드가 올라온 상태에서도 사용자가 스크롤을 할 수 있도록 SingleChildScrollView를 적용한다. LOGIN, SIGNUP 버튼의 Row가 포함된 Column 상위에 SingleChildScrollView 위젯을 추가해주어야한다.

SingleChildScrollView(
  padding: EdgeInsets.only(bottom: 20),
  child: Column(
    children: [
      Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [
          GestureDetector(
            onTap: () {
              setState(() {
                isSignupScreen = false;
              });
            },

padding 적용 전

 

그리고 위 영상에서 submit 버튼과 password validator message가 겹쳐서, padding을 추가해주었다.(bottom: 20)

 

 

Unfocus

사용자가 입력을 하다가 focus를 벗어날 수 있도록 화면상의 빈 공간을 눌렀을 때 unfocus가 되도록 한다. 최상위 Stack 자체에 GestureDetector -onTap()에 unfocus를 적용한다.

 

 

추가: 구글 로그인 버튼에도 AnimatedPositioned 위젯 적용

 

 

 

 

728x90
반응형