4択クイズアプリ(Kotlin)

【Android Studio】Kotlinでつくるクイズアプリ講座 第5回「正解・不正解の判定」

Sara

Android Studio Ladybug | 2024.2.1 に対応しました(2024年11月)

ここまでの記事はこちら
Java バージョンはこちら

前回クイズを表示することができたので、今回はクイズの正解・不正解を判定してみましょう。

正解・不正解の判定は解答ボタンが押されたときに呼ばれる checkAnswer 関数を使います。

ダイアログを使ってクイズの答えも表示してみましょう。

正解・不正解を判定する

1. クイズの出題数を設定する

まずはクイズを何問出題するかを決めます。

3~5行目を追加してください。

ここではクイズを5問出題するように設定しました。

出題したクイズは quizData リストから削除するので、出題数はリストの要素数を超えない範囲に設定してください。

2. checkAnswer 関数

checkAnswer関数にコードを追加します。

必要な import

ダイアログを使うために以下のimportが追加されます。

import com.google.android.material.dialog.MaterialAlertDialogBuilder

3・4行目:どの解答ボタンが押されたかを取得

val answerBtn: Button = findViewById(view.id)
val btnText = answerBtn.text.toString()

押された解答ボタンを見つけて、そのボタンのテキストを取得しています。

8~13行目:正解・不正解の判定

8行目では解答ボタンのテキストと rightAnswer が一致するかで正解・不正解を判定しています。

if (btnText == rightAnswer) {
  alertTitle = "正解!"
  rightAnswerCount++
} else {
  alertTitle = "不正解…"
}

正解の場合は、このあと作成するダイアログのタイトルを「正解!」として、正解数をカウントする rightAnswerCount に1を加算します。

不正解の場合は、ダイアログのタイトルを「不正解…」とするだけです。

16行目〜:ダイアログを表示する

16行目からはダイアログを作成しています。

まずはタイトル・メッセージ・OKボタンを追加します。

19~21行目は OK ボタンが押された時に checkQuizCount 関数を呼び出す設定をしています。

22行目の setCancelable はダイアログの外側をタップしたときにダイアログを閉じるかどうかを指定しています。

false にしているので OK ボタンを押さないとダイアログを閉じることはできません。

ダイアログの表示には DialogFragment を使うべきですが、このクイズでは画面を固定すると想定していること、より簡単に実装することを理由にここでは使用していません。講座の完全版では DialogFragment を使う方法を紹介しています。

3. checkQuizCount 関数

ダイアログの OK ボタンが押されたら呼ばれる checkQuizCount 関数に以下のコードを書きます。

最初に設定した出題数 QUIZ_COUNT と quizCount が同じになったら結果画面に移動します。

QUIZ_COUNT に達していない場合は quizCount に1を足して、再び showNextQuiz メソッドを呼ぶことで、クイズを続けて出題できるようになります。

4. countLabel の更新

最後に「Q1」と表示している countLabel を更新しましょう。

showNextQuiz 関数に3行目を追加します。

クイズ画面を作成した時に strings.xml に

<string name="count_label">Q%d</string>

と書きました。

getString メソッドを使って strings.xml に定義したこの文字列を取得して、第2引数に %d の部分に入れる数値を指定しています。

5. アプリを実行する

エミュレータでアプリを実行してみましょう。

正解・不正解の判定が正しく行われ、クイズが連続して出題されるでしょうか?

もし上手く動かない場合は下にサンプルコードを貼ってあるのでご確認ください。

次に行うこと

これでメインのクイズ機能は完成です!

次回からは結果画面を作成していきましょう。

ここまでのコード

Q
MainActivity.kt
package com.example.quizapp

import android.os.Bundle
import android.view.View
import android.widget.Button
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.example.quizapp.databinding.ActivityMainBinding
import com.google.android.material.dialog.MaterialAlertDialogBuilder

class MainActivity : AppCompatActivity() {

    companion object {
        const val QUIZ_COUNT = 5
    }

    private lateinit var binding: ActivityMainBinding
    private var rightAnswer: String? = null
    private var rightAnswerCount = 0
    private var quizCount = 1

    private val quizData = mutableListOf(
        mutableListOf("北海道", "札幌市", "長崎市", "福島市", "前橋市"),
        mutableListOf("青森県", "青森市", "広島市", "甲府市", "岡山市"),
        mutableListOf("岩手県", "盛岡市", "大分市", "秋田市", "福岡市"),
        mutableListOf("宮城県", "仙台市", "水戸市", "岐阜市", "福井市"),
        mutableListOf("秋田県", "秋田市", "横浜市", "鳥取市", "仙台市"),
        mutableListOf("山形県", "山形市", "青森市", "山口市", "奈良市"),
        mutableListOf("福島県", "福島市", "盛岡市", "新宿区", "京都市"),
        mutableListOf("茨城県", "水戸市", "金沢市", "名古屋市", "奈良市"),
        mutableListOf("栃木県", "宇都宮市", "札幌市", "岡山市", "奈良市"),
        mutableListOf("群馬県", "前橋市", "福岡市", "松江市", "福井市")
    )

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
            insets
        }

        binding.answerBtn1.setOnClickListener { checkAnswer(it) }
        binding.answerBtn2.setOnClickListener { checkAnswer(it) }
        binding.answerBtn3.setOnClickListener { checkAnswer(it) }
        binding.answerBtn4.setOnClickListener { checkAnswer(it) }

        quizData.shuffle()

        showNextQuiz()
    }

    // クイズを出題する
    private fun showNextQuiz() {
        // カウントラベルの更新
        binding.countLabel.text = getString(R.string.count_label, quizCount)

        // クイズを1問取り出す
        val quiz = quizData[0]

        // 問題をセット
        binding.questionLabel.text = quiz[0]

        // 正解をセット
        rightAnswer = quiz[1]

        // 都道府県名を削除
        quiz.removeAt(0)

        // 正解と選択肢3つをシャッフル
        quiz.shuffle()

        // 正解と選択肢をセット
        binding.answerBtn1.text = quiz[0]
        binding.answerBtn2.text = quiz[1]
        binding.answerBtn3.text = quiz[2]
        binding.answerBtn4.text = quiz[3]

        // 出題したクイズを削除する
        quizData.removeAt(0)
    }

    // 解答ボタンが押されたら呼ばれる
    private fun checkAnswer(view: View) {
        // どの解答ボタンが押されたか
        val answerBtn: Button = findViewById(view.id)
        val btnText = answerBtn.text.toString()

        // ダイアログのタイトルを作成
        val alertTitle: String
        if (btnText == rightAnswer) {
            alertTitle = "正解!"
            rightAnswerCount++
        } else {
            alertTitle = "不正解..."
        }

        // ダイアログを作成
        MaterialAlertDialogBuilder(this)
            .setTitle(alertTitle)
            .setMessage("答え : $rightAnswer")
            .setPositiveButton("OK") { dialogInterface, i ->
                checkQuizCount()
            }
            .setCancelable(false)
            .show()
    }

    // 出題数をチェックする
    private fun checkQuizCount() {
        if (quizCount == QUIZ_COUNT) {
            // 結果画面を表示

        } else {
            quizCount++
            showNextQuiz()
        }
    }
}
Subscribe
Notify of
8 Comments
古い順
新しい順 人気順
Inline Feedbacks
View all comments
macaron
8 months ago

2. checkAnswer 関数
https://codeforfun.jp/android-studio-quiz-game-with-kotlin-5/

18行目のコードについての質問です
コードでは「$rightAnswer」になっていますが、
エラーになります。これは「rightAnswer」ではないでしょうか?
知識不足でしたらすみません。お忙しいこととは思いますが、
ご確認よろしくお願いいたします

macaron
8 months ago
Reply to  Sara

違う箇所でエラーになっていたようで、無事修正することができました。返信いただきましてありがとうございました。

macaron
8 months ago

$rightAnswerについて質問させていただいたものです。
$がどういう意味なのかを調べようと「kotolin $ 使い方」「kotolin $ 意味」などで検索してみたのですがページがうまく探せませんでした。
何かヒントになるようなことでも構いません、ご教授いただけますと幸いです。
よろしくお願いいたします。

macaron
8 months ago
Reply to  Sara

いつもお返事ありがとうございます😭
こんなシンプルな記述で文字列に変数を埋め込めるんですね!
まだまだ知らないことだらけですが、
少しずつ学習を進めていきたいと思います。
今後もよろしくお願いいたします。

ABOUT ME
Sara
Sara
運営者
書籍やオンライン講座でプログラミングを勉強してフリーランスのプログラマーになりました。
このサイトでは「わかりやすく・シンプル」をモットーに、プログラミングの基礎からアプリ開発まで紹介します。
独学でプログラミングを勉強をしている方、基礎は勉強したけれど次に何をすれば良いか分からない...という方のお役に立てるサイトを目指しています。
主な使用言語:Java / Kotlin / PHP
>> 詳しいプロフィール
>> お問い合わせ
>> 書籍を出版しました!
本格的に学びたい方へ

Code for Fun プログラミング講座

POINT 01

動くコード

プログラミングの文法を学んでも、そこからどのようにアプリ開発ができるのかイメージが湧きにくいものです。

Code for Fun のプログラミング講座では、ゲームやカレンダーなどアプリとして機能するものを作りながらプログラミングを学ぶことができます。

POINT 02

自分のペースで

オンライン講座なので、ご自身のペースで学習を進めて頂けます。

受講期限もないので、いつでも前のレッスンに戻ることができるので安心です。

お申し込みしたその日からすぐに始めることができます。

POINT 03

個別サポート

プログラミング学習では、エラーが起きることはよくあります。そんな時はお気軽にお問い合わせください!

コメント欄またはメールによるサポートを回数無制限でご利用頂けます。(*講座に関連するご質問のみ対応)

今すぐ無料でお試し

8
0
この記事にコメントするx
記事URLをコピーしました