안드로이드/앱개발(Android)

(코틀린 kotlin) 로또번호생성기 앱

김염인 2021. 12. 26. 13:29

 

목표 : 총 6개의 숫자를 랜덤으로 만들 수 있는 로또 번호 생성기 앱을 제작

 

< 세부 사항 >

1~10은 노란색 10~20은 파란색 등 숫자별로 Background Color값이 달라야함,

초기화 버튼시 만든 로또 번호는 다 지워짐

번호를 수동으로 추가할 수 있음,

 

먼저 레이아웃을 그리기 위해 ContraintLayout을 만들어 준다.

NumberPicker를 그려주어 1부터 45까지 선택이 가능한 코드 작성

 

val numberpick = findviewbyId(R.id.number_pick)

numberpick.minValue = 0

numberpick.maxValue = 45

numberpicker Layout의 위치

app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"

 

이렇게 설정하면 가운데 위치에 설정이 된다.

 

번호추가하기 / 초기화 버튼은 

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintBaseline_toBottomOf="@id/NumberPicker"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toStartOf="@id/resetButton"
    android:text="@string/Add_Button"
    android:id="@+id/addButton"
    app:layout_constraintHorizontal_chainStyle="packed"
    android:layout_marginRight="16dp"
    app:layout_marginBaseline="15dp"
    >
</Button>

<Button
    android:id="@+id/resetButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintStart_toEndOf="@id/addButton"
    app:layout_constraintTop_toTopOf="@id/addButton"
    app:layout_constraintEnd_toEndOf="parent"
    android:text="@string/Reset_Button"
    >
</Button>

여기서 핵심은 chainStyle 둘은 chain으로 이루어져 있어 번호 추가하기 버튼에 margin값을 설정할시 연결된 초기화 버튼에도 margin값이 같이 적용이 된다. 그리고 constraintLayout의 특징으로 위치를 지정해줄 수 있는데 여기서는

baseline으로 numberpicker의 아래에 위치를 하게 하였고 번호 추가 버튼의 end부분은 resetButton이 시작하는 위치에 있도록 설정을 해주었다. 

 

그리고 각 번호는 LinearLayout으로 6개를 만들어 줌,

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintTop_toBottomOf="@id/addButton"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    android:layout_marginTop="20dp"
    app:layout_constraintWidth="0dp"
    android:gravity="center"
    >

    <TextView
        android:gravity="center"
        android:background="@drawable/circle_blue"
        android:textColor="@color/white"
        android:id="@+id/first_number"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="19sp"
        android:text="1"
        tools:visibility="visible"
        android:visibility="gone"
        android:layout_margin="5dp"
        android:textStyle="bold">
    </TextView>

    <TextView
        android:gravity="center"
        android:background="@drawable/circle_red"
        android:textColor="@color/white"
        android:id="@+id/second_number"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="19sp"
        android:text="1"
        tools:visibility="visible"
        android:visibility="gone"
        android:layout_margin="5dp"
        android:textStyle="bold">
    </TextView>

    <TextView
        android:gravity="center"
        android:background="@drawable/circle_yellow"
        android:textColor="@color/white"
        android:id="@+id/third_number"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="19sp"
        android:text="1"
        tools:visibility="visible"
        android:visibility="gone"
        android:layout_margin="5dp"
        android:textStyle="bold">
    </TextView>

    <TextView
        android:gravity="center"
        android:background="@drawable/circle_green"
        android:textColor="@color/white"
        android:id="@+id/fourth_number"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="19sp"
        android:text="1"
        tools:visibility="visible"
        android:visibility="gone"
        android:layout_margin="5dp"
        android:textStyle="bold">
    </TextView>

    <TextView
        android:gravity="center"
        android:background="@drawable/circle_gray"
        android:textColor="@color/white"
        android:id="@+id/fifth_number"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="19sp"
        android:text="1"
        tools:visibility="visible"
        android:visibility="gone"
        android:layout_margin="5dp"
        android:textStyle="bold">
    </TextView>

    <TextView
        android:gravity="center"
        android:background="@drawable/circle_blue"
        android:textColor="@color/white"
        android:id="@+id/sixth_number"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="19sp"
        android:text="1"
        tools:visibility="visible"
        android:visibility="gone"
        android:layout_margin="5dp"
        android:textStyle="bold">
    </TextView>

</LinearLayout>

 

그리고 이제 Layout 구성은 끝났고 구현코드를 본다.

private val clearButton: Button by lazy{
    findViewById<Button>(R.id.resetButton)
}

private  val addButton: Button by lazy{
    findViewById<Button>(R.id.addButton)
}

private  val runButton: Button by lazy{
    findViewById<Button>(R.id.runButton)
}

private  val numberPicker: NumberPicker by lazy{
    findViewById<NumberPicker>(R.id.NumberPicker)
}
private var didrun = false
private val pickNumberSet = mutableSetOf<Int>()

먼저 버튼과 numberPicker등 기능 설정을 위해 mainActivity에서 findviewbyid로 불러옴,

 

private val numberTextViewList : List<TextView> by lazy{
    listOf<TextView>(
        findViewById<TextView>(R.id.first_number),
        findViewById<TextView>(R.id.second_number),
        findViewById<TextView>(R.id.third_number),
        findViewById<TextView>(R.id.fourth_number),
        findViewById<TextView>(R.id.fifth_number),
        findViewById<TextView>(R.id.sixth_number),
    )

TextView 를 List형식으로 저장하여 numberTextViewList에 저장,

 

자동생성버튼

private fun initRunButton(){
    runButton.setOnClickListener{
        val list = getRandomNumber()

        list.forEachIndexed{
            index, number ->
            var textView = numberTextViewList[index]

            textView.text = number.toString()
            textView.isVisible = true

            setNumberBackground(number, textView)
        }

    }
}

private fun getRandomNumber() : List<Int> {
    val numberList = mutableListOf<Int>().apply {
        for (i in 1..45){
            if (pickNumberSet.contains(i)){
                continue
            }
            this.add(i)
        }
    }
    numberList.shuffle()

    val newList = pickNumberSet.toList() + numberList.subList(0,6-pickNumberSet.size)

    return newList.sorted()
}

자동으로 번호를 생성하는 코드, setonclickListener이용 하여 버튼클릭시 작동되도록 함

getRandomNumber()는 List<Int> 형식으로 return되도록 하는 코드, 

apply란 무엇일까?

apply 사용 규칙

수신 객체 람다 내부에서 수신 객체의 함수를 사용하지 않고 수신 객체 자신을 다시 반환 하려는 경우에 apply 를 사용합니다.

수신 객체 의 프로퍼티 만을 사용하는 대표적인 경우가 객체의 초기화 이며, 이곳에 apply 를 사용합니다.

val peter = Person().apply {
    // apply 의 블록 에서는 오직 프로퍼티 만 사용합니다!
    name = "Peter"
    age = 18
}

 

따라서 this.add(i)를 통하여 자기자신에게 로또 번호를 추가, 

 

private fun setNumberBackground(number:Int, textview:TextView){
    when(number){
        in 1..10 -> textview.background = ContextCompat.getDrawable(this, R.drawable.circle_yellow)
        in 11..20 -> textview.background = ContextCompat.getDrawable(this, R.drawable.circle_blue)
        in 21..30 -> textview.background = ContextCompat.getDrawable(this, R.drawable.circle_red)
        in 31..40 -> textview.background = ContextCompat.getDrawable(this, R.drawable.circle_gray)
        else -> textview.background = ContextCompat.getDrawable(this, R.drawable.circle_green)
    }
}

setNumberBackground에 매개변수가 들어오면 number의 수 만큼 backgroundColor를 결정해주는 when문이 작성된다.

 


private fun initResetButton(){
    clearButton.setOnClickListener{
        pickNumberSet.clear()
        numberTextViewList.forEach{
            it.isVisible = false
        }
        didrun = false
    }
}
private fun initAddButton(){
    addButton.setOnClickListener{
        if(didrun){
            Toast.makeText(this,"초기화 후에 시도해 주세요",Toast.LENGTH_SHORT).show()
            return@setOnClickListener
        }

        if(pickNumberSet.size >= 6){
            Toast.makeText(this,"번호는 6개까지 선택가능 합니다.",Toast.LENGTH_SHORT).show()
            return@setOnClickListener
        }

        if(pickNumberSet.contains(numberPicker.value)){
            Toast.makeText(this,"이미 선택한 번호 입니다.",Toast.LENGTH_SHORT).show()
            return@setOnClickListener
        }

        val textView = numberTextViewList[pickNumberSet.size]
        textView.isVisible = true
        textView.text = numberPicker.value.toString()

        setNumberBackground(numberPicker.value, textView)

        pickNumberSet.add(numberPicker.value)
    }
}

마지막으로 add버튼과 reset버튼 foreach를 사용하면 it.~~식으로 layout접근 가능하다.

 

이렇게 앱이 완성됐다.