xml 파일 작업 )
xml 파일부터 작업을 시작합니다.
구현하고자 하는 화면 구성은 아래와 같습니다.
"번호 추가하기", "초기화", "자동 생성 시작" 총 3개의 버튼이 필요합니다.
NumberPicker가 필요합니다
로또 번호는 기본적으로 TextView를 활용하여 보여주고, 배경에 drawble 이미지를 사용합니다.
가장 상위 layout을 Constraint로 만들고, 수평으로 나열되는 TextView는 Linear layout으로 만듭니다.
drawble은 res 하위에 있는 drawble 폴더에서 만들 수 있습니다.
모양을 설정합니다.
색상과 size를 설정합니다.
만들어진 drawble 이미지는 아래와 같이 불럴와 쓸 수 있습니다.
kt 파일 작업 )
1) NumberPicker로 번호 추가
2) 누적된 번호 초기화
3) 모든 번호를 random으로 채우기
크게 위 3가지 작업을 해주어야 합니다.
로또 번호가 평상 시엔 보이고 있지 않다가 추가를 할 때만 화면에 visible하게 합니다.
번호를 표시해주는 TextView들은 findViewById로 받아와서 list 형태로 관리합니다.
listOf 함수로 TextView type의 list를 만들어주었습니다.
NumberPicker의 범위는 아래처럼 지정해줍니다.
뽑은 번호는 중복될 수 없으므로 set으로 관리합니다.
수정 가능해야 하므로 mutable로 선언합니다.
아래는 by lazy의 형식입니다.
var을 사용할 수 없고, val에서만 사용 가능합니다.
by lazy 뒤에 열린 중괄호 안에 초기화 코드를 작성합니다.
변수 선언과 동시에 초기화를 하지만, 바로 초기화되지 않고 호출되는 시점에서 초기화가 이루어집니다.
by lazy와 같은 늦은 초기화는, 첫 초기화 값이 정해지지 않았을 때 null 사용을 지양하기 위해 씁니다.
null을 엄격하게 관리하는 kotlin에서는 아래처럼 하기보다 차라리 초기화를 미룬다는 의미입니다.
설명은 아래 포스팅을 참고하였습니다.
스코프 함수 중 하나인 apply에 대한 설명은 아래 유튜브를 참고하였습니다.
https://www.youtube.com/watch?v=QGDWWL6qA3I
인스턴스를 생성하자마자 apply를 붙이면 참조 연산자 없이 사용 가능합니다.
또한 인스턴스 자신을 반환하므로 코드가 깔끔해진다는 장점이 있습니다.
Int형 List를 반환하는 getRandomNumber 함수를 만듭니다.
수정가능한 Int형 element를 갖는 list를 만들고 numberList라는 변수 이름에 할당합니다.
list 안에 1부터 45까지의 숫자를 할당합니다.
리스트 안의 element 순서를 random하게 섞고
기존의 수동으로 번호를 뽑아 만들어놨던 pickNumberSet을 list로 변환한다음
조금 전에 만든 리스트, numberList에서 남은 빈자수만큼의 element를 추출해서 새로운 리스트를 만들어줍니다.
가령 subList(0,3)은 numberList의 인덱스 0,1,2까지 추출하겠다는 의미입니다.
파이썬에서는 난수를 만들어주는 함수가 따로 있었는데, 여기에서는 랜덤의 개념을 빌린 거지 엄밀하게 난수 생성은 아닌 것입니다.
마지막에는 오름차순으로 정렬을 해주도록 합니다.
수동으로 로또 번호를 추가해주는 함수를 만듭니다.
버튼을 눌렀을 때 동작하도록 setOnClickListener함수로 중괄호를 열어줍니다.
boolean type의 변수 didRun은 runButton이 눌렸을 때 값이 true로 바뀌는데
이 경우 빈 자리가 없어 숫자를 더 추가할 수 없으니 "초기화 후에 시도해주세요."라는 문구를 Toast 메세지로 구현합니다.
뽑은 번호는 pickNumberSet 안에 추가하여 관리하는데
만약 numberPicker로 추가하려는 값이 이미 뽑힌 번호라 pickNumberSet 안에 들어있으면
"이미 선택한 번호입니다."라는 문구를 출력하고 다시 클릭할 수 있는 상태로 되돌려줍니다.
pickNumberSet.size는 지금까지 추가된 번호의 갯수를 의미합니다.
if문에 안 걸리고 여기까지 왔으면 정상적으로 번호를 추가해줘야 합니다.
새로 추가할 번호 자리(인덱스)에 해당되는 TextView를 visible로 바꿔주고
.text를 활용하여 화면으로 보여줍니다.
이후엔 새로 추가한 번호가 속한 영역에 따라 배경색을 정해주는 setNumberBackground 함수로 배경색을 정해주고 pickNumberSet에 뽑은 번호를 추가하여 size를 키워줍니다.
초기화 버튼 함수를 만들어줍니다.
clear함수로 Set 안에 들어있는 걸 모두 비워주고, didRun값을 false로 바꿔서
랜덤 자동 추가 버튼을 눌렀을 때 첫번째 if문에 안 걸리고 정상적으로 숫자가 추가되게끔 해줍니다.
이후에는 .forEach를 활용하여 List의 모든 element(TextView)의 visible 상태를 false로 바꿔 눈에 안 보이게 해줍니다.
forEach를 쓸 땐 중괄호를 열어주어야 합니다.
getRandomNumber()는 랜덤의 6개 숫자가 sorted된 list입니다.
forEachIndexed는 list 안의 element들의 value뿐만 아니라 index도 활용할 수 있게 해주는 것입니다.
자세한 설명은 아래의 포스팅을 참고하였습니다.
https://skytitan.tistory.com/181
6개의 번호를 보여줄 TextView 6개를 numberTextViewList라는 이름의 list로 관리 중이었는데
각 인덱스를, 즉 각 TextView를 textView란 변수에 할당하고, 해당 index에 대응되는 value, 즉 number 값을 .text를 활용하여 보여줍니다.
이후엔 isVisible을 true로 바꿔서 눈으로 볼 수 있게 해주고, 번호에 대응되는 배경색을 background로 입혀줍니다.
'Kotlin' 카테고리의 다른 글
코틀린 스터디 - 12장 (0) | 2023.10.15 |
---|---|
Kotlin_에어비앤비 (0) | 2022.09.14 |
Kotlin_비밀 다이어리 (0) | 2022.03.14 |
BMI 계산기 복습 (0) | 2022.03.05 |