안드로이드 kotlin, xml 코드 리팩토링(1)

JINNI·2023년 10월 15일
0

💡 Text 하드코딩하지 않고 리소스화하기

TextView에 데이터를 설정할 때 아래와 같이 데이터 문자열을 그대로 작성해 넣었다.

<!-- activity_login.xml -->
<EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_marginEnd="20dp"
        android:minHeight="48dp"
        android:hint="아이디를 입력해주세요"
        android:textSize="18sp"
        android:layout_marginTop="30dp"
        android:layout_marginStart="20dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView2"
        android:layout_height="wrap_content" />

→ 하드코딩 경고가 발생, 유연성과 확장성 저하! strings.xml 파일을 만들어 리소스화!

<!-- strings.xml -->
<resources>
    <string name="tv_login_welcome">Welcome to SOPT</string>
    <string name="tv_login_id">ID</string>
    <string name="tv_login_pw">비밀번호</string>
    <string name="et_login_id_hint">아이디를 입력해주세요.</string>
    <string name="et_login_pw_hint">비밀번호를 입력해주세요.</string>
    <string name="btn_login_sing_in">로그인하기</string>
    <string name="btn_login_sign_up">회원가입</string>

    <string name="tv_mypage_name">이름</string>
    <string name="tv_mypage_id">ID</string>
    <string name="tv_mypage_id_info">admin</string>
    <string name="tv_mypage_mbti">MBTI</string>
    <string name="tv_mypage_mbti_info">ENFJ</string>

    <string name="tv_sign_up">SIGN UP</string>
    <string name="tv_sign_up_id">ID</string>
    <string name="tv_sign_up_pw">비밀번호</string>
    <string name="tv_sign_up_name">닉네임</string>
    <string name="tv_sign_up_mbti">MBTI</string>
    <string name="et_sign_up_id_hint">6글자 이상 10글자 이하로 입력해주세요.</sting>
    <string name="et_sign_up_pw_hint">8글자 이상 12글자 이하로 입력해주세요.</string>
    <string name="et_sign_up_name_hint">1글자보다 길어야 합니다.</string>
    <string name="et_sign_up_mbti_hint">MBTI를 입력해주세요.</string>
		<string name="btn_sign_up">회원가입하기</string>
</resources>
<!-- activity_sign_up.xml 중 일부 -->
<EditText
        android:id="@+id/MbtiText"
        android:layout_width="match_parent"
        android:minHeight="48dp"
        android:layout_marginEnd="20dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="25dp"
        android:layout_marginStart="20dp"
        android:hint="@string/et_sign_up_mbti_hint"
        android:textSize="18sp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/MbtiView" />

    <androidx.appcompat.widget.AppCompatButton
        android:id="@+id/btn_sign_up"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp"
        android:layout_marginStart="20dp"
        android:layout_marginEnd="20dp"
        android:text="@string/btn_sign_up"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"



💡 CTRL+ALT+L로 소스코드 정렬하기

Kotlin 파일 코드 스타일 커스텀!

Kotlin 파일 코드 스타일 커스텀

// 포맷팅 전
class LoginActivity : AppCompatActivity() {
    private lateinit var binding: ActivityLoginBinding
    lateinit var getResultID: ActivityResultLauncher<Intent> // 반환
    var getid : String = "000000"
    var getpw : String = "000000"
    var getname : String = "이름"
    var getmbti : String = "EEEE"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityLoginBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // ActivityResultLauncher 초기화, 결과값 이벤트 핸들러 정의
        getResultID = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){
            result ->
            if(result.resultCode == RESULT_OK){
                getid = result.data?.getStringExtra("idresult").toString()
                getpw = result.data?.getStringExtra("pwresult").toString()
                getname = result.data?.getStringExtra("name").toString()
                getmbti = result.data?.getStringExtra("mbti").toString()
            }
        }

// 포맷팅 후
class LoginActivity : AppCompatActivity() {
    private lateinit var binding: ActivityLoginBinding
    lateinit var getResultID: ActivityResultLauncher<Intent> // 반환
    var getid: String = "000000"
    var getpw: String = "000000"
    var getname: String = "이름"
    var getmbti: String = "EEEE"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityLoginBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // ActivityResultLauncher 초기화, 결과값 이벤트 핸들러 정의
        getResultID =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
                if (result.resultCode == RESULT_OK) {
                    getid = result.data?.getStringExtra("idresult").toString()
                    getpw = result.data?.getStringExtra("pwresult").toString()
                    getname = result.data?.getStringExtra("name").toString()
                    getmbti = result.data?.getStringExtra("mbti").toString()
                }
            }



💡 알아보기 쉬운 이름 설정하기! 네이밍 컨벤션 지키도록 수정

✅ id의 기본적인 네이밍 규칙
  • view_where_description 형태로 작성
  • 레이아웃 주요 구성요소 이름
    - Button - btn
    - EditText - et
    - TextView - tv
    - Menu - mnu

shift+F6을 이용해 연결된 변수명까지 한번에 수정할 수 있다.

→ xml 파일 내부에서만 변경되어서 kotlin 파일은 하나하나 수정해주었다.

// SignUpActivity.kt
// 수정 전
        binding.btnSignUp.setOnClickListener {
            val testResult = testInfo()

            if (testResult) { 
                val intent = Intent(this, LoginActivity::class.java)
                intent.putExtra("idresult", binding.editText.text.toString())
                intent.putExtra("pwresult", binding.editText2.text.toString())
                intent.putExtra("mbti", binding.MbtiText.text.toString())
                intent.putExtra("name", binding.nameText.text.toString())
                Snackbar.make(
                    binding.root,
                    "회원가입 성공!",
                    Snackbar.LENGTH_SHORT
                ).show()
                setResult(RESULT_OK, intent)
                finish()
            }

// 수정 후
        binding.btnLoginIdSignUp.setOnClickListener {
            val testResult = testInfo() // 조건 검사 결과를 저장

            if (testResult) { // 조건이 적절한 경우
                val intent = Intent(this, LoginActivity::class.java)
                intent.putExtra("idresult", binding.etLoginIdIdHint.text.toString())
                intent.putExtra("pwresult", binding.etLoginIdPwHint.text.toString())
                intent.putExtra("mbti", binding.etSignUpIdMbtitext.text.toString())
                intent.putExtra("name", binding.etSignUpIdNametext.text.toString())
                Snackbar.make(
                    binding.root,
                    "회원가입 성공!",
                    Snackbar.LENGTH_SHORT
                ).show()
                setResult(RESULT_OK, intent)
                finish()
            }



💡 @+와 @ 자동완성

@+는 새로 선언하는 리소스 아이디, @는 이미 추가된 리소스 아이디를 참조하겠다는 의미

자동완성으로 인해 제약을 걸 때 @로 써야할 것이 @+로 작성되는 경우가 많다.

하지만 정상적으로 작동하기 때문에 문제의식을 갖지 못하지만 깔끔한 코드를 위해 수정이 필요함!

<!-- 수정 전 -->
		<TextView
        android:id="@+id/tv_mypage_id_name"
        ~
        app:layout_constraintBottom_toTopOf="@+id/tv_mypage_id_user_id"
        ~
        app:layout_constraintTop_toBottomOf="@+id/img_mypage_id_profile" />

    <TextView
        android:id="@+id/tv_mypage_id_user_id"
        ~
        app:layout_constraintTop_toBottomOf="@+id/tv_mypage_id_name" />

		<TextView
        android:id="@+id/tv_mypage_id_user_id_content"
        ~
        app:layout_constraintTop_toBottomOf="@+id/tv_mypage_id_user_id" />

<!-- 수정 후 -->
		<TextView
        android:id="@+id/tv_mypage_id_name"
        ~
        app:layout_constraintBottom_toTopOf="@id/tv_mypage_id_user_id"
        ~
        app:layout_constraintTop_toBottomOf="@id/img_mypage_id_profile" />

    <TextView
        android:id="@+id/tv_mypage_id_user_id"
        ~
        app:layout_constraintTop_toBottomOf="@id/tv_mypage_id_name" />

		<TextView
        android:id="@+id/tv_mypage_id_user_id_content"
        ~
        app:layout_constraintTop_toBottomOf="@id/tv_mypage_id_user_id" />



💡 하나의 액션, 하나의 커밋!

✅ 커밋 메시지는 ‘{#이슈 번호} [타입] 작업 내용’ 으로 작성할 것!
커밋은 잘게 쪼개서 기능별로 진행





앞으로 공부해보고 적용해볼 개념

  • Companion object의 이해와 이를 이용한 코드 리팩토링!
  • 가독성 향상을 위한 기능별 함수화
  • 관련 activity를 auth 폴더 등으로 묶는 방법?
  • intent 반복을 피하기 위한 scope function
  • 여러 개의 view에서 공통적으로 사용되는 함수를 위한 새로운 파일 속 확장 수
  • match_parent보다 0dp가 권장되는 이유?
  • AndroidManifest.xml에서 exported = true? false?
  • with 함수란?
  • 상하좌우 같은 마진값을 쓰는 경우 marginHorizontal, marginVertical 사용하기
  • tools의 적용
  • 이미지 비율을 나타낼 수 있는 constraintDimensionRatio 이용
profile
천재 개발자 되기

0개의 댓글