티스토리 뷰

012

 

 

간단한 회원가입 화면을 만들어보겠습니다.

 

요구사항은 다음과 같습니다.

1. 가입버튼 기본 비활성화

1-1. 이용 약관 동의 체크 시 버튼 활성화, 체크 해제시 다시 비활성화

2. 버튼 클릭 시 이름,이메일 입력 여부 체크(이름, 이메일 필수 입력/ 성별 필수 x)

2-1. 미입력 또는 이메일 타입 오류 시 안내 문구 출력

3. 모든 조건에 만족하는 데이터 입력시 단일 문자열로 log 출력

 

homework2.xml

기존에 만들어뒀던 화면을 재활용하겠습니다.

성별은 둘 중 하나 택1이기 때문에 라디오그룹으로 묶었습니다. 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Homework2Activity"
    android:orientation="vertical"
    >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="회원가입"
        android:textStyle="bold"
        android:textColor="#000000"
        android:layout_gravity="center"/>

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:src="@mipmap/ic_launcher_round"
        android:layout_gravity="center"/>

    <EditText
        android:id="@+id/ed_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="이름을 입력하세요"
        android:layout_marginTop="10dp"/>
    <EditText
        android:id="@+id/ed_email"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="이메일을 입력하세요"
        android:layout_marginTop="10dp"
        android:inputType="textEmailAddress"/>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="성별"
        android:layout_marginTop="16dp"
        android:textColor="#000000"/>
    <RadioGroup
        android:id="@+id/rd_group"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_marginTop="5dp"
        >
        <RadioButton
            android:id="@+id/rb_male"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="남성"/>
        <RadioButton
            android:id="@+id/rb_female"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="여성"/>
    </RadioGroup>

    <CheckBox
        android:id="@+id/check"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="이용약관에 동의합니다"
        android:layout_marginTop="30dp"
        android:layout_marginBottom="30dp"/>
    <Button
        android:id="@+id/btn_enter"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="가입하기"
        />

</LinearLayout>

 

Homework2.kt

import android.os.Bundle
import android.util.Log
import android.util.Patterns
import android.widget.RadioGroup
import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.example.ch4.databinding.ActivityHomework2Binding

class Homework2Activity : AppCompatActivity() {
    lateinit var binding: ActivityHomework2Binding
    private var sex: String = ""

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()

        binding = ActivityHomework2Binding.inflate(layoutInflater)

        setContentView(binding.root)

        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
            insets
        }


        binding.run{
            btnEnter.isEnabled = false

            //약관 체크 여부에 따른 가입하기 버튼 상태 변경
            check.setOnCheckedChangeListener {_, isChecked ->
                btnEnter.isEnabled = isChecked
            }

            rdGroup.setOnCheckedChangeListener{_, checkedId ->
                when(checkedId){
                    rbMale.id -> sex = "남성"
                    rbFemale.id -> sex = "여성"
                }
            }

            val name = edName.text
            val email = edEmail.text
            btnEnter.setOnClickListener {
                if(name.isEmpty()){
                    showToast("name invalid")
                    return@setOnClickListener
                }
                if (email.isEmpty() || !isValidEmail(email.toString())){
                    showToast("email invalid")
                    return@setOnClickListener
                }

                Log.d("출력", "이름: ${edName.text}, 이메일: ${edEmail.text}, 성별: $sex")

            }

        }
    }
    private fun showToast(message: String){
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
    }
    fun isValidEmail(email: String): Boolean = Patterns.EMAIL_ADDRESS.matcher(email).matches()

}

 

 

EditText에 들어있는 객체를 읽을 땐 EditText.text로 읽어야 한다.

EditText.text는 살아있는 객체, 즉 현재 입력한 값을 바로 받아오고, EditText.text.toString()은 그 순간을 캡쳐한 스냅샷.

val name = edName.text.toString()

 처음에 이런 식으로 작성했는데 name이 계속 null이 뜨길래 뭐지? 했는데 

입력 전 캡쳐(toString) -> name.isEmpty() => ㅇㅇ 트루 줄게 이 상태였다. 

 

(02.05 수정)

맞긴 한데 제 경우엔 위치 문제였음!! name과 email을 엔터 버튼이 클릭하기도 전에, 생성하자마자 toString()을 해버려서 그런 거였음.

btnEnter.setOnClickListener 안에서 name과 email을 생성해줬으면 바로 toString을 붙여도 무방함 -> 그때는 edName에 값이 들어 있는 상태일 거니까!!

 

⭐체크박스의 상태에 따라 버튼에 변화를 주고 싶다면 리스너로 읽을 것

btnEnter.isEnabled = check.isChecked

처음엔 그냥 이렇게 줬다. 그랬더니 체크박스를 클릭해도 버튼의 상태가 바뀌지 않는 거임

당연함.. 처음 상태 주고 또 바꾸는 무언가가 없으니 그냥 초기값 그대로 고정인 거임.

리스너는 어떤 체크 박스인지, 체크 상태를 판별하는 두 가지 파라미터가 있지만 이 코드에서는 어떤 체크박스인지 판별할 필요가 없기 때문에 _로 넣었다.

 

⭐라디오 그룹

라디오 그룹 리스너 또한 라디오그룹과 선택된 라디오버튼의 id를 파라미터로 받고 있지만 라디오그룹을 사용하지 않아서 _로 버렸다. 그리고 id 값으로 확인을 하기 때문에 뒤에 .id를 꼬옥 붙여줘야 합니다.

안 붙이면 걍 라디오버튼 객체임.

 

⭐이메일 형식 확인하기

안드로이드는 참 편리한 기능을 많이 제공하는 것 같다. Patterns로 이메일과 함께 전화번호, ip등 다양한 형식 확인을 제공하고 있다.

 

끝!!