본문 바로가기
카테고리 없음

회고록의 진행[생존 이야기]

by 덩얼이 2023. 8. 4.
반응형

개인 프로젝트

이번 개인 프로젝트는 안드로이드 스튜디오를 적절하게 활용하게 되는 기초적인 프로젝트이다.

발제 내용인데 레이아웃을 직접 그려가며 기초적인 내용들을 다루는 개인 프로젝트인것 같다. 알고리즘 문제들도 풀고 있는데 어느정도 풀렸으면 카테고리를 따로 빼서 다뤄볼 예정이다. 지금은 전체적인 공부의 내용만 담고 있는데 여러 카테고리를 만들어야겠다.

 

• Lv1 로그인 화면을 구현

• Lv2 회원가입 페이지 만들기

• Lv3 프로필 홈 화면 만들기

이렇게 총 3단계까지 구현하는게 있다. 발제에서 디자인 틀이랑 엑티비티 이름까지 설정해줘서 따라만 하면? 어려울게 없는 개인 과제이다.

그럼 지금부터 내가 구현한것과 코드를을 살펴보자.

 

Lv1

 

Lv1에 만족하는 로그인 페이지이다. 로그인의 기능을 사용하기 위해서는 DB가 필요하긴하지만 안드로이드 기본적으로 제공되는 기능인 Intent로 데이터를 액티비티 전환을 할때 입력한 데이터를 넘겨주는 putExtra를 사용해서 데이터를 넘겨주는 기능을 한다. 각각의 버튼들에는 이름을 써줘서 데이터를 받았을때 객체화를 시켜줄수 있게 이름을 지정해준다. 레이아웃은 이렇게 두개의 리니어 레이아웃을 적용해서

프로필은 위에 아래는 입력할수있는 텍스트뷰와 버튼을 배치했다.

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SignInActivity"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0.5"
        android:orientation="vertical"
        >
    <ImageView
        android:id="@+id/imageView2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scaleType="fitXY"
        android:src="@drawable/flog"
        android:background="@drawable/circle_background"
        android:clipToOutline="true"
        />

    </LinearLayout>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="아이디"
        android:paddingLeft="20dp"
        android:textSize="25dp"/>

    <EditText
        android:id="@+id/in_id1"
        android:layout_width="300dp"
        android:layout_height="wrap_content"
        android:hint="ID"
        android:layout_gravity="center"
        android:inputType="text"
        android:textSize="10pt"
        android:textStyle="italic" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="20dp"
        android:text="비밀번호"
        android:textSize="25dp"/>

    <EditText
        android:id="@+id/in_pw1"
        android:layout_width="300dp"
        android:layout_height="wrap_content"
        android:hint="Password"
        android:layout_gravity="center"
        android:inputType="textPassword"
        android:textSize="10pt"
        android:textStyle="italic"
        />


    <Button
        android:id="@+id/button3"
        android:layout_width="250dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="로그인"
        />

    <Button
        android:id="@+id/button4"
        android:layout_width="250dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="화원가입" />

    <Space
        android:layout_width="match_parent"
        android:layout_height="50dp" />

</LinearLayout>

로그인 페이지의 XML 코드이다. 이미지뷰를 원으로 만드는 방법을 여러가지를 검색해 봤었는데 종속성을 넣어서 하는 방법도 있었는데 이는 코틀린말고 자바일때 적용되는것 같다..

이렇게 Circle 이미지뷰 라는 기능으로 종속성을 해주고

 <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/circle_iv"
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:layout_gravity="center"
        android:background="@android:color/transparent"
        app:civ_border_overlay="true"
        app:civ_border_width="5dp"
        app:civ_border_color="#000000"
        android:src="@drawable/test_img"
        />

이렇게 CircleImageView로 사용하는 방법이 있었는데 오류도 엄청 뜨고 적용 자체가 안되는 문제를 발견하였다. 삽을 파던 와중에 검색을 잘못했나? 라는 생각도 들었고 더 찾아보던 와중에 그냥 XML 파일 하나 추가해주면 백그라운드로 원형을 적용할 수 있는 방법을 찾았다!

방법은 drawable 파일 안에 xml 파일을 만들어주고 이미지뷰에서 불러서 사용하는 방법인데 다음과 같다.

 

circle_background.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid android:color="@android:color/transparent" />
    <stroke
        android:width="20dp"
        android:color="@android:color/white" />
</shape>

 

이렇게 drawable 파일안에 xml 파일을 만들어준다음 코드를 보면 이렇게 원형이띠의 형태의 그림이 그려지게된다.

  <ImageView
        android:id="@+id/imageView2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scaleType="fitXY"
        android:src="@drawable/flog"
        android:background="@drawable/circle_background"
        android:clipToOutline="true"
        />

그리고 다음과 같이 background를 적용 시켜주면 사진의 크기를 조절하면서 여백을 없애고 백그라운드로 원형지게 바꿀수 있는데 이부분에 대해서는 삽을 좀 많이 팠던 부분이였다.. 그래도 해결 했으니 다음으로 넘어가는 식으로 진행하였다. 여기까지가 Lv1의 했던 내용과 내가 삽을 판 부분이다..

 

Lv2

두번째 구현은 회원가입 페이지 만들기이다. 사실 페이지 만들기는 하나만 만들어 놓으면 복붙으로 처리해서 두번째 화면을 만들때는 시간이 더욱 빨라진다. 처음에 했던 로그인 페이지를 그대로 복붙해서 내가 쓸 것과 뺄것을 적용하면 끝이다. 사진으로 알아보자.

이렇게 그대로 끌어와서 회원가입에 필요한 텍스트뷰를 수정해주면 사실 끝이고 이미지 사진은 drawable에 저장해서 불러서 쓰면 그만인 부분이다. 실제로 코드를 살펴보면 비슷하다.

 

Sigup.xml

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SignInActivity"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0.5"
        android:orientation="vertical"
        >

    <ImageView
        android:id="@+id/img_pro1"
        android:layout_width="322dp"
        android:layout_height="300dp"
        android:layout_gravity="center"
        android:src="@drawable/ddi"
        android:background="@drawable/circle_background"
        android:clipToOutline="true"
        />
    </LinearLayout>

    <!--<ImageView
        android:id="@+id/imageView2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:paddingTop="10dp"
        android:scaleType="fitXY"
        android:src="@drawable/flog" />-->



    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0.5"
        android:orientation="vertical"
        >

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="이름"
        android:paddingLeft="60dp"
        android:textSize="20dp"/>

    <EditText
        android:id="@+id/in_name"
        android:layout_width="300dp"
        android:layout_height="wrap_content"
        android:hint="이름"
        android:layout_gravity="center"
        android:inputType="text"
        android:textSize="8pt"
        android:textStyle="italic" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="61dp"
        android:text="아이디"
        android:textSize="20dp"/>

    <EditText
        android:id="@+id/in_id"
        android:layout_width="300dp"
        android:layout_height="wrap_content"
        android:hint="ID"
        android:layout_gravity="center"
        android:inputType="text"
        android:textSize="8pt"
        android:textStyle="italic"
        />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="비밀번호"
        android:paddingLeft="60dp"
        android:textSize="20dp"/>

    <EditText
        android:id="@+id/in_pw"
        android:layout_width="300dp"
        android:layout_height="wrap_content"
        android:hint="Password"
        android:layout_gravity="center"
        android:inputType="textPassword"
        android:textSize="8pt"
        android:textStyle="italic" />



    <Button
        android:id="@+id/btn_sig"
        android:layout_width="250dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="화원가입" />

    <!--<Space
        android:layout_width="match_parent"
        android:layout_height="50dp" />-->

    </LinearLayout>

</LinearLayout>

실제로 이렇게 Lv1과 코드가 유사한 부분이 많고 원형 이미지 뷰를 만들때 삽판 부분이 그대로 있는걸 볼 수가 있다. 다음으로는 액티비티 코드를 살펴보며 어떻게 연결이 되었는지 알아보자

 

SigupActivity

package com.example.myself

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
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 editName = findViewById<EditText>(R.id.in_name)
        val editId = findViewById<EditText>(R.id.in_id)
        val editPassword = findViewById<EditText>(R.id.in_pw)
        val btnSignUp = findViewById<Button>(R.id.btn_sig)


        btnSignUp.setOnClickListener {
            val id = editId.text.toString()
            val password = editPassword.text.toString()
            val name = editName.text.toString()

            if (name.isNotEmpty() && id.isNotEmpty() && password.isNotEmpty()) {
                // 회원가입 성공
                Toast.makeText(this, "회원가입 성공", Toast.LENGTH_SHORT).show()
                val intent = Intent(this, SignInActivity::class.java)
                intent.putExtra("userid",id)
                intent.putExtra("userpassward",password)
                intent.putExtra("username",name)
                startActivity(intent)
                //finish()
            } else {
                // 입력되지 않은 정보가 있음
                Toast.makeText(this, "입력되지 않은 정보가 있습니다.", Toast.LENGTH_SHORT).show()
            }
        }
    }
}

각각의 버튼들에 이름을 붙여서 이름으로 사용하게 구현을 하였고 회원가입 버튼을 눌렀을때 발생하는 이벤트는 클릭 리스너로 구현을 하였다. if문으로 하나라도 비어있는 텍스트뷰가 있으면 입력되지 않은 정보가 있다라고 토스 메시지를 띄워주는 부분도 함께있다. 

여기서 전 포스팅에서 다뤘던 Intent를 활용해서 화면을 넘길때 입력된 데이터도 같이 넘어가는 부분을 구현을 해주었는데 putExtra()를 이용하여 데이터를 넘길 이름과 if문에 사용된 이름으로 데이터를 넘겨주게 된다.  이쪽 부분은 어려운게 없다.

코드를 간단히 설명하자면 왜 데이터를 넘기느냐 라고 생각할 수 있는데 이는 회원가입을 하고 회원가입 버튼을 눌렀을때 로그인 창에서 다시 아이디와 비번을 입력할 필요없이 회원가입했던 데이터를 그대로 넘겨서 바로 로그인 할 수 있는 부분이다. 

다음으로 마지막인 프로필 페이지를 살펴보자

Lv3

페이지를 여러개 만들때는 전에 만들어 놓았던 xml을 복사해서 붙여넣기 한다음 내가 필요한 부분만 살리고 필요없는 부분은 삭제해주는것이 유용하게 쓰인다.

기본적인 레이아웃이다. 이렇게 보면 프로필 사진은 어디있고 그 아래 요소들은 왜 비어있냐 라고 생각 할 수 있겠지만 각 요소 하나하나에 id를 달아주었기 때문에 코드 상에서 수정을 할 수 있는것이다. 빠르게 코드로 알아보자

 

home.xml

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".HomeActivity"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="vertical"
        >

        <ImageView
            android:id="@+id/p_main"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:scaleType="fitXY"
            android:src="@mipmap/ic_launcher_round" />


    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="vertical"
        >


        <Space
            android:layout_width="match_parent"
            android:layout_height="50dp" />

        <TextView
            android:id="@+id/bl_id"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:autoSizeTextType="uniform"
            android:layout_gravity="center"
            android:paddingLeft="61dp"
            android:text="아이디 :"
            android:textSize="20dp"/>

        <TextView
            android:id="@+id/bl_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="이름 :"
            android:paddingLeft="60dp"
            android:textSize="20dp"/>





        <TextView
            android:id="@+id/bl_age"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="나이 : "
            android:paddingLeft="60dp"
            android:textSize="20dp"/>

        <TextView
            android:id="@+id/bl_mbti"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="MBTI : "
            android:paddingLeft="60dp"
            android:textSize="20dp"/>

        <Space
            android:layout_width="match_parent"
            android:layout_height="30dp" />


        <Button
            android:id="@+id/btn_end"
            android:layout_width="250dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="종료"
            android:textSize="20dp"/>



    </LinearLayout>
</LinearLayout>

이렇게 재사용이 가능한 부분이 있다. xml 파일을 만들어 줬다면 이제 액티비티의 코드를 살펴보자.

 

HomeActivity

package com.example.myself

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import org.w3c.dom.Text

class HomeActivity : AppCompatActivity() {
    //프로필 화일
    private lateinit var imageView: ImageView
    private val imageArray = arrayOf(
        R.drawable.main,
        R.drawable.dangdang,
        R.drawable.jeju,
        R.drawable.jejui1,
        R.drawable.seol

    )

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

        val tvUserId = findViewById<TextView>(R.id.bl_id)
        val userId = intent.getStringExtra("userId")
        tvUserId.text = "아이디 :$userId"

        val tvUserName = findViewById<TextView>(R.id.bl_name)
        /*val userName = intent.getStringExtra("username")*/
        tvUserName.text = "💻이름 :####"

        val tvUserAge = findViewById<TextView>(R.id.bl_age)
        tvUserAge.text = "🐰🐰나이 : 25"

        val tvUserMb = findViewById<TextView>(R.id.bl_mbti)
        tvUserMb.text = "💊MBTI : ISFJ"

        imageView = findViewById(R.id.p_main)
        setRandomImage()

        // 종료 버튼 클릭 시 SignInActivity로 이동
        findViewById<Button>(R.id.btn_end).setOnClickListener {
            setRandomImage()
            finish()
        }
    }

    private fun setRandomImage() {
        val randomIndex = (imageArray.indices).random()
        val randomImageResource = imageArray[randomIndex]
        imageView.setImageResource(randomImageResource)
    }
}

이렇게 각 버튼들의 내용을 여기서 입력해줄수가 있는것이고 이 부분은 액티비티 A -> B 로 Intent를 해서 데이터를 넘겨줄 수 있었는데 처음에 입력했을때 A->B->C 이렇게 한곳의 데이터를 Intent를 하는게 어려운 부분이 있어서 데이터를 두번 넘겨주기 위해서는 인터페이스나 다른걸 방법을 써야하지만 일단 이렇게 하나씩 만들어주어도 내 소개 어플이기 때문에 문제가 없다고 판단을 하였다.

그리고 xml부분에서 디자인을 보았을때 프로필 사진이 없는걸 확인할 수 있는데 

android:src="@mipmap/ic_launcher_round"

이렇게 디폴트로 되어있는 이미지를 연결해준다음 xml에 있는 사진을 코드상으로 종료 버튼을 누르면 이미지가 랜덤하게 뜰 수 있게 구현을 하였다.

private lateinit var imageView: ImageView
private val imageArray = arrayOf(
    R.drawable.main,
    R.drawable.dangdang,
    R.drawable.jeju,
    R.drawable.jejui1,
    R.drawable.seol

)

이렇게 사진을 arrayOf로 만들어준다음 랜덤 함수로 선언해주어서 사용할 수 있게 되었고 메스로 따로 빼서 구현을 해주었다.

그렇게 개인과제에 대해서 마무리를 하게 되었다. 요구했던 과정을 다 구현하였고 이제 알고리즘에 대해서 쭉 적어낼 예정이다.

 

마무리하며

아직 구현하면서 코드를 짤 때 깔끔하게는 못 하는것 같지만 일단 돌아가는것에 대해 의미를 둬야할것같다. 알고리즘에 대해서 다뤄보면서 코드에 대해서 깔끔하고 좋은 코드를 써야 할것 같다.!

반응형