Каким бы образом вы это реализовали?

  1. Имеем 4 TextView, множество String, записанных в формате :
    <string name="common_q1"> Вопрос 1 </string>
    <string name="common_a1_1"> Ответ 1 </string>
    <string name="common_a1_2"> Ответ 2 </string>   -- ПРАВИЛЬНЫЙ ОТВЕТ 
    <string name="common_a1_3"> Ответ 3 </string>

    <string name="common_q1"> Вопрос 2 </string>
    <string name="common_a1_1"> Ответ 1 </string> -- ПРАВИЛЬНЫЙ ОТВЕТ 
    <string name="common_a1_2"> Ответ 2 </string>   
    <string name="common_a1_3"> Ответ 3 </string>

    <string name="common_q1"> Вопрос 2 </string>
    <string name="common_a1_1"> Ответ 1 </string> 
    <string name="common_a1_2"> Ответ 2 </string>   -- ПРАВИЛЬНЫЙ ОТВЕТ 
    <string name="common_a1_3"> Ответ 3 </string>

Также имеется функция, которая находит ID строк и при нажатии на кнопку записывает в TextView каждый раз новую строку ( https://ru.stackoverflow.com/questions/1340763/Можно-ли-автоматически-изменять-название-строки-в-getstring) Т.Е. в TextView 1 выведется Вопрос 1, в TextView 2 выведется Ответ 1, в TextView 3 выведется Ответ 2 и тд. При нажатии на кнопку в эти же TextView выводится уже новые вопросы и ответы.

  1. Суть в том, чтобы в конкретный момент времени знать в каком именно TextView хранится правильный ответ на вопрос и организовать проверку на правильность ответа при нажатии на этот TextView.

Код желательно для Kotlin, но и Java тоже будет очень полезен

Всем, кто отвечает - огромное СПАСИБО!


Ответы (1 шт):

Автор решения: Vadim Yaroschuk

Я бы решил подобным образом:


/**
* @param [question] - это наш R.string.X
*/
data class Question(
   val question: Int,
   val answers: List<Answer>
)

sealed interface Answer {
   val answer: Int // наш ответ в виде R.string.X

   class RightAnswer(override val answer: Int) : Answer
   class WrongAnswer(override val answer: Int) : Answer
}

fun setQuestion(Question question) {
   questionTextView.setText(question)
   recyclerView.setAdapter(Adapter(
      question.answers, 
      callback = { if(question is RightAnswer) pass() else failed() }
   )) // но, лучше, конечно, обновить данные
}

fun pass() {
  // геним тут новый вопрос
}

fun failed() {
  // показываем юзеру что он не прав
}

class Adapter(private val list: List<Answer>, private val callback: (Answer) -> Unit) : RecyclerView.Adapter<...> // тут наш адаптер

Но, можно не запариваться (но это плохой вариант) и просто менять для каждого TextView OnClickListener после ответа:

textView1.setOnClickListener { v ->
   success()
}

textView2.setOnClickListener { v ->
   failed()
}

textView3.setOnClickListener { v ->
   failed()
}

Так же, вам стоит понять, что UI должен быть максимально "глупым" и вы не должны делать выкрутасы, как показано во втором примере.

UPD: заполнить Question можно следующим образом:

fun questionOf(questionId: Int, rightAnswerId: Int): Question? {
   val question: Int = getQuestion(questionId) ?: return null
   val answers: List<Int> = getAnswers(questionId).mapIndexed { id, answer ->
      if(rightAnswerId != id) Answer.WrongAnswer(answer) else Answer.RightAnswer(answer)
   }
   return Question(question, answers)
}

private fun getAnwers(questionId: Int): List<Int> {
   var x = 0
   val list = mutableListOf<Int>()
   while(true) {
      resources.getIdentifier("common_q${questionId}_a$x", "string").takeIf { it != 0 }?.let { list += it } ?: break
   }
   return list
}

private fun getQuestion(id: Int): Int? {
   return resources.getIdentifier("common_q$id", "string").takeIf { it != 0 }
}

Всё что нужно вам - это хранить текущий идентификатор, т.е просто инкременировать какую-то переменную после ответа.

Ещё один UPD: вы делаете всё очень криво, советую вообще отказаться от такого вида вопросов/ответа.

→ Ссылка