728x90

EditText를 이용해서 로그인 기능 구현하기 

먼저 필드의 유효성 검사를 하기 위해서 addTextChangedListenerTextWatcher를 사용한다.

 

원형 

EditText.addTextChangedListener(object : TextWatcher{
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
                TODO("Not yet implemented")
            }

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                TODO("Not yet implemented")
            }  //텍스트 변화 감지시 마다 호출

            override fun afterTextChanged(s: Editable?) {
                TODO("Not yet implemented")
            }

        })

onTextChagned 에서 변화가 있을때마다 호출해줌

 

validation () 

private fun validation(editText: EditText) {  //각 필드 유효성 체크
        editText.addTextChangedListener(object : TextWatcher {
            val tv_passwordDescription = findViewById<TextView>(R.id.tv_DescriptionPassword)
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {

            }

            //텍스트 변화 있을 때 마다 실행
            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {

                if (editText.text.length == 0 || editText.text.isNullOrEmpty() || isEmpty(editText)
                ) {
                    when (editText.id) {
                        R.id.et_Id -> editText.error = "아이디를 입력하세요"
                        R.id.et_Email -> editText.error = "이메일을 입력하세요"
                        R.id.et_Password -> {
                            editText.error = "비밀번호를 입력하세요"
                            tv_passwordDescription.isVisible = true
                        }

                        R.id.et_ConfirmPassword -> editText.error = "비밀번호를 확인해주세요."
                        else -> ""
                    }
                } else {
                    if (editText.id == R.id.et_Password) {
                        tv_passwordDescription.isVisible = false
                        if (check(editText) && editText.text.length >= 10) { //비밀번호가 유효하고 10자 이상인지

                        } else {
                            editText.error = "10자리 이상, 특수문자, 숫자포함"
                        }

                    }
                    if (editText.id == R.id.et_ConfirmPassword) {
                        if (isEqualPassword()) {                  //password와confirmPassword가 같은지 체크

                        } else {
                            editText.error = "비밀번호가 같지 않음"
                        }
                    }
                }
            }

            override fun afterTextChanged(s: Editable?) {

            }

        })
    }

예시 EditText의 길이가 0 이거나 공백이면 error

setOnFocusChangeListener 를 이용해서 포커스가 아웃 되었을 때 역시 비어있으면 에러 처리

 

원형 

EditText.setOnFocusChangeListener { v, hasFocus ->
            if(hasFocus){

            }else{ //포커스 아웃시 처리

            }
        }

포커스가 되어있을 때 / 아닐 때 

 

focusOut()

private fun focusOut(editText: EditText) {//EditText가 비어 있을때 포커스 아웃처리
        editText.setOnFocusChangeListener { v, hasFocus ->
            if (hasFocus) {
            } else {
                editText.error = if (editText.text.length == 0 || editText.text.isNullOrEmpty()
                ) {
                    when (editText.id) {
                        R.id.et_Id -> "아이디를 입력하세요"
                        R.id.et_Email -> "이메일을 입력하세요"
                        R.id.et_Password -> "비밀번호를 입력하세요"
                        R.id.et_ConfirmPassword -> "비밀번호를 확인해주세요"
                        else -> ""
                    }
                } else null
            }
        }
    }

 

 

정규식을 이용해서 특수문자,숫자 포함 비밀번호 만들기

비밀번호가 특수문자 와 숫자를 포함하는지 체크 하는 check()

private fun check(editText: EditText): Boolean { //특수문자 숫자 정규식
        val pwd = """^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[!@#$%^+\-=])(?=\S+$).*$"""
        val pattern = Pattern.compile(pwd)
        return pattern.matcher(editText.text).matches()
    }

matches() 리턴 값 -> bollean  

 

비밀번호가 같지 않으면 가입 처리가 불가능

 

비밀번호 check에서 걸러짐
입력 값이 비어있을 때
유효성 검사 완료 가입승인

 

 

SignUpActivity 전체 코드

class SignUpActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_sign_up)
        val signUpButton = findViewById<Button>(R.id.btn_SignUp)
        val id = findViewById<EditText>(R.id.et_Id)
        val password = findViewById<EditText>(R.id.et_Password)
        val confirmPassword = findViewById<EditText>(R.id.et_ConfirmPassword)
        val email = findViewById<EditText>(R.id.et_Email)
        val spinner = findViewById<Spinner>(R.id.spinner)
        val emailForm = findViewById<EditText>(R.id.et_EmailForm)
        createSpinner(spinner, emailForm)
        validation(id)
        validation(email)
        validation(password)
        validation(confirmPassword)
        focusOut(id)
        focusOut(email)
        focusOut(password)
        focusOut(confirmPassword)

        signUpButton.setOnClickListener {
            if (id.text.isNullOrEmpty() || confirmPassword.text.isNullOrEmpty() || password.text.isNullOrEmpty() || email.text.isNullOrEmpty() || emailForm.text.isNullOrEmpty()) {
                Toast.makeText(this, "입력값이 비어있습니다.", Toast.LENGTH_SHORT).show()
                return@setOnClickListener
            } else {//모든 필드가 입력된 상태
                if (isEqualPassword() && check(password)) { //유효성 검사 후 승인
                    Intent().apply {
                        putExtra("updatedId", id.text.toString())
                        putExtra("updatedPassword", password.text.toString())
                        setResult(RESULT_OK, this)
                    }
                    saveData()
                    finish()
                } else if (check(password)) { //password 와 confirmPassword가 같을 때 처리
                    Toast.makeText(this, "비밀번호가 일치하지 않습니다.", Toast.LENGTH_SHORT).show()
                } else { //둘 다 아닐 때
                    Toast.makeText(this, "비밀번호는 10자리 이상, 특수문자, 숫자포함 입니다.", Toast.LENGTH_SHORT)
                        .show()
                }

            }
        }


    }

    private fun saveData() {   //입력 값 저장
        val id = findViewById<EditText>(R.id.et_Id)
        val password = findViewById<EditText>(R.id.et_Password)
        val confirmPassword = findViewById<EditText>(R.id.et_ConfirmPassword)
        val email = findViewById<EditText>(R.id.et_Email)
        val emailForm = findViewById<EditText>(R.id.et_EmailForm)
        getSharedPreferences(INFO, Context.MODE_PRIVATE)?.edit {
            putString(ID, id.text.toString())
            putString(EMAIL, email.text.toString())
            putString(EMAIL_FORM, emailForm.text.toString())
            putString(PASSWORD, password.text.toString())
            putString(CONFIRM_PASSWORD, confirmPassword.text.toString())
            apply()
        }
    }

    private fun getSaveData() {  //저장한 값 불러오기
        val id = findViewById<EditText>(R.id.et_Id)
        val password = findViewById<EditText>(R.id.et_Password)
        val confirmPassword = findViewById<EditText>(R.id.et_ConfirmPassword)
        val email = findViewById<EditText>(R.id.et_Email)
        val emailForm = findViewById<EditText>(R.id.et_EmailForm)
        getSharedPreferences(INFO, Context.MODE_PRIVATE).run {
            id.setText(getString(ID, ""))
            email.setText(getString(EMAIL, ""))
            password.setText(getString(PASSWORD, ""))
            confirmPassword.setText(getString(CONFIRM_PASSWORD, ""))
            emailForm.setText(getString(EMAIL_FORM, ""))
        }

    }

    override fun onResume() {  //onResume 시 값 불러옴
        getSaveData()
        super.onResume()
    }

    override fun onDestroy() {  //onDestroy 시 값 저장
        saveData()
        super.onDestroy()
    }

    private fun focusOut(editText: EditText) {//EditText가 비어 있을때 포커스 아웃처리
        editText.setOnFocusChangeListener { v, hasFocus ->
            if (hasFocus) {
            } else {
                editText.error = if (editText.text.length == 0 || editText.text.isNullOrEmpty()
                ) {
                    when (editText.id) {
                        R.id.et_Id -> "아이디를 입력하세요"
                        R.id.et_Email -> "이메일을 입력하세요"
                        R.id.et_Password -> "비밀번호를 입력하세요"
                        R.id.et_ConfirmPassword -> "비밀번호를 확인해주세요"
                        else -> ""
                    }
                } else null
            }
        }
    }

    private fun validation(editText: EditText) {  //각 필드 유효성 체크
        editText.addTextChangedListener(object : TextWatcher {
            val tv_passwordDescription = findViewById<TextView>(R.id.tv_DescriptionPassword)
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {

            }

            //텍스트 변화 있을 때 마다 실행
            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {

                if (editText.text.length == 0 || editText.text.isNullOrEmpty() || isEmpty(editText)
                ) {
                    when (editText.id) {
                        R.id.et_Id -> editText.error = "아이디를 입력하세요"
                        R.id.et_Email -> editText.error = "이메일을 입력하세요"
                        R.id.et_Password -> {
                            editText.error = "비밀번호를 입력하세요"
                            tv_passwordDescription.isVisible = true
                        }

                        R.id.et_ConfirmPassword -> editText.error = "비밀번호를 확인해주세요."
                        else -> ""
                    }
                } else {
                    if (editText.id == R.id.et_Password) {
                        tv_passwordDescription.isVisible = false
                        if (check(editText) && editText.text.length >= 10) { //비밀번호가 유효하고 10자 이상인지

                        } else {
                            editText.error = "10자리 이상, 특수문자, 숫자포함"
                        }

                    }
                    if (editText.id == R.id.et_ConfirmPassword) {
                        if (isEqualPassword()) {                  //password와confirmPassword가 같은지 체크

                        } else {
                            editText.error = "비밀번호가 같지 않음"
                        }
                    }
                }
            }

            override fun afterTextChanged(s: Editable?) {

            }

        })
    }

    private fun isEmpty(editText: EditText): Boolean {          //공백 문자 처리
        val empty = editText.text.toString()
        empty.replace(" ", "")
        return empty.contains(" ")
    }

    private fun createSpinner(spinner: Spinner, emailForm: EditText) {   //스피너 생성 및 리스너
        spinner.apply {
            adapter = ArrayAdapter.createFromResource(//스피너 생성
                baseContext,
                R.array.email,
                android.R.layout.simple_list_item_1
            )
            onItemSelectedListener = object : OnItemSelectedListener { //리스너
                override fun onItemSelected(
                    parent: AdapterView<*>?,
                    view: View?,
                    position: Int,
                    id: Long
                ) {
                    if (spinner.selectedItemPosition == 3) {    //드롭메뉴 직접입력 선택시 직접입력하게 비움
                        emailForm.apply {
                            setText("")
                            setHint("직접입력")
                        }
                    } else emailForm.setText(spinner.selectedItem.toString()) // 드롭메뉴 아이템선택시 EditText 입력
                }

                override fun onNothingSelected(parent: AdapterView<*>?) {
                }
            }
        }
    }

    private fun check(editText: EditText): Boolean { //특수문자 숫자 정규식
        val pwd = """^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[!@#$%^+\-=])(?=\S+$).*$"""
        val pattern = Pattern.compile(pwd)
        return pattern.matcher(editText.text).matches()
    }


    private fun isEqualPassword(): Boolean {   //password 와 confirmPassword가 같은지 체크
        val password = findViewById<EditText>(R.id.et_Password)
        val confirmPassword = findViewById<EditText>(R.id.et_ConfirmPassword)
        return password.text.toString() == confirmPassword.text.toString()
    }
}

+ Recent posts