코틀린(Kotlin)/해보기

[코틀린(Kotlin)] 로그인, 회원가입, 자기소개 페이지 만들기

초보왕보초 2023. 12. 15. 19:49
728x90

구현하고자 하는 것

  • 로그인 페이지(SignInActivity)
    → 로그인 버튼을 누르면 HomeActivity 실행 (Extra로 아이디를 넘겨주기)
    → 아이디 / 비밀번호 모두 입력되어야만 로그인 버튼 실행 ("로그인 성공" 토스트 메시지 출력)
    → 아이디 / 비밀번호 중 하나라도 비어 있다면 "아이디 / 비밀번호를 확인해주세요" 토스트 메시지 출력
    → 회원가입 버튼을 누르면 SignUpActivity 실행
    → 비밀번호 EditText는 입력 내용이 가려지게 하기
  • 회원가입 페이지(SignUpActivity)
    → 이름, 아이디, 비밀번호 모두 입력 됐을 경우에만 회원가입 버튼이 클릭가능
    → 셋 중 하나라도 비어 있다면 "입력되지 않은 정보가 있습니다" 토스트 메시지 출력
    → 비밀번호 EditText는 입력 내용이 가려지게 하기
    → 회원가입 버튼이 눌리면 SignInActivity로 이동하기
    회원가입 페이지에서 입력한 아이디 / 비밀번호가 로그인 화면으로 돌아올 때 자동 입력되게 만들기
    (registerForActivityResult 활용)

  • 자기소개 페이지(HomeActivtiy)
    → SignInActivity에서 받은 extra data(아이디)를 화면에 표시하기
    자기소개 페이지가 시작될 때 보이는 ImageView를 5장의 랜덤 이미지로 보이게 하기
    → 종료 버튼이 눌리면 SignInActivity로 이동하기 (finish 활용)

 

 

activity_signin.xml

더보기
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SignInActivity">

    <ImageView
        android:id="@+id/iv_signInLogo"
        android:layout_width="150dp"
        android:layout_height="150dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.15"
        android:src="@drawable/lv2" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="30dp"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/iv_signInLogo">

        <TextView
            android:id="@+id/tv_id"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="아이디"
            android:textSize="20sp"
            android:textStyle="bold"
            android:typeface="monospace"/>

        <EditText
            android:id="@+id/et_id"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="아이디를 입력하세요."
            android:inputType="text"
            android:textSize="15sp"
            android:textStyle="italic" />

        <TextView
            android:id="@+id/tv_pw"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="비밀번호"
            android:textSize="20sp"
            android:textStyle="bold"
            android:typeface="monospace"/>

        <EditText
            android:id="@+id/et_pw"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="비밀번호를 입력하세요."
            android:inputType="textPassword"
            android:textSize="15sp"
            android:textStyle="italic" />

        <Button
            android:id="@+id/btn_login"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="40dp"
            android:text="로그인"
            android:textSize="18dp"
            android:textStyle="bold" />

        <Button
            android:id="@+id/btn_signUp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:text="회원가입"
            android:textSize="18dp"
            android:textStyle="bold" />


    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

로그인 페이지의 레이아웃

 

activity_sign_up.xml

더보기
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SignUpActivity">

    <ImageView
        android:id="@+id/iv_signInLogo"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:src="@drawable/lv2"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.15"
        tools:srcCompat="@tools:sample/avatars" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="30dp"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/iv_signInLogo">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="이름"
            android:textSize="20dp"
            android:textStyle="bold"
            android:typeface="monospace"/>

        <EditText
            android:id="@+id/et_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="이름을 입력하세요."
            android:inputType="text"
            android:textSize="15sp"
            android:textStyle="italic"
            android:layout_marginBottom="20dp" />

        <TextView
            android:id="@+id/tv_id"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="아이디"
            android:textSize="20sp"
            android:textStyle="bold"
            android:typeface="monospace"/>

        <EditText
            android:id="@+id/et_id"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="아이디를 입력하세요."
            android:inputType="text"
            android:textSize="15sp"
            android:textStyle="italic" />

        <TextView
            android:id="@+id/tv_pw"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="비밀번호"
            android:textSize="20sp"
            android:textStyle="bold"
            android:typeface="monospace"/>

        <EditText
            android:id="@+id/et_pw"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="비밀번호를 입력하세요."
            android:inputType="textPassword"
            android:textSize="15sp"
            android:textStyle="italic" />

        <Button
            android:id="@+id/btn_signUpConfirm"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp"
            android:text="회원가입"
            android:textSize="18dp"
            android:textStyle="bold" />

    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

회원가입 페이지의 레이아웃

activity_home.xml

더보기
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".HomeActivity">

    <ImageView
        android:id="@+id/iv_signInLogo"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:src="@drawable/lv2"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.15" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="40dp"
        android:orientation="vertical"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/iv_signInLogo">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_margin="15dp"
            android:gravity="center_horizontal">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:text="아이디 : "
                android:textSize="20dp"
                android:textStyle="bold"
                android:typeface="monospace"/>

            <TextView
                android:id="@+id/tv_userId"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:text=""
                android:textSize="20dp"
                android:textStyle="bold"
                android:typeface="monospace" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_margin="15dp"
            android:gravity="center_horizontal">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:text="이름 : "
                android:textSize="20dp"
                android:textStyle="bold"
                android:typeface="monospace"/>

            <TextView
                android:id="@+id/tv_userName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:text="유영국"
                android:textSize="20dp"
                android:textStyle="bold"
                android:typeface="monospace" />
        </LinearLayout>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="15dp"
            android:layout_gravity="center_horizontal"
            android:text="나이 : 26"
            android:textSize="20dp"
            android:textStyle="bold"
            android:typeface="monospace"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="15dp"
            android:layout_gravity="center_horizontal"
            android:text="MBTI : INFP"
            android:textSize="20dp"
            android:textStyle="bold"
            android:typeface="monospace"/>

        <Button
            android:id="@+id/btn_finish"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp"
            android:text="종료"
            android:textSize="18dp"
            android:textStyle="bold" />


    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

자기소개 페이지의 레이아웃

 

SignInActivity

더보기
package com.android.ex4_makepage

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts

class SignInActivity : AppCompatActivity() {

    // ActivityResultLauncher 자료형인 getResult 변수를 전역 변수로 선언
    private lateinit var getResult: ActivityResultLauncher<Intent>

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_signin)

        // 아이디, 비밀번호 각 EditText랑 연결
        val user_Id = findViewById<EditText>(R.id.et_id)
        val user_Pw = findViewById<EditText>(R.id.et_pw)

        // 버튼 코드에 연결
        val btn_login = findViewById<Button>(R.id.btn_login)
        val btn_signup = findViewById<Button>(R.id.btn_signUp)

        // 만들어준 변수 getResult에 registerForActivityResult 메서드를 활용해서
        // ActivityLauncher를 생성
        getResult = registerForActivityResult(
            ActivityResultContracts.StartActivityForResult()
        ) { result ->
            // SignUpActivity로 부터 돌아올 때의 결과 값을 받아 올 수 있는 구문
            if (result.resultCode == RESULT_OK) {
                val userId = result.data?.getStringExtra("userId") ?: ""
                val userPw = result.data?.getStringExtra("userPw") ?: ""

                // EditText에 .text를 사용하면 TypeMismatch 에러가 발생하므로 .SetText()
                user_Id.setText(userId)
                user_Pw.setText(userPw)
            }
        }

        btn_login.setOnClickListener {
            // 액티비티 전환 명시적 인텐트
            val intent = Intent(this, HomeActivity::class.java)

            // 입력받은 아이디, 비밀번호 데이터 값
            val userId_Data = user_Id.text.toString()
            val userPw_Data = user_Pw.text.toString()

            // 입력받은 아이디의 키-밸류 인텐트(HomeActivity로)
            intent.putExtra("id_DataFromSignInActivity", userId_Data)

            // 아이디나 비밀번호에 값이 없을 경우엔 토스트 외 반응x
            if (userId_Data.isEmpty() || userPw_Data.isEmpty()) {
                Toast.makeText(applicationContext, "아이디/비밀번호를 확인해주세요", Toast.LENGTH_SHORT).show()
            } else {
                Toast.makeText(applicationContext, "로그인 성공", Toast.LENGTH_SHORT).show()
                startActivity(intent)
            }
        }

        // 회원가입 버튼 클릭 시 SignUpActivity로 전환해주는 인텐트
        btn_signup.setOnClickListener {
            val intent = Intent(this, SignUpActivity::class.java)
            // launch는 startActivity와 동일한 기능
            getResult.launch(intent)
        }
    }
}

로그인 페이지 코드

SignUpActivity

더보기
package com.android.ex4_makepage

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.Toast

class SignUpActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_sign_up)

        // 회원가입 버튼 연결
        val btn_SignUp = findViewById<Button>(R.id.btn_signUpConfirm)

        btn_SignUp.setOnClickListener {
            // 이름, 아이디, 비밀번호 각 EditText와 연결
            val user_Name = findViewById<EditText>(R.id.et_name)
            val user_Id = findViewById<EditText>(R.id.et_id)
            val user_Pw = findViewById<EditText>(R.id.et_pw)

            // 이름, 아이디, 비밀번호 데이터 값
            val userName_Data = user_Name.text.toString()
            val userId_Data = user_Id.text.toString()
            val userPw_Data = user_Pw.text.toString()

            // 이름, 아이디, 비밀번호 값이 없을 경우엔 토스트 외 반응x
            if (userName_Data.isEmpty() || userId_Data.isEmpty() || userPw_Data.isEmpty()) {
                Toast.makeText(applicationContext, "입력되지 않은 정보가 있습니다", Toast.LENGTH_SHORT).show()
            } else {
                // 다 적었으면 finish()로 SignInActivity화면으로 돌아간다
                Toast.makeText(applicationContext, "회원가입 완료!", Toast.LENGTH_SHORT).show()

                // 아이디와 비밀번호 SignInActivity 인텐트 구문
                val intent = Intent(this, SignInActivity::class.java)
                intent.putExtra("userId", userId_Data)
                intent.putExtra("userPw", userPw_Data)
                setResult(RESULT_OK, intent)

                finish()
            }
        }
    }
}

회원가입 페이지 코드

HomeActivity

더보기
package com.android.ex4_makepage

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import kotlin.random.Random

class HomeActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_home)

        // TextView 연결
        val user_Id = findViewById<TextView>(R.id.tv_userId)

        // ImageView 연결
        val profileImage = findViewById<ImageView>(R.id.iv_signInLogo)

        // profileImage를 랜덤 출력
        when (Random.nextInt(1, 6)) {
            1 -> profileImage.setImageResource(R.drawable.lv1)
            2 -> profileImage.setImageResource(R.drawable.lv2)
            3 -> profileImage.setImageResource(R.drawable.lv3)
            4 -> profileImage.setImageResource(R.drawable.lv4)
            5 -> profileImage.setImageResource(R.drawable.lv5)
        }

        // 아이디 인텐트 받아오기
        val userId_Data = intent.getStringExtra("id_DataFromSignInActivity")

        // 받아온 인텐트 데이터로 TextView 설정
        user_Id.setText(userId_Data)

        // 종료버튼
        val btn_close = findViewById<Button>(R.id.btn_finish)
        btn_close.setOnClickListener {
            finish()
        }
    }
}

자기소개 페이지 코드

 

 

 

 




 

registerForActivityResult()의 활용

구현하려는 것 :  SignUpActivity ↔ SignInActivity 간 데이터 전달

 

사용한 방법

  1. ActivityResultLauncher 자료형인 getResult 변수를 전역변수로 선언
  2. getResult에 registerForActivityResult 메서드를 활용해서 ActivityLauncher를 만든다
    → registerForActivtyResult 메서드의 파라미터는 ActivityResultContract, ActivityResultCallback이 필요하다
    →  ActivityResultContract는 startActivityForResult 외에도 다양한 객체들이 있다
    →  ActivityResultCallback은 람다로 사용하고, ActivityResult 객체가 파라미터로 떨어지고 여기서 원하는 데이터를 가져오면 된다
    →  그 후 result.resultCode가 올바르게 넘어오면 B액티비티에서 넘겨준 이름과 나이를 getStringExtra로 받는다

  3. 만들어준 getResult.launch()를 통해 데이터를 받아올 Activity를 실행한다
  4. 데이터를 보내줄 Activity인 SignUpActivity에서 setResult를 등록해 준다

 

 

참고 자료 1

참고 자료 2

728x90