회원가입 & 로그인 - 페이지 만들기

변현섭·2023년 8월 30일
0
post-thumbnail

이번 시리즈에서는 실시간 채팅 앱을 만들어보도록 하겠습니다. 저의 본업이 백엔드 개발이다보니, 서버가 있는 채팅 앱을 만들어보려 합니다. 참고로, 프론트엔드 코딩에는 Android Kotlin을, 백엔드 코딩에는 Java Spring을 사용할 것이며, 서버는 EC2, 데이터베이스는 RDS, 이미지 저장에는 S3를 사용하도록 하겠습니다. 코드에 대한 별도의 설명 없이 구현 코드만 보여드릴 예정이며, 구현 코드는 아래의 깃허브 링크에서도 확인하실 수 있습니다.
>> 프론트엔드 깃허브 링크
>> 백엔드 깃허브 링크

이번 포스팅에서는 스플래시 화면, 회원가입, 로그인 페이지를 만들어보도록 하겠습니다.

1. 스플래시 화면 구성하기

1) SplashActivity

① chatting app이라는 이름으로 프로젝트를 생성한다.

② default 패키지 하위로, SplashActivity와 IntroActivity를 추가한다.

③ SplashActivity에 아래의 내용을 입력한다.

@Suppress("DEPRECATION")
class SplashActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_splash)

        Handler().postDelayed({
            startActivity(Intent(this, IntroActivity::class.java))
            finish()
        }, 3000)
    }
}

④ Splash 화면이 가장 먼저 나타날 수 있도록, AndroidManifest.xml 파일의 activity 컨테이너를 수정한다.

<activity
    android:name=".IntroActivity"
    android:exported="false" />
    
<activity
    android:name=".SplashActivity"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<activity
    android:name=".MainActivity"
    android:exported="true">
</activity>

⑤ 스플래시 화면에 사용할 말풍선 아이콘을 splash라는 이름으로 drawable 패키지에 추가한다.

⑥ 하늘색을 main color로 사용하기 위해 values > colors.xml 파일에 아래의 내용을 추가한다.

<color name="skyBlue">#B8F8FB</color>

⑦ activity_splash.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"
    android:background="@color/skyBlue"
    tools:context=".SplashActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="120dp"
        android:text="U &amp; I TALK"
        android:textColor="@color/black"
        android:textSize="60sp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:layout_width="350dp"
        android:layout_height="350dp"
        android:layout_marginBottom="80dp"
        android:src="@drawable/splash"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

2) IntroActivity

activity_intro.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"
    android:background="@color/skyBlue"
    tools:context=".IntroActivity">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        android:gravity="center"
        android:text="너와 나의 채팅공간,\n\nU &amp; I TALK"
        android:textSize="40sp"
        android:textStyle="bold"
        android:textColor="#000000"
        app:layout_constraintTop_toTopOf="parent"
        tools:layout_editor_absoluteX="15dp" />

    <ImageView
        android:layout_width="250dp"
        android:layout_height="250dp"
        android:src="@drawable/splash"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="250dp"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.93"
        tools:layout_editor_absoluteX="9dp">

        <Button
            android:id="@+id/join"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="15dp"
            android:background="@color/black"
            android:text="회원 가입"
            android:textColor="@color/white"
            android:textSize="20sp"
            android:textStyle="bold" />

        <Button
            android:id="@+id/login"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="15dp"
            android:background="@color/black"
            android:text="로그인"
            android:textColor="@color/white"
            android:textSize="20sp"
            android:textStyle="bold" />

    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

2. 회원가입 페이지 만들기

① default 패키지 하위로, authentication이라는 패키지를 생성한다.

② authentication 패키지 하위로 JoinActivity를 생성한다.

③ IntroActivity 파일에 아래의 내용을 입력한다.

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

        val joinBtn = findViewById<Button>(R.id.join)
        joinBtn.setOnClickListener {
            val intent = Intent(this, JoinActivity::class.java)
            startActivity(intent)
        }
    }
}

④ 프로필 이미지를 나타낼 사진을 drawable 디렉토리 하위에 profile이라는 이름의 파일을 추가한다.

⑤ 어플리케이션의 main color인 하늘색으로 된 테두리를 만들자. drawable 디렉토리 하위로, main_border 리소스 파일을 생성한다.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item>
        <shape android:shape="rectangle">
            <solid android:color="@color/skyBlue" />
        </shape>

    </item>

    <item android:top = "3dp"
        android:right= "3dp"
        android:left="3dp"
        android:bottom="3dp">

        <shape android:shape="rectangle">
            <solid android:color="#ffffff" />
        </shape>

    </item>

</layer-list>

⑥ 버튼의 색이 적용되지 않는 문제를 해결하기 위해 res > values > themes > (night 안 쓰여있는) themes.xml 파일의 3번째 줄을 아래와 같이 수정한다.

<style name="Base.Theme.ChattingApp" parent="Theme.AppCompat.Light">

⑦ activity_join.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"
    android:background="@color/white"
    tools:context=".authentication.JoinActivity">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
            <androidx.constraintlayout.widget.ConstraintLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <ImageView
                    android:layout_width="150dp"
                    android:layout_height="150dp"
                    android:src="@drawable/splash"
                    android:layout_marginTop="10dp"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent" />

            </androidx.constraintlayout.widget.ConstraintLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="닉네임"
                    android:layout_marginHorizontal="40dp"
                    android:layout_marginTop="10dp"
                    android:layout_marginBottom="5dp"
                    android:textStyle="bold"
                    android:textColor="#000000"
                    android:textSize="20sp"/>

                <com.google.android.material.textfield.TextInputLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginHorizontal="40dp"
                    android:layout_marginBottom="10dp">

                    <com.google.android.material.textfield.TextInputEditText
                        android:id="@+id/nickname"
                        android:hint="nickname"
                        android:padding="5dp"
                        android:background="@drawable/main_border"
                        android:textColorHint="#808080"
                        android:textSize="25sp"
                        android:layout_width="match_parent"
                        android:layout_height="40dp"/>

                </com.google.android.material.textfield.TextInputLayout>

            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="이메일"
                    android:layout_marginHorizontal="40dp"
                    android:layout_marginTop="10dp"
                    android:layout_marginBottom="5dp"
                    android:textStyle="bold"
                    android:textColor="#000000"
                    android:textSize="20sp"/>

                <com.google.android.material.textfield.TextInputLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginHorizontal="40dp"
                    android:layout_marginBottom="10dp">

                    <com.google.android.material.textfield.TextInputEditText
                        android:id="@+id/joinEmail"
                        android:hint="email"
                        android:padding="5dp"
                        android:background="@drawable/main_border"
                        android:textColorHint="#808080"
                        android:textSize="25sp"
                        android:layout_width="match_parent"
                        android:layout_height="40dp"/>

                </com.google.android.material.textfield.TextInputLayout>

            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="비밀번호"
                    android:layout_marginHorizontal="40dp"
                    android:layout_marginTop="10dp"
                    android:layout_marginBottom="5dp"
                    android:textStyle="bold"
                    android:textColor="#000000"
                    android:textSize="20sp"/>

                <com.google.android.material.textfield.TextInputLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginHorizontal="40dp"
                    android:layout_marginBottom="10dp"
                    app:counterMaxLength="12"
                    app:counterEnabled="true">

                    <com.google.android.material.textfield.TextInputEditText
                        android:id="@+id/joinPassword"
                        android:hint="password"
                        android:padding="5dp"
                        android:background="@drawable/main_border"
                        android:textColorHint="#808080"
                        android:textSize="25sp"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:inputType="textPassword" />

                </com.google.android.material.textfield.TextInputLayout>


            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="비밀번호 확인"
                    android:layout_marginHorizontal="40dp"
                    android:layout_marginTop="10dp"
                    android:layout_marginBottom="5dp"
                    android:textStyle="bold"
                    android:textColor="#000000"
                    android:textSize="20sp"/>

                <com.google.android.material.textfield.TextInputLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginHorizontal="40dp"
                    android:layout_marginBottom="10dp"
                    app:counterMaxLength="12"
                    app:counterEnabled="true">

                    <com.google.android.material.textfield.TextInputEditText
                        android:id="@+id/passwordChk"
                        android:hint="password check"
                        android:padding="5dp"
                        android:background="@drawable/main_border"
                        android:textColorHint="#808080"
                        android:textSize="25sp"
                        android:layout_width="match_parent"
                        android:layout_height="40dp"
                        android:inputType="textPassword" />

                </com.google.android.material.textfield.TextInputLayout>


            </LinearLayout>

            <Button
                android:id="@+id/joinBtn"
                android:text="회원가입"
                android:textSize="30sp"
                android:textStyle="bold"
                android:gravity="center"
                android:layout_margin="30dp"
                android:background="@color/skyBlue"
                android:layout_width="match_parent"
                android:layout_height="50dp"/>

        </LinearLayout>

    </ScrollView>

</androidx.constraintlayout.widget.ConstraintLayout>

⑧ 타이틀 바를 없애기 위해 themes.xml 파일의 style 컨테이너 안에 아래와 같이 item 컨테이너를 추가하자.

<style name="Base.Theme.ChattingApp" parent="Theme.AppCompat.Light">
    <!-- Customize your light theme here. -->
    <!-- <item name="colorPrimary">@color/my_light_primary</item> -->
    <item name="windowNoTitle">true</item>
</style>

3. 로그인 페이지 만들기

① authentication 패키지 하위로 LoginActivity를 생성한다.

② IntroActivity 파일에 로그인 버튼에 대한 클릭 이벤트 리스너를 추가한다.

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

        val joinBtn = findViewById<Button>(R.id.join)
        joinBtn.setOnClickListener {
            val intent = Intent(this, JoinActivity::class.java)
            startActivity(intent)
        }

        val loginBtn = findViewById<Button>(R.id.login)
        loginBtn.setOnClickListener {
            val intent = Intent(this, LoginActivity::class.java)
            startActivity(intent)
        }
    }
}

③ activity_login.xml 파일에 아래의 내용을 입력한다.

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
    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"
    android:background="@color/white"
    tools:context=".authentication.LoginActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <ImageView
                android:layout_width="250dp"
                android:layout_height="250dp"
                android:src="@drawable/splash"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                android:layout_marginTop="40dp"/>

        </androidx.constraintlayout.widget.ConstraintLayout>


        <com.google.android.material.textfield.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginHorizontal="40dp"
            android:layout_marginTop="40dp">

            <com.google.android.material.textfield.TextInputEditText
                android:id="@+id/email"
                android:hint="email"
                android:padding="5dp"
                android:background="@drawable/main_border"
                android:textSize="25sp"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>

        </com.google.android.material.textfield.TextInputLayout>

        <com.google.android.material.textfield.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginHorizontal="40dp"
            android:layout_marginTop="20dp"
            app:counterMaxLength="12"
            app:counterEnabled="true">

            <com.google.android.material.textfield.TextInputEditText
                android:id="@+id/password"
                android:hint="password"
                android:padding="5dp"
                android:background="@drawable/main_border"
                android:textSize="25sp"
                android:inputType="textPassword"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>

        </com.google.android.material.textfield.TextInputLayout>

        <Button
            android:id="@+id/loginBtn"
            android:text="로그인"
            android:layout_marginTop="90dp"
            android:layout_marginHorizontal="40dp"
            android:background="@color/skyBlue"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

    </LinearLayout>
</ScrollView>

유저의 회원가입 및 로그인에 대한 처리는 다음 포스팅에서 다루기로 하자.

profile
Java Spring, Android Kotlin, Node.js, ML/DL 개발을 공부하는 인하대학교 정보통신공학과 학생입니다.

0개의 댓글