오늘은 어제 끝냈던 자기소개 앱 만들기를 약간 수정해보았다.
회원가입 화면에 비밀번호 확인 editText를 추가로 만들어서, 비밀번호를 한번 더 확인할 수 있게 해줬다. 회원가입을 진행하기 전에, 비밀번호 text와 비밀번호확인 text를 가져와서 서로 일치한다면 진행시켜줬다.
if (editPassword.text.toString() == editPasswordCheck.text.toString()) {
//여기서 기존 회원가입 코드 작성.
}
다음으로는 spinner를 만들어줬다. 기존에 아이디를 입력할 수 있는 editText를 이메일 형식으로 변경해주고, @부분부터 뒷부분은 spinner를 이용해서 직접입력, 또는 naver.com/daum.net등의 형식을 고를수 있게 만들었다. 만드는 방법은 간단한데, 먼저 xml에서 spinner를 선언해준다.
<Spinner
android:id="@+id/spinner"
android:layout_width="150dp"
android:layout_height="50dp"
android:layout_marginRight="15dp"
android:visibility="visible"/>
그 후에는 Activity로 돌아와서, spinner안에 넣을 내용을 배열로 선언해주고, adapter를 만들어준다. 그뒤에 spinner에 해당 배열을 넣어주면 끝난다.
val spinner = findViewById<Spinner>(R.id.spinner)
val spinnerArray = arrayOf("직접입력", "@naver.com", "@gmail.com", "@daum.net")
val adapter: ArrayAdapter<String> =
ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, spinnerArray)
spinner.adapter = adapter
여기까지 해주면 화면상에서 spinner안에 배열에 있는 내용이 들어간다. 하지만 지금은 기능에 대한것이 구현이 안되어있다. 만약 @naver.com을 선택한다면 해당 내용을 editText뒤에 붙여주기 위해서
OnItemSelectedListener를 이용할거다.
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener{
override fun onItemSelected(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) {
if(p2 != 0){
val selectedValue = spinner.selectedItem.toString()
editEmailBack.setText(selectedValue)
spinner.visibility = View.INVISIBLE
editEmailBack.visibility = View.VISIBLE
}
}
override fun onNothingSelected(p0: AdapterView<*>?) {
}
}
이렇게 이용해주고, 먼저 onItemSelected를 오버라이드 한 부분에서 p0~03이 매개변수로 주어져있는데, 각각 어떤걸 의미하냐면
p0 -> AdapterView 인터페이스를 나타내며 Spinner는 AdapterView를 상속하기때문에 p0은 현재 이벤트가 발생한 spinner를 가르킨다. null일수 있으니 ?로 선언되어있다.
p1 -> AdapterView에서 각 항목을 나타내는 View이다. 보통 spinner에서는 TextView를 상속한 뷰가 될것이고, p1역시 null일수 있으니 ?로 선언됐다.
p2 -> 현재 선택된 항목의 인덱스이다. 배열로 선언해뒀던 spinner의 내용들의 인덱스값이다.
p3 -> 현재 선택된 항목의 고유한 식별자이다. spinner에서는 일반적으로 잘 사용되지 않고, adapterView의 기능중 하나인 getItemId에서 반환한 항목의 고유 Id가 될 수 있다.
사실 spinner를 사용하려면 p2만 알면 될것같다.
회원가입하면서 EditText에서 Focus Out이 될때에 대한 기능을 setOnFocusChangeListener을 이용해서 추가해줬다. 예를 들어 nameEditText에서는
editName.setOnFocusChangeListener { view, b ->
if (!b) {
if (editName.text.isEmpty()) {
errorName.visibility = View.VISIBLE
} else {
errorName.visibility = View.INVISIBLE
}
}
}
if문 안에 !b를 사용해서 클릭이 지나갔을때? 커서가 다른곳으로 이동했을때? 포커스 아웃됐을떄???? 에 대한 내용을 넣어줬다. 나는 그때 editName이 빈칸이라면 평상시에는 안보이게 미리 만들어둔 errName텍스트를 보이게 만들어서 경고내용을 알렸다.

마지막으로 비밀번호에 조건을 걸어줬다. 나는 3가지 조건을 걸었는데 길이가 10미만일때, 대문자를 포함하지 않았을때, 특수문자를 포함하지 않았을때 비밀번호를 다시 입력하게 만들어줬다.
비밀번호를 확인해주는 함수를 하나 만들고, 해당 함수에서 처리해줬다.
private fun passwordChecking(value: String): String {
var returnValue = "ok"
if (value.length < 10) {
returnValue = "length"
return returnValue
}
if (!containsUpper(value)){
returnValue = "containsUpper"
return returnValue
}
if (!containSpecialChar(value)){
returnValue = "specialChar"
return returnValue
}
return returnValue
}
새로운 string값을 만들고, 각각 제약을 걸어줬는데, 대문자포함하는부분과 특수문자를 포함하는 부분은 따로 함수를 만들어줬다.
//특수문자가 있는지확인
private fun containSpecialChar(value:String):Boolean{
val sCharPattern = Regex("[^A-Za-z0-9]") //영어 대소문자, 숫자가 아닌 모든 숫자를 나타내는 정규표현식
return sCharPattern.containsMatchIn(value)
}
//대문자 확인
private fun containsUpper(value:String):Boolean{
val myList = ('A'..'Z').toList()
return myList.any { it in value }
}
이렇게 제약조건을 걸어서 더 보안성이 강화된 비밀번호를 받을 수 있게 만들어줬다.
그 후에는 회원가입 버튼을 눌렀을때, 비밀번호를 확인해줬다.
val check = passwordChecking(editPassword.text.toString())
when(check){
"ok" -> {
//회원가입 진행
}
"length" -> {
message("비밀번호는 최소 10글자 이상이여야 합니다.")
}
"specialChar" -> {
message("비밀번호는 1개이상의 특수문자가 포함되어야 합니다.")
}
"containsUpper" -> {
message("비밀번호에는 대문자가 포함되어야 합니다.")
}
}
이렇게 해서 자기소개 앱을 더 꾸며보고 수정해봤다. 사실 아직 완벽하진 않다. 원하는 목표는 현재는 버튼이 클릭이 되었을때 제약조건들을 확인하고, 통과하지못하면 토스트메시지를, 통과한다면 회원가입이 완료가 되는데, 제약조건이 만족하지 않는다면 버튼을 비활성화해서 아예 버튼을 누르지 못하게 할 예정이다. 이 부분은
signBtn.isEnabled = false
이런식으로 비활성화를 해주고, 만족한다면 활성화해주는 방향으로 추후에 수정해볼 예정이다.
오늘 앱을 만들며 공부한 spinner및 정규식을 이용한 제약조건 확인하는 내용은 앞으로도 종종 쓰일것 같아서 좋은 내용을 공부한것 같아 기분 좋은 날인거같다!
🦾🦾