UI

두 개의 editText를 통해 이메일 형식인 아이디와 비밀번호를 입력하도록 하고, 이후 로그인 버튼을 통해 로그인할 수 있도록 한다.
로그인 구현
LoginActivity.kt
var auth : FirebaseAuth? = null
FirebaseAuth 인스턴스를 전역 변수로 선언해 준다.
override fun onStart() {
super.onStart()
auth?.currentUser?.reload() // 현재 사용자가 로그인 되어있는지 확인
login_btn.isEnabled = false // 로그인 버튼 비활성화
}
onStart() 메서드에서 사용자가 로그인되어있는지 확인
login_email_et.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(p0: Editable?) {
//텍스트 입력 후
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
//텍스트 입력 전
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
//텍스트 입력 중
}
})
editText의 addTextChangedListener에 TextWatcher 인터페이스를 연결하여 이벤트를 처리
텍스트 입력 상태를 고려하여 override한 각각의 메서드 내부를 구현
경고 문구를 출력하거나, 로그인 버튼을 활성화한다.
// 로그인 버튼 활성화 함수
private fun isActive(activate_login: Boolean?, activate_pw : Boolean?) {
login_btn.isEnabled = activate_login == true && activate_pw == true
}
addTextChangeListener는 EditText에 추가적인 글자 변화가 있는지 항상 듣고 있는 리스너
TextWatcher는 인터페이스로써 3단계(글자 변화 전, 중, 후)로 구성된 글자 변화의 시점의 메서드를 가지고 있음
fun isEmail(email: String?): Boolean { // 아이디가 이메일 형식이 맞는지 확인하는 함수
var returnValue = false
val p: Pattern = Patterns.EMAIL_ADDRESS
val m: Matcher = p.matcher(email)
if (m.find()) {
returnValue = true
}
return returnValue
}
isEmail 메서드를 작성하여 아이디가 이메일 형식인지 확인
android.util에서 제공하는 기본 패턴을 사용하여 입력값(email 변수)이 이메일 형식인지 확인
// 로그인하는 함수
private fun signinEmail(){
if(login_email_et.text.toString().isEmpty() ||
login_pw_et.text.toString().isEmpty()
) { // 아이디와 비밀번호가 채워지지 않은 경우
Toast.makeText(this, "아이디와 비밀번호를 채워주세요.", Toast.LENGTH_LONG).show()
} else if(!isEmail(login_email_et.text.toString())){ // 아이디가 이메일 형식이 아닐 경우
Toast.makeText(this,"이메일 형식으로 입력해주세요.", Toast.LENGTH_LONG).show()
} else {
auth?.signInWithEmailAndPassword(
login_email_et.text.toString(),
login_pw_et.text.toString()
)?.addOnCompleteListener { task ->
if (task.isSuccessful) { // 아이디와 패스워드가 맞았을 경우, 로그인
moveMainPage(task.result.user)
} else { // 아이디와 패스워드가 틀렸을 경우
if (task.exception?.message.equals("The password is invalid or the user does not have a password.")) { // 비밀번호가 틀렸을 경우
login_pw_warn.visibility = View.VISIBLE
login_pw_warn.text = "비밀번호가 일치하지 않습니다."
} else if (task.exception?.message.equals("There is no user record corresponding to this identifier. The user may have been deleted.")) { // 존재하지 않는 계정일 경우
login_pw_warn.visibility = View.VISIBLE
login_pw_warn.text = "계정이 존재하지 않습니다."
} else { // 로그인 오류
Toast.makeText(this, task.exception?.message, Toast.LENGTH_LONG).show()
}
}
}
}
}
// 메인 페이지로 이동하는 함수
private fun moveMainPage(user: FirebaseUser?){
if(user != null){
val intent = Intent(this, MainActivity::class.java)
finishAffinity() // 액티비티 스택을 비움
startActivity(intent)
}
}
아이디와 비밀번호가 올바르게 채워졌을 때 FirebaseAuth의 signInWithEmailAndPassword 기능을 통해서 메인 페이지로 이동한다. 만약, 로그인을 할 수 없는 경우라면 경고 메시지를 띄운다.
<전체 코드>
class LoginActivity : AppCompatActivity() {
var auth : FirebaseAuth? = null
var activateLogin : Boolean? = false
var activatePw : Boolean? = false
override fun onStart() {
super.onStart()
auth?.currentUser?.reload() // 현재 사용자가 로그인 되어있는지 확인
login_btn.isEnabled = false // 로그인 버튼 비활성화
}
override fun onCreate(savedInstanceState:Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
auth = FirebaseAuth.getInstance()
login_email_et.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(p0: Editable?) {
//텍스트를 입력 후
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
//텍스트 입력 전
login_email_warn.visibility = View.INVISIBLE
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
//텍스트 입력 중
activateLogin = isEmail(login_email_et.text.toString()) // 아이디가 이메일 형식일 경우에 로그인 버튼 활성화 준비
if(activateLogin!!){
login_email_warn.visibility = View.INVISIBLE
} else {
login_email_warn.visibility = View.VISIBLE
}
isActive(activateLogin, activatePw)
}
})
login_pw_et.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(p0: Editable?) {
//텍스트를 입력 후
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
//텍스트 입력 전
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
//텍스트 입력 중
activatePw = login_pw_et.length() > 0 // 비밀번호를 한 자리 이상 입력할 경우에 로그인 버튼 활성화 준비
isActive(activateLogin, activatePw)
}
})
login_btn.setOnClickListener{
signinEmail()
}
// 화면 전환
login_signup_tvb.setOnClickListener {
val intent = Intent(this, UserActivity::class.java)
startActivity(intent)
}
login_pw_tvb.setOnClickListener {
val intent = Intent(this, FindpwActivity::class.java)
startActivity(intent)
}
}
// 뒤로가기 2번
private var backPressedTime : Long = 0
override fun onBackPressed() {
// 2초내 다시 클릭하면 앱 종료
if (System.currentTimeMillis() - backPressedTime < 2000) {
finishAffinity()
return
}
// 한 번 클릭했을 시 메시지
Toast.makeText(this, "뒤로가기 버튼을 한번 더 누르시면 앱이 종료됩니다.", Toast.LENGTH_SHORT).show()
backPressedTime = System.currentTimeMillis()
}
private fun signinEmail(){ // 로그인하는 함수
if(login_email_et.text.toString().isEmpty() ||
login_pw_et.text.toString().isEmpty()
) { // 아이디와 비밀번호가 채워지지 않은 경우
Toast.makeText(this, "아이디와 비밀번호를 채워주세요.", Toast.LENGTH_LONG).show()
} else if(!isEmail(login_email_et.text.toString())){ // 아이디가 이메일 형식이 아닐 경우
Toast.makeText(this,"이메일 형식으로 입력해주세요.", Toast.LENGTH_LONG).show()
} else {
auth?.signInWithEmailAndPassword(
login_email_et.text.toString(),
login_pw_et.text.toString()
)?.addOnCompleteListener { task ->
if (task.isSuccessful) {
// 아이디와 패스워드가 맞았을 경우, 로그인
moveMainPage(task.result.user)
} else { // 아이디와 패스워드가 틀렸을 경우
if (task.exception?.message.equals("The password is invalid or the user does not have a password.")) { // 비밀번호가 틀렸을 경우
login_pw_warn.visibility = View.VISIBLE
login_pw_warn.text = "비밀번호가 일치하지 않습니다."
} else if (task.exception?.message.equals("There is no user record corresponding to this identifier. The user may have been deleted.")) { // 존재하지 않는 계정일 경우
login_pw_warn.visibility = View.VISIBLE
login_pw_warn.text = "계정이 존재하지 않습니다."
} else { // 로그인 오류
Toast.makeText(this, task.exception?.message, Toast.LENGTH_LONG).show()
}
}
}
}
}
private fun moveMainPage(user: FirebaseUser?){ // 메인 페이지로 이동하는 함수
if(user != null){
val intent = Intent(this, MainActivity::class.java)
finishAffinity() // 액티비티 스택을 비움
startActivity(intent)
}
}
fun isEmail(email: String?): Boolean { // 아이디가 이메일 형식이 맞는지 확인하는 함수
var returnValue = false
val p: Pattern = Patterns.EMAIL_ADDRESS
val m: Matcher = p.matcher(email)
if (m.find()) {
returnValue = true
}
return returnValue
}
private fun isActive(activate_login: Boolean?, activate_pw : Boolean?) { // 로그인 버튼 활성화 함수
login_btn.isEnabled = activate_login == true && activate_pw == true
}
}