본문 바로가기
프로그래밍/Flutter-Dart

[Flutter] Login App (3)

by 채연2 2021. 3. 29.

1. get package 사용

2. 이메일 유효성 검사

3. 비밀번호 obscure suffix icon event

4. login button event

 

 

 

1. 기본 틀 구현

// @dart=2.9
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

class Login extends StatelessWidget {
  final TextEditingController _email = new TextEditingController();
  final TextEditingController _pass = new TextEditingController();

  String get emailText => _email.text;
  String get passText => _pass.text;

  @override
  Widget build(BuildContext context) {
    double width = MediaQuery.of(context).size.width;
    double height = MediaQuery.of(context).size.height;

    onSubmit() {
      print(emailText + " " + passText);
    }

    return Container(
      padding: EdgeInsets.only(top: height / 10),
      child: Column(
        children: <Widget>[
          TextField(
            controller: _email,
            decoration: InputDecoration(hintText: '이메일'),
          ),
          Text('alert message'),
          TextField(
            controller: _pass,
            decoration: InputDecoration(
                hintText: '비밀번호',
                suffixIcon: IconButton(
                  icon: Icon(
                        Icons.remove_red_eye,
                        color: Colors.grey,
                      ),
                )),
            obscureText: true,
          ),
          Container(
              padding: EdgeInsets.only(top: height / 10),
              child: ElevatedButton(
                child: Text('로그인'),
                onPressed: onSubmit,
                style: ElevatedButton.styleFrom(
                    primary: Colors.black,
                    onPrimary: Colors.white,
                    padding: EdgeInsets.only(
                        left: width / 10 * 2, right: width / 10 * 2)),
              ))
        ],
      ),
    );
  }
}

 

 

2-1. email 유효성 검사

String _buildEmail(text) {
   if (text.toString().isEmpty) {
      _pass.clear();
      return '이메일을 입력해주세요.';
   } else if (!RegExp(
         r"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?")
         .hasMatch(text.toString())) {
      return '이메일 형식을 확인하세요.';
   } else {
      return null;
   }
}

 

 

2-2. Controller class (alert message)

class Controller extends GetxController {
  var alert = ''.obs;

  textChange(String text) {
    alert.value = text;
  }
}

 

 

2-3. Controller 사용 (email TextField 입력에 따른 alert message 보여주는 Text Change)

class Login extends StatelessWidget {
  ...
  Controller _controller = Get.put(Controller());

  @override
  Widget build(BuildContext context) {
    ...
    return Container(
      padding: EdgeInsets.only(top: height / 10),
      child: Column(
        children: <Widget>[
          TextField(
            controller: _email,
            decoration: InputDecoration(hintText: '이메일'),
            onChanged: (text) {
              _controller.textChange(_buildEmail(text));
            },
          ),
          Obx(() => Text(_controller.alert.value ?? '')),
          TextField(
            controller: _pass,
            decoration: InputDecoration(
                hintText: '비밀번호',
                suffixIcon: IconButton(
                  icon: Icon(
                        Icons.remove_red_eye,
                        color: Colors.grey,
                      ),
                )),
            obscureText: true,
          ),
          Container(
              padding: EdgeInsets.only(top: height / 10),
              child: ElevatedButton(
                child: Text('로그인'),
                onPressed: onSubmit,
                style: ElevatedButton.styleFrom(
                    primary: Colors.black,
                    onPrimary: Colors.white,
                    padding: EdgeInsets.only(
                        left: width / 10 * 2, right: width / 10 * 2)),
              ))
        ],
      ),
    );
  }
}

 

 

3-1. Controller class (password suffix icon)

class Controller extends GetxController {
  var alert = ''.obs;
  var isobscure = true.obs;

  textChange(String text) {
    alert.value = text;
  }

  obscureChange() {
    isobscure.value = !isobscure.value;
  }
}

 

 

3-2. Controller 사용 (suffix icon 이벤트)

@override
Widget build(BuildContext context) {
   ...
   return Container(
      padding: EdgeInsets.only(top: height / 10),
      child: Column(
         children: <Widget>[
            ...
            Obx(() => TextField(
               controller: _pass,
               decoration: InputDecoration(
                  hintText: '비밀번호',
                  suffixIcon: IconButton(
                     icon: Icon(
                        Icons.remove_red_eye,
                        color: _controller.isobscure.value
                            ? Colors.grey
                            : Colors.black,
                     ),
                     onPressed: _controller.obscureChange,
                  )),
                  obscureText: _controller.isobscure.value,
               },
            )),
            ...
         ],
      ),
   );
}

 

 

4-1. Controller class (login button active)

class Controller extends GetxController {
  var alert = ''.obs;
  var isobscure = true.obs;
  var btnable = false.obs;

  textChange(String text) {
    alert.value = text;
  }

  obscureChange() {
    isobscure.value = !isobscure.value;
  }

  btnableChange(bool value) {
    btnable.value = value;
  }
}

 

 

4-2. Controller 사용 (각 TextField 입력에 따른 login button 활성화 이벤트)

@override
Widget build(BuildContext context) {
   ...
   return Container(
      padding: EdgeInsets.only(top: height / 10),
      child: Column(
         children: <Widget>[
            ...
            Obx(() => TextField(
               ...
               onChanged: (text) {
                  if(text.isEmpty) {
                     _controller.btnableChange(false);
                  } else if(_controller.alert.value == null) {
                     if(!_controller.btnable.value) {
                        _controller.btnableChange(true);
                     }
                  } else {
                     _controller.btnableChange(false);
                  }
               },
            )
         ),
         Container(
            padding: EdgeInsets.only(top: height / 10),
            child: Obx(() => ElevatedButton(
               child: Text('로그인'),
               onPressed: onSubmit,
               style: ElevatedButton.styleFrom(
                  primary: _controller.btnable.value ? Colors.black : Colors.black26,
                  onPrimary: Colors.white,
                  padding: EdgeInsets.only(
                     left: width / 10 * 2, right: width / 10 * 2)),
                  )
               )
            )
         ],
      ),
   );
}

 

 

5. 결과

 

 

 

 

참고 : donggyu9410.medium.com/flutter%EC%97%90%EC%84%9C-%EC%9C%A0%ED%9A%A8%EC%84%B1-%EA%B2%80%EC%82%AC-%ED%8F%BC-%EB%A7%8C%EB%93%A4%EA%B8%B0-14c622cfdf47

 

Flutter에서 유효성 검사 폼 만들기

우선 프로젝트의 기본 짜임새는 다음과 같습니다.

donggyu9410.medium.com

 

320x100

'프로그래밍 > Flutter-Dart' 카테고리의 다른 글

[Flutter] Flexible, Expanded  (0) 2022.02.16
[Flutter] Row, Column  (0) 2022.02.16
[Flutter] native code 호출하기  (0) 2021.03.26
[Flutter] Card  (0) 2021.03.25
[Flutter] Unsound null safety 관련  (0) 2021.03.25

댓글