이 글은 유데미 강의 Android 12 및 Kotlin 개발 완전 정복을 참고하여 작성하였습니다.
작성자 : 조윤주
개발환경은 Windows, Android Studio입니다.
버튼 기능을 QuestionActivity에 추가
1. 버튼을 눌렀을 때 스타일 추가
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<stroke
android:width="1dp"
android:color="@color/design_default_color_primary"
/>
<solid android:color="@color/white"/>
<corners android:radius="10dp"/>
</shape>
버튼을 누른 경우 위의 스타일을 적용시켜야 한다.
2. 버튼을 클릭할 수 있도록 만들기
버튼을 클릭할 수 있게 만들기 위해 AppCompat 액티비티를 만들어야한다.
class QuizQuestionsActivity : AppCompatActivity(), View.OnClickListener{
private var mCurrentPosition : Int = 1 //현재 몇번째 문제인지 저장하는 변수.
private var mQuestionsList : ArrayList<Question>? = null
private var mSelectedOptionPosition : Int = 0 //선택한 옵션이 무엇인지 저장하는 변수. default는 0
//내용 생략}}
AppCompat Activity에서 QuizQuestionsActivity를 상속받는 동시에 리스너를 구현할 수 있도록 옆에 View.OnClickListener를 작성하고, mCurrentPosition 변수를 생성하고 1로 초기화 시킨 뒤, onCick함수를 작성한다. onClick 함수를 작성하기 전, 필요한 변수들을 전역변수로 선언해준다.
override fun onClick(view: View?) {
when(view?.id){
R.id.tv_option_one->{
tvOptionOne?.let{
selectedOptionView(it,1)
}
}
R.id.tv_option_two->{
tvOptionOne?.let{
selectedOptionView(it,2)
}
}
R.id.tv_option_three-> {
tvOptionOne?.let {
selectedOptionView(it, 3)
}
}
R.id.tv_option_four-> {
tvOptionOne?.let {
selectedOptionView(it, 4)
}
}
}
}
3. 문제에 따른 버튼 내용 바꾸기
private fun setQuestion() {
var currentPosition = 1
val question: Question = mQuestionsList!![mCurrentPosition - 1]
ivImage?.setImageResource(question.image)
progressBar?.progress = mCurrentPosition
tvProgress?.text = "$mCurrentPosition/${progressBar?.max}"
tvQuestion?.text = question.question
tvOptionOne?.text = question.optionOne
tvOptionTwo?.text = question.optionTwo
tvOptionThree?.text = question.optionThree
tvOptionFour?.text = question.optionFour
btnSubmit = findViewById(R.id.btn_submit)
//마지막 질문인 경우 버튼의 내용을 Finish로, 그렇지 않은경우 Submit으로 한다.
if(mCurrentPosition == mQuestionsList!!.size){
btnSubmit?.text = "FINISH"
}
else{
btnSubmit?.text = "SUBMIT"
}
}
4. 버튼을 클릭했을 때, 스타일 바꾸기
버튼을 클릭하기 전에는 회색 테두리지만, 선택한 버튼은 보라색 테두리를 가지도록 만든다. 선택한 옵션의 스타일을 바꾸는 메소드와 선택하지 않은 옵션의 스타일을 바꾸는 메소드, 각각 두개가 필요하다. 해당 메소드는 다음과 같다.
private fun defaultOptionsView(){
val options = ArrayList<TextView>()
tvOptionOne?.let{
options.add(0,it)
}
tvOptionTwo?.let{
options.add(1,it)
}
tvOptionThree?.let{
options.add(2,it)
}
tvOptionFour?.let{
options.add(3,it)
}
for(option in options){
option.setTextColor(Color.parseColor("#7A8089"))
option.typeface = Typeface.DEFAULT
option.background = ContextCompat.getDrawable(this,R.drawable.default_option_border_bg)
}
}
private fun selectedOptionView(tv:TextView,selectedOptionNum:Int){
defaultOptionsView()
mSelectedOptionPosition = selectedOptionNum
tv.setTextColor(Color.parseColor("#363A43"))
tv.setTypeface(tv.typeface,Typeface.BOLD)
tv.background = ContextCompat.getDrawable(this,R.drawable.selected_option_border_bg)
}
5. 옵션 텍스트 뷰에 클릭 이벤트 적용
이제 옵션 텍스트 뷰에 클릭이벤트를 적용시킨다. Oncreate에 해당 코드를 추가하여, 각 옵션뷰들에 클릭이벤트를 발생하도록 만든다.
tvOptionOne?.setOnClickListener(this)
tvOptionTwo?.setOnClickListener(this)
tvOptionThree?.setOnClickListener(this)
tvOptionFour?.setOnClickListener(this)
btn_submit?.setOnClickListener(this) //6에서 설명
6. 제출 버튼에 이벤트 적용
옵션 텍스트 뷰에 클릭이벤트를 적용시킨 것 처럼, 제출 버튼도 Oncreate에 코드를 추가하여 이벤트를 발생시키도록 하고, 어떤 이벤트를 적용시킬지 onClick메서드에 추가적으로 정의해준다.
답변을 고르고 정답 여부를 다음 질문에 반영하기
버튼에서 했던 것 처럼, 맞았을 때의 style과 틀렸을 때의 style을 만들어준다.
1. 정답/오답에 따라 다른 이벤트 적용
제출 버튼을 눌렀을 때, 정답일 때의 이벤트와 틀렸을때의 이벤트를 정의해준다. 또한, 버튼을 눌렀을 때 다음 문제로 넘어가도록 해준다.
R.id.btn_submit->{
if(mSelectedOptionPosition==0){
mCurrentPosition++
when{
mCurrentPosition<=mQuestionsList!!.size->{setQuestion()}
}
}
else{
val question = mQuestionsList?.get(mCurrentPosition-1)
if(question!!.correctAnswer != mSelectedOptionPosition){
answerView(mSelectedOptionPosition,R.drawable.wrong_option_border_bg)
}
answerView(question.correctAnswer,R.drawable.correct_option_border_bg)
if(mCurrentPosition == mQuestionsList!!.size){
btnSubmit?.text = "FINISH"
}
else{
btnSubmit?.text = "GO TO NEXT QUESTION"
}
mSelectedOptionPosition = 0
}
}
}
2. 마지막 문제에 도달했을 때, 메세지 띄우기
제출 버튼의 이벤트의 when문에 else문을 이용해 마지막 문제에 도달하면 Toast를 사용하여 메세지를 출력한다.
else ->{
Toast.makeText(this,"You Made it to the end",Toast.LENGTH_SHORT).show()
}
결과 UI 만들기
Result Activity를 만들어주고, 다음과 같은 화면이 나오도록 결과 UI를 만들어준다. activity_result.xml의 자세한 코드는 생략하겠다.
데이터를 보내기
1. Constants에 필요한 데이터를 정의한다.
Constants에 넘겨야하는 데이터인 유저이름, 총 문제수, 맞은 문제수 변수를 const val로 정의해준다.
const val USER_NAME : String = "user_name"
const val TOTAL_QUESTIONS : String = "total_questions"
const val CORRECT_ANSWERS : String = "correct_answers"
2. 필요한 데이터 넘겨받기
QuizQuestionActivity에서 유저이름을 넘겨받을 변수를 nullable로 선언하고, 다음과 같은 코드를 onCreate 내부에 작성하여, QuizActivity가 실행되면 유저이름을 저장하도록 한다.
mUserName = intent.getStringExtra(Constants.USER_NAME)
3. 정답 수 데이터, 문제 수 데이터 저장
QuizQuestionActivity에서 정답수를 저장할 변수를 0으로 초기화 하고, 제출 버튼을 눌렀을 때, 정답의 수가 1 증가하도록 만든 다음, 이를 위에서 했던 유저이름을 저장한 방식과 같이 intent를 사용하여 Constants.CORRECT_ANSWER에 넘겨준다.
문제 수 또한 같은 방식으로 mQuestionList의 size메서드를 사용하여 전체 문제 수를 Constants.TOTAL_QUESTIONS변수에 넘겨준다.
4. 결과 창에 나오는 값 넣기
val tvName : TextView = findViewById(R.id.tv_name)
val tvScore : TextView = findViewById(R.id.tv_score)
val btnFinish : Button = findViewById(R.id.btn_finish)
tvName.text = intent.getStringExtra(Constants.USER_NAME)
val totalQuestions = intent.getIntExtra(Constants.TOTAL_QUESTIONS,0)
val correctAnswer = intent.getIntExtra(Constants.CORRECT_ANSWERS,0)
tvScore.text = "Your Score is $correctAnswer out of $totalQuestions"
5. Finish버튼 누르면 처음으로 돌아가기
결과가 나오는 화면에는 FINISH버튼이 있는데 해당 버튼을 누르면 처음화면으로 돌아가도록 만든다.
btnFinish.setOnClickListener{
startActivity(Intent(this,MainActivity::class.java))
}
'GDSC HUFS 4기 > Kotlin Team #2' 카테고리의 다른 글
[2팀] 드로잉 앱 만들기 (1) (0) | 2022.11.15 |
---|---|
[2팀] 드로잉 앱 만들기(2) (1) | 2022.11.14 |
[2팀] 코틀린으로 XML, UI를 생성해서 계산기 만들기 (0) | 2022.10.31 |
[2팀] 코틀린으로 분 단위 계산기 만들기 (0) | 2022.10.26 |
[2팀] 객체지향 프로그래밍 기초(2) (1) | 2022.10.13 |