kotlin / android studio: дождитесь нажатия кнопки - PullRequest
0 голосов
/ 02 января 2019

, поэтому я пишу приложение, которое просит пользователя идентифицировать различные ноты, которые им воспроизводятся.я представляю, что это можно сделать, проиграв одну случайную ноту из набора заметок, затем подождав, пока пользователь нажмет кнопку с соответствующей заметкой, сообщив пользователю, правильно ли они вставили ноту, и, после небольшой задержки, запуститевсе по-новому.

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

Вот что я сделал до сих пор:

У меня есть 12 кнопок, по одной на каждую ноту хроматической шкалы, каждая с соответствующим onClickListener, похожим на это

        dobutton.setOnClickListener {
            var mediaPlayer: MediaPlayer? = MediaPlayer.create(this, R.raw.cping)
            mediaPlayer?.start()
            givenAnswer = 4 // etc. for all the other notes.

Затем я ввожу некоторые переменные:

        var score = 0
        var index = 0
        var setAnswer = 0
        var givenAnswer = 0

Затем у меня есть цикл while, который заканчивается после нескольких сыгранных раундов и включает, во-первых, этот раздел, который случайным образом выбирает одну из нот для воспроизведения и устанавливает правильный ответ,с соответствующими файлами для воспроизведения и значениями для setAnswer для каждой ноты хроматической шкалы ...

while (index != 11) {

    val randomGenerator = Random()
    val randomInt = randomGenerator.nextInt(11)

    when (randomInt) {
        0 ->{
            var mediaPlayer: MediaPlayer? = MediaPlayer.create(this, R.raw.abping)
            mediaPlayer?.start()
            println(pingsArray[0])
            setAnswer = 0
        }
        1 -> {
            var mediaPlayer: MediaPlayer? = MediaPlayer.create(this, R.raw.aping)
            mediaPlayer?.start()
            println(pingsArray[1])
            setAnswer = 1
        } // etc. for all the other notes...

... а затем этот блок, который сравнивает правильный ответ с заданным и соответственно увеличивает значения.

run {
        if (setAnswer == givenAnswer) {
            index = index + 1
            score = score + 1
        }
        else {
            index = index + 1
        }
    }
}

После этого цикл while должен начаться заново.Тогда все это дает оценку.

Теперь моя проблема в том, что весь цикл while выполняется за один раз, не давая пользователю времени на что-либо ответить.Потратив целый день на поиски в Интернете и не найдя ничего полезного, я наконец решил спросить здесь.В случае, если это показывает слишком много: я только начал кодировать несколько дней назад, поэтому, пожалуйста, помилуйте, если мои вопросы немного глупы, и мой код не соответствует стандартам.Это просто куча сложных вещей, когда вы новичок в этом ...

Спасибо!

1 Ответ

0 голосов
/ 02 января 2019

Если вы просто намереваетесь непрерывно ждать, пока пользователь нажмет кнопку, прежде чем воспроизводить следующий звук, то, честно говоря, для каждого из ваших слушателей onClick просто добавьте новый вызов к вашей функции, который генерирует следующий медиапроигрыватель (давайте назовем его playNextSound()) и немедленно сравните результат, например:

dobutton.setOnClickListener {
    val mediaPlayer: MediaPlayer = MediaPlayer.create(this, R.raw.cping)
    mediaPlayer.start()

    index += 1
    if(setAnswer == thisButton){
        score += 1
    }

    if(index < 11){
        playNextSound()
    } else {
        showResults()
    }
}

В противном случае, если вы намереваетесь установить какое-то время ожидания, тогда это немного другая история. Возможно, вы захотите воспользоваться несколькими асинхронными решениями, чтобы обойти вашу головоломку: CountDownTimer или более продвинутый Обработчик & Runnable решение.

В первом случае вы можете объявить таймер обратного отсчета до определенного времени после воспроизведения музыки, например:

var timeoutCountdown: CountDownTimer = object: CountdownTimer(timeInMills, timeInMills) {

    override fun onFinish() {
        //Do something to inform the user he has run out of time. For example:
        showErrorDialog()
        index += 1
        if(index < 11){
            playNextSound()
        } else {
            showResults()
        }
    }

    override fun onTick(p0: Long) {
        //Ignore, unless you want to do something here.   
    }
}

, а затем в самом playNextSound(), после воспроизведения звука, позвоните timeoutCountdown.start(). Затем в каждом из onClickListener сделайте то же самое, что и простая реализация выше, и просто добавьте одну строку:

dobutton.setOnClickListener {
    //ADD THIS LINE TO STOP THE COUNTDOWN
    try { timeoutCountdown.cancel() } catch(ignored: Exception){}

    val mediaPlayer: MediaPlayer = MediaPlayer.create(this, R.raw.cping)
    mediaPlayer.start()

    index += 1
    if(setAnswer == thisButton){
        score += 1
    }

    if(index < 11){
        playNextSound()
    } else {
        showResults()
    }
}

Если вы стремитесь использовать вместо этого Handler / Runnable ситуацию, которая действительно излишня, если только для этого использования, дайте мне знать, и я добавлю ее.

РЕДАКТИРОВАТЬ: При использовании этой реализации больше не требуется цикл while; вы используете функции и триггер события (onClickListener или CountDownTimer) в качестве потока управления.

...