포스팅 OS : Mac

검색어 : 코틀린(Kotlin), enum, when, 스피너(Spinner), 임포트(import)



▶︎ 이전 포스팅 목록

2018/02/10 - [Android_Kotlin] - [Android Kotlin] 안드로이드 스튜디오(Andorid Studio)에 코틀린(Kotlin) 개발환경 셋팅

2018/03/14 - [Android_Kotlin] - [Android Kotlin] 텍스트뷰(TextView)와 버튼(Button)을 사용한 헬로 코틀린

2018/03/14 - [Android_Kotlin] - [Android Kotlin] 함수와 변수를 이용하여 에디트텍스트(EditText)에 입력한 값 중 큰 값 구하기

2018/03/15 - [Android_Kotlin] - [Android Kotlin] 문자열 템플릿(String Template) 사용법

2018/06/05 - [Android_Kotlin] - [Android Kotlin] 클래스, 프로퍼티, 커스텀 접근자 - 라디오 버튼(Radio Button)





이번에는 enum과 when을 사용하는 방법에 대하여 포스팅하겠습니다. 


enum과 when을 충분히 사용해 볼수 있는 예제로 색을 혼합해 혼합된 색상에 대해 출력해주는 액티비티를 만들겠습니다.


참고로 제가 안드로이드 예제를 통한 학습방법을 고집하는 이유는 단순히 코틀린만을 공부하는게 아니라 코틀린을 안드로이드에 적절히 사용하는 방법도 같이 익히기 위해서 입니다. 제가 작성하는 포스팅을 처음부터 차근차근 보다보면 코틀린을 공부함과 동시에 안드로이드 앱을 코틀린으로 제작하는 방법도 저절로 배우게 되실 거라고 봅니다.



1. Color 클래스

enum class Color (
// 상수의 프로퍼티를 정의
val r: Int, val g: Int, val b: Int
) {
// 각 상수를 생성할 때 그에 대한 프로퍼티 값을 지정
RED(255, 0, 0),
ORANGE(255, 165, 0),
YELLOW(255, 255, 0),
GREEN(0, 255, 0),
BLUE(0, 0, 255),
INDIGO(75, 0, 130),
VIOLET(238, 130, 238); // 마지막엔 반드시 세미콜론(;)을 사용해야 한다.

// enum 클래스 안에서 메소드를 정의
fun rgb() = "R : " + r + " G : " + g + " B : " + b
}



2. 레이아웃

<?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"
android:orientation="vertical"
tools:context="com.kotlin_test.Activity.EnumWhenActivity">

<TextView
android:text="1. 색 정보 보기"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp" />
<TextView
android:id="@+id/txt_color_result"
android:layout_width="match_parent"
android:layout_height="100dp"
android:textSize="20dp"
android:textStyle="bold"
android:gravity="center" />

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="3">
<Button
android:id="@+id/btn_red"
android:text="Red"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"/>

<Button
android:id="@+id/btn_orange"
android:text="Orange"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"/>

<Button
android:id="@+id/btn_yellow"
android:text="Yellow"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"/>
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="4">
<Button
android:id="@+id/btn_green"
android:text="Green"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"/>

<Button
android:id="@+id/btn_blue"
android:text="Blue"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"/>

<Button
android:id="@+id/btn_indigo"
android:text="Indogo"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"/>

<Button
android:id="@+id/btn_violet"
android:text="Violet"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"/>
</LinearLayout>


<TextView
android:text="2. 혼합할 색상을 골라주세요"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="20dp"
android:textSize="20sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="8"
android:gravity="center">
<TextView
android:text="1번 색"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="2"
android:textSize="20sp"
android:textStyle="bold"
android:gravity="center"/>
<Spinner
android:id="@+id/spn_first"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="3"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="8"
android:gravity="center">
<TextView
android:text="2번 색"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="2"
android:textSize="20sp"
android:textStyle="bold"
android:gravity="center"/>
<Spinner
android:id="@+id/spn_second"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="3"/>
</LinearLayout>
<Button
android:id="@+id/btn_mix"
android:text="Mix"
android:layout_width="match_parent"
android:layout_height="50dp"/>

<TextView
android:id="@+id/txt_mix_result"
android:layout_width="match_parent"
android:layout_height="80dp"
android:textSize="20sp"
android:textStyle="bold"
android:gravity="center"/>

</LinearLayout>



3. res > values > string.xml String Array 삽입

<string-array name="colorList">
<item>Red</item>
<item>Orange</item>
<item>Yellow</item>
<item>Green</item>
<item>Blue</item>
<item>Indogo</item>
<item>Violet</item>
</string-array>



4. 소스

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.view.View
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.Spinner
import com.kotlin_test.R
import com.kotlin_test.model.Color
import com.kotlin_test.model.Color.*
import kotlinx.android.synthetic.main.activity_enum_when.*

class EnumWhenActivity : AppCompatActivity() {

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

// 색 정보 보기 구간 ---------------------------------------------------------------------------
btn_red.setOnClickListener {
txt_color_result.setText(getMsg(Color.RED))
}

btn_orange.setOnClickListener {
txt_color_result.setText(getMsg(Color.ORANGE))
}

btn_yellow.setOnClickListener {
txt_color_result.setText(getMsg(Color.YELLOW))
}

btn_green.setOnClickListener {
txt_color_result.setText(getMsg(Color.GREEN))
}

btn_blue.setOnClickListener {
txt_color_result.setText(getMsg(BLUE))
}

btn_indigo.setOnClickListener {
txt_color_result.setText(getMsg(Color.INDIGO))
}

btn_violet.setOnClickListener {
txt_color_result.setText(getMsg(Color.VIOLET))
}


// 색 혼합 구간 -------------------------------------------------------------------------------
var firstColor : Color? = RED
var secondColor : Color? = RED

// 스피너 셋팅
val spnFirst = findViewById(R.id.spn_first) as Spinner
val spnSecond = findViewById(R.id.spn_second) as Spinner
val adapter = ArrayAdapter.createFromResource(this, R.array.colorList, android.R.layout.simple_spinner_item)

// 첫 번째 스피너
spnFirst.adapter = adapter
spnFirst.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(adapterView: AdapterView<*>, view: View, position: Int, l: Long) {
firstColor = setColor(position)
}

override fun onNothingSelected(adapterView: AdapterView<*>) {

}
}

// 두 번째 스피너
spnSecond.adapter = adapter
spnSecond.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(adapterView: AdapterView<*>, view: View, position: Int, l: Long) {
secondColor = setColor(position)
}

override fun onNothingSelected(adapterView: AdapterView<*>) {

}
}

// Mix 버튼
btn_mix.setOnClickListener {
txt_mix_result.setText("mix : " + mix(firstColor, secondColor) + "\n" +
"mixOptimized : " + mixOptimized(firstColor, secondColor))
}
}

fun getMsg(color : Color) = "색상 코드 : ${color.rgb()}\n" +
"연관 단어1 : ${getMnemonic(color)}\n" +
"연관 단어2 : ${getWarmth(color)}"

// import com.kotlin_test.model.Color.*
// 짧은 이름으로 사용하기 위해 enum 상수를 모두 임포트 하면 아래와 같이 RED, ORANGE 등으로 사용 가능합니다
fun setColor(positon: Int) =
when (positon) {
0 -> RED
1 -> ORANGE
2 -> YELLOW
3 -> GREEN
4 -> BLUE
5 -> INDIGO
6 -> VIOLET
else -> null
}

// when을 사용해 올바른 enum 값 찾기
fun getMnemonic(color: Color) =
when (color) {
RED -> "Richard"
ORANGE -> "Of"
YELLOW -> "York"
GREEN -> "Gave"
BLUE -> "Battle"
INDIGO -> "In"
VIOLET -> "Vain"
}

// 한 when 분기 안에 여러 값 사용하기
// 콤마로 구분한다.
fun getWarmth(color: Color) =
when(color) {
RED, ORANGE, YELLOW -> "warm"
GREEN -> "neutral"
BLUE, INDIGO, VIOLET -> "cold"
}

// when의 분기 조건에 여러 다른 객체 사용하기
// 비효율 적인 코드 - 여러 set 인스턴스를 생성하기 떄문에
fun mix(c1: Color?, c2: Color?) =
when (setOf(c1, c2)) {
setOf(RED, YELLOW) -> "ORANGE"
setOf(YELLOW, BLUE) -> "GREEN"
setOf(BLUE, VIOLET) -> "INDIGO"
else -> "Dirty color"
}

// 인자가 없는 when
// when에 인자가 없으면 각 분기의 조건이 Boolean 결과를 계산하는 식이어야 한다.
// 위 mix 함수보다 불필요한 객체 생성을 막을 수 있어서 효율적이다. 비록 코드는 약간 읽기 어려워지지만 성능 향상이 가능하다
fun mixOptimized(c1: Color?, c2: Color?) =
when {
(c1 == RED && c2 == YELLOW) || (c1 == YELLOW && c2 == RED) -> "ORANGE"
(c1 == YELLOW && c2 == BLUE) || (c1 == BLUE && c2 == YELLOW) -> "GREEN"
(c1 == BLUE && c2 == VIOLET) || (c1 == VIOLET && c2 == BLUE) -> "INDIGO"
else -> "Dirty color"
}
}



5. 실행 결과



+ Recent posts