[Android / Kotlin] TextWatcher와 정규식을 사용한 회원 가입 화면

Subeen·2023년 3월 2일
1

Android

목록 보기
2/73
post-thumbnail

📍 TextWatcher 란?

EditText의 값이 변경될 때마다 입력 된 값을 실시간으로 관찰하면서 특정 작업을 처리 해주기 위한 인터페이스이다.

TextWatcher에는 3가지 메서드가 있으며, 인터페이스를 구현할 때 TextWatcher가 가지고 있는 메서드를 재정의 해야 한다.

  • beforeTextChanged(CharSequence charSequence, int i, int i1, int i2)
    - 텍스트가 변경되기 전에 호출된다.
    - charSequence : 현재 EditText에 입력 된 값
  • onTextChanged(CharSequence charSequence, int i, int i1, int i2)
    - 텍스트가 변경될 때마다 호출된다.
    - charSequence : 새로 입력한 문자열이 추가 된 EditText 값
  • afterTextChanged(Editable editable)
    - 텍스트가 변경된 후 호출된다.

📍 정규 표현식이란?

정규표현식이란 특정한 규칙을 가진 문자열의 집합을 표현하기 위해 쓰이는 형식 언어이다.
전화번호, 주민등록번호, 이메일 등 사용자가 정해진 형식대로 입력했는지 검증해야 할 경우 정규표현식을 사용하여 구현할 수 있다.

  • 정규 표현식
    • 숫자 : ^[0-9]*$
    • 영문자 : ^[a-zA-Z]*$
    • 한글 : ^[가-힣]*$
    • 이메일 : \w+@\w+\.\w+(\.\w+)?
    • 전화번호 : ^\d{2,3}-\d{3,4}-\d{4}$
    • 휴대전화번호 : ^01(?:0|1|[6-9])-(?:\d{3}|\d{4})-\d{4}$
    • 주민등록번호 : \d{6} - [1-4]\d{6}
    • 우편번호 : ^\d{3}-\d{2}$

📍 결과 동영상

  • 회원가입 화면 목표
    • 이메일 아이디, 비밀번호, 비밀번호 확인 입력으로 구성
    • 이메일 칸 입력 시 유효성 검사
    • 비밀번호는 정규식을 사용하여 영문+숫자+특수문자 조합 8~16자리
    • 비밀번호와 비밀번호 확인 입력 값이 동일한지 확인
    • 이메일의 경우 TextWatcher를 사용하여 이메일 형식이 아닐 경우 EditText 테두리를 빨간색으로 처리
    • 비밀번호의 경우 TextWatcher를 사용하여 주어진 비밀번호 조합이 아닐 경우 EditText 테두리를 빨간색으로 처리
    • 확인 버튼을 눌렀을 때 Firebase Authenticate 회원가입을 사용하여 계정 등록

📍 Code

👩🏻‍💻 이메일 EditText에 TextWatcher 연결 & 유효성 검사 함수

		// 이메일 EditText TextWatcher
		binding.emailArea.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
            }

            override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
                // 텍스트가 변경될 때마다 호출된다.
                // 이메일을 입력할 때 실시간으로 이메일 형식을 검사한다.
                isRegularEmail()
            }

            override fun afterTextChanged(p0: Editable?) {
            }

        })
        
        // 이메일 유효성 검사 함수 
        private fun isRegularEmail(): Boolean {
			val email = binding.emailArea.text.toString().trim()
            val pattern = android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()
          
			if (pattern) {
              // 유효성 검사 결과 이메일 형식일 경우  
              binding.emailArea.setBackgroundResource(R.drawable.background_radius)
              return true
			} else {
              // 유효성 검사 결과 이메일 형식이 아니면 EditText 테두리를 빨간색으로 처리한다.
              binding.emailArea.setBackgroundResource(R.drawable.background_radius_red)
              return false
			}
    }

👩🏻‍💻 비밀번호 EditText에 TextWatcher 연결 & 유효성 검사 함수

		// 비밀번호 EditText TextWatcher
        binding.pwdArea.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
            }

            override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
                // 텍스트가 변경될 때마다 호출된다.
                // 비밀번호를 입력할 때 실시간으로 비밀번호 형식을 검사한다.
                isRegularPwd()
            }

            override fun afterTextChanged(p0: Editable?) {
            }

        })
        
        private fun isRegularPwd(): Boolean {
          val pwd = binding.pwdArea.text.toString().trim()
          // 영어, 숫자, 특수문자, 글자 수는 8~16자인 비밀번호 패턴
          val pwdPattern =
              "^(?=.*[A-Za-z])(?=.*[0-9])(?=.*[$@$!%*#?&.])[A-Za-z[0-9]$@$!%*#?&.]{8,16}$"
          val pattern = Pattern.matches(pwdPattern, pwd) // 패턴이 맞는지 확인

          if (pattern) {
			// 유효성 검사 결과 정해진 비밀번호 형식일 경우  
            binding.pwdArea.setBackgroundResource(R.drawable.background_radius)
            return true
          } else {
            // 유효성 검사 결과 비밀번호 형식이 아니면 EditText 테두리를 빨간색으로 처리한다. 
            binding.pwdArea.setBackgroundResource(R.drawable.background_radius_red)
            return false
          }
    }
        

👩🏻‍💻 확인 버튼을 눌렀을 때 처리

        binding.joinBtn.setOnClickListener {
            var isGotoJoin = true

            val email = binding.emailArea.text.toString()
            val pwd = binding.pwdArea.text.toString()

            if (!isRegularEmail()) {
                toast("아이디는 이메일 형식으로 입력해주세요.")
                isGotoJoin = false
            } else if (!isRegularPwd()) {
                toast("비밀번호는 영문+숫자+특수문자 조합하여 8~16자리로 입력해주세요.")
                isGotoJoin = false
            } else if (email.isEmpty() || pwd.isEmpty()) {
                toast("공란이 존재합니다.")
                isGotoJoin = false
            } else if (!isEqualsPwd()) {
                toast("비밀번호 정보가 일치하지 않습니다.")
                isGotoJoin = false
            }

            if (isGotoJoin) {
				// 회원가입 조건이 충족되었을 경우에만 signUp 함수로 이동 
                signUp(email, pwd)
            }
        }
        
        // Firebase Authenticate 회원가입
		private fun signUp(email: String, password: String) {
			FBAuth.auth.createUserWithEmailAndPassword(email, password)
			.addOnCompleteListener(this) { task ->
				if (task.isSuccessful) {
					toast("회원가입 성공")
					goToMainActivity(task.result?.user)
				} else if (task.exception?.message.isNullOrEmpty()) {
					toast(task.exception?.message.toString())
				} else {
					toast("이미 사용중인 아이디입니다. 다른 아이디를 사용해주세요.")
				}
			}
    	}

👩🏻‍💻 EditText 둥근 모서리 레이아웃 만들기

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <stroke
        android:width="1dp"
        android:color="#999999" />
    <solid android:color="#00ff0000" />
    <corners android:radius="3dp" />
</shape>

TextWatcher 참고
정규표현식 참고

profile
개발 공부 기록 🌱

0개의 댓글