Skip to content

코딩 컨벤션

K056_차지원 edited this page Nov 8, 2021 · 6 revisions

안드로이드 컨벤션

데이터 바인딩

  • bindingAdapter는 안건 올리고 4인 동의 후 가능
  • 리사이클러 뷰 아이템의 데이터 클래스는 XxxItem, xml의 바인딩 변수는 item 사용

뷰 ID 네이밍

  • 기본 형식: [what]\_[where]\_[des] ex) tv_addCalendar_titleHeader
    • 섹션을 확실하게 구분할 수 있다.
    • 언더바로 구분되어 원하는 정보를 골라 읽기 편하다.
    • des를 읽을 때에는 구분해서 읽을 일이 없다.
  • 각 절에서 두 단어 이상이 혼용될 때는 camel case로 작성.
  • 카멜 케이스로 구분되지 않는 뷰(switch, toolbar, ...)는 풀 네임을 사용.
  • 접두사는 simple style(textView -> tv)
Prefix 풀네임
layout LinearLayout, ConstraintLayout,include ...
custom CustomView
tv TextView
bt Button
img ImageView
rv RecyclerView
cb CheckBox
cg CheckGroup
switch Switch
divider View
toolbar Toolbar
compose ComposeView

Drawable

참고: 헤이딜러 drawable 가이드

  • <WHAT>(_<WHERE>)_<DESCRIPTION>(_<SIZE>)
  • 이미지가 여러군데에서 활용될 경우, <WHERE>는 생략 가능하다.
  • 이미지의 크기가 1개밖에 없는 경우, <SIZE>는 생략 가능하다.

What

Prefix 설명
btn_ 버튼으로 쓰이는 이미지
ic_ 아이콘, 벡터에 사용하는 이미지
bg_ 버튼이 아닌 화면에 보여지는 이미지
img_ 실제사진이거나 아이콘형태가 아닌 일러스트형태의 이미지
div_ divider로 활용되는 이미지
color_ color selector

Selector

  • 배경이나 버튼에서 View의 상태에 따라서 drawable이 변해야 하는 경우에 대한 이름은 아래와 같다.
상태 Suffix
Normal _normal
Pressed _pressed
Focused _focused
Disabled _disabled
Selected _selected
Activated _activated

Background

  • 배경색이 pressed상태에 따라서 white -> sky_blue로 변하는 경우는 bg_white_to_sky_blue.xml로 한다.
  • 배경이 white색의 24dp로 테두리를 그리는 경우는 bg_white_radius_24dp.xml로 한다.
  • 배경이 투명하며 배경의 선만을 sky_blue색의 8dp로 테두리를 그리는 경우는 bg_stroke_sky_blue_radius_8dp.xml로 한다.

예시

  • btn_call_normal.png: 전화걸기 버튼 이미지
  • btn_call_pressed.png: 전화걸기 버튼 눌렸을때의 이미지
  • btn_call.xml: 전화걸기 버튼 이미지의 selector xml
  • ic_dealer_gift.png: 딜러가 보내준 기프티콘을 보여줄때 표시되는 이미지
  • img_splash_chart.png: 스플래시 화면에서 보여지는 차트 이미지

레이아웃 prefix

  • item_<what>: 리사이클러 뷰 아이템 레이아웃에 사용
  • view_<what>: 커스텀 뷰 레이아웃에 사용

리소스 네이밍

Color

<!--color 리소스 정리-->
<color name="light_gray">#E4E4E4</color>
<color name="gray">#8D8D8D</color>
<color name="gray_alpha_30">#30000000</color>

<!--색 변수 wHeRe_wHAt. 여러 곳에서 사용된다면 where 생략 가능.-->
<color name="saveSchedule_titleText">@color/light_gray</color>
<color name="yearCalendarView_titleText">@color/gray</color>
<color name="close_background">@color/gray_alpha_30</color>

description은 테마 속성으로 분리. ex) <item name="titleTextColor">@color/yellow_500</item>

레이아웃에서 사용은 테마 속성을 참조 style="@style/Theme.titleTextColor"

코틀린 컨벤션

클래스 명

단어의 첫 글자만 upper case

class Person
class User 

프로퍼티

뷰모델, 어댑터의 프로퍼티 명은 풀네임을 사용

val addTaskViewModel: AddTaskViewModel by viewModels()
val addTaskAdapter = AddTaskAdapter()

함수 명

첫 단어를 제외한 단어부터 단어의 첫 글자만 upper case

fun getPersonId() {}
fun getUserId() {}

클래스 내부 함수 배치 순서

  • 프로퍼티
  • 생성자
  • init
  • onCreate
  • onCreateView
  • 함수
  • ondestroy
  • companion object
interface Example{
    // 띄기
    fun A()
    
    fun B()
    
    fun C()
    // 띄기
}

class D(
    a,
    b,
    c // 140space 맞춰서
) : B {
    // 띄기
    private val _binding
    private val binding = get() = _binding
    
    private val viewModel by viewModels{}
    
    private lateinit var
    
    private val a = 3
    
    init {
        
    }
    
    override onCreate()
    
    private fun()
    
    override onDestroy()
    
    inner class C() {
        
    }
    
    companion object {
        
    }
}

함수 파라미터

//single Event
class Adapter(val onClick : (String) -> Unit)

//Multiple Event
class Adapter(val onClick : MinSeokOnClickListener)

fun interface MinSeokOnCLickListener {
    
    fun onClick(str : String)
    
    fun onLongClick(str : String)
    
}

val onclickListener = object: MinSeokOnCLickListener {
    fun onClick(str : String) {
    
    }
    
    fun onLongClick(str : String) {
    
    }
}

Adapter(onclickListener)

Adapter(::onClick) // 3줄 이상 분리
Adapter {
    Log.d("asd", it)
} // 2줄 이내 사용

Enum

[What]Type

Sealed

NetworkState(= retrofit Result), MultipleViewHodler, 이외는 잘..?

scope 함수

apply, also, with, let, run

  • Scope 중첩 지양(최대 2중첩)
  • it 지양

함수명 prefix

비동기 함수

  • fetch: Read
  • post : Write view(viewModel.fetchData) -> viewModel(repo.fetchData) -> repo(source.fetchData)

추가

  • add: list 안에 넣을 때
  • create: 새로 생성

조회

  • get: any
  • find: nullable any
  • is, has: boolean

화면전환

  • show[Dialog]
  • start[Activity]
  • navigate[Fragment]

화면 갱신

  • show
  • invalidate

if문

else if 사용 금지 -> when으로 변환 else도 지양 고려

if (true) {
    foo()
} else {
    bar()
}

// else 지양 
⬇️
bar()
if (true) {
    foo()
}

if (true) foo() else bar()

when문

// 2줄 이하는 block 안에서
when {
    aaa -> {
        
    }
    
    bbb -> {
        
    }
}

// 3줄 이상은 함수로
when {
    aaa -> foo()
    bbb -> bar()
}

intent, startActivity

// 1. startActivityforRequest 불가능
MissionActivity.startActivity(context, "mission_id")

// 2 startActivity 따로 해줘야함
MissionActivity.getIntent(context,"mission_id").let {
    startActivity(it)    
}

// 3. 기본
MissionActivity.class
companion object {
    fun getIntent() : Intent{
        intent = Intent(context, MissionActivity::class.java)
        intent.putExtra("mission_id",10)
        return intent
    }
}

상수

resource -> 화면에 보이는가를 기준으로 string.xml에 분리 결정 Android intent extra name은 companion에 const val 선언

  • ex: EXTRA_TITLE_ID = "title_id" 상수 네이밍은 upper snake case

의미 있는 숫자, 문자열은 companion에 const val 선언

  • ex: LOOP_COUNT = 10

네트워크 response 객체 Entity 매핑 방식

  • from ⭐

테스트 함수 네이밍

  • 한국어, snake case
instrument ok
fun `일정을_잘못_가져올_때`()

참고 url

헤이딜러

Kotlin 스타일 가이드

혼자서 안드로이드 App 개발하기

xml 네이밍