【Android Studio】クイズアプリ開発講座 第4回「問題と選択肢を表示する」
前回はクイズを管理する配列を作成しました。
今回はその配列からクイズを取り出して画面に表示してみましょう。
問題と選択肢を表示する
1. 問題と選択肢のセット
まずはクイズ出題用のメソッドを作成します。
5〜23行目を追加します。
7行目:Warning の解消
countLabel.setText(getString(R.string.count_label, quizCount));
クイズ画面を作成したときに strings.xml に用意した文字列
<string name="count_label">Q%d</string>
の %d 部分に値をセットしています。
1つ目の引数には strings.xml に定義した文字列を R.string.名前 と書いて、2つ目の引数には %d 部分に入れる数値を指定します。
10行目
ArrayList<String> quiz = quizArray.get(0);
quizArrayから0番目のクイズを取り出しています。
取り出したクイズは
{"都道府県名", "正解", "選択肢1", "選択肢2", "選択肢3"}
の順番で要素が入っています。
questionLabel には都道府県名を表示するので quiz.get(0) で quiz 配列から取り出します。
questionLabel.setText(quiz.get(0));
rightAnswer には正解を入れておくので quiz.get(1) で quiz 配列から取り出します。
rightAnswer = quiz.get(1);
2. showNextQuiz を呼び出す
アプリを起動したらすぐにクイズが出題されるように、onCreate メソッド内で showNextQuiz メソッドを呼び出します。
5行目を追加します。
3. アプリを実行
アプリをエミュレータで実行してみましょう。
quizArray の最初の要素である「北海道」の問題と選択肢が表示されたでしょうか?
4. 出題順をシャッフル
Collections クラスには、ArrayList の要素をシャッフルできる shuffle メソッドが用意されています。
たった1行書くだけで出題順をシャッフルすることができます。
5行目を追加します。
5. 選択肢をシャッフル
次にボタンに表示する選択肢をシャッフルします。
quizArray は「ArrayList の中に ArrayList を入れた2次元 ArrayList」にしたので、取り出した quiz も ArrayList 型になっています。
同じように shuffle メソッドを使うことができますが、今回は都道府県を取り出してからシャッフルします。
showNextQuiz メソッドに15・18・27行目を追加、21〜24行目は添字を変更します。
15行目
quiz.remove(0);
都道府県名はボタンに表示する選択肢ではないので削除しておきます。
18行目
Collections.shuffle(quiz);
都道府県名は削除したので、この時点で quiz リストに残っているのは正解と3つの選択肢です。
これら4つの順番を shuffle メソッドを使ってシャッフルします。
シャッフルしてから解答ボタンにセットすることで、毎回違う順番で選択肢を表示できるようになります。
27行目
quizArray.remove(0);
同じクイズが出題されないように quizArray から問題を削除しておきます。
6. アプリを実行
クイズがランダムに表示されるかエミュレータで確認してみましょう。
ランダムに出題されるかを確認するために、一度アプリを終了して再度開いてみてください。
問題文が変わって、解答ボタンの順番もシャッフルされているでしょうか?
次に行うこと
次回はクイズアプリで一番重要な機能「正解・不正解の判定」を実装していきます。
ここまでのコード
- MainActivity.java
-
package com.example.quizapp; import android.os.Bundle; import androidx.activity.EdgeToEdge; import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; import com.example.quizapp.databinding.ActivityMainBinding; import java.util.ArrayList; import java.util.Collections; public class MainActivity extends AppCompatActivity { private ActivityMainBinding binding; private String rightAnswer; private int rightAnswerCount; private int quizCount = 1; private ArrayList<ArrayList<String>> quizArray = new ArrayList<>(); private String[][] quizData = { // {"都道府県名", "正解", "選択肢1", "選択肢2", "選択肢3"} {"北海道", "札幌市", "長崎市", "福島市", "前橋市"}, {"青森県", "青森市", "広島市", "甲府市", "岡山市"}, {"岩手県", "盛岡市","大分市", "秋田市", "福岡市"}, {"宮城県", "仙台市", "水戸市", "岐阜市", "福井市"}, {"秋田県", "秋田市","横浜市", "鳥取市", "仙台市"}, {"山形県", "山形市","青森市", "山口市", "奈良市"}, {"福島県", "福島市", "盛岡市", "新宿区", "京都市"}, {"茨城県", "水戸市", "金沢市", "名古屋市", "奈良市"}, {"栃木県", "宇都宮市", "札幌市", "岡山市", "奈良市"}, {"群馬県", "前橋市", "福岡市", "松江市", "福井市"}, }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); EdgeToEdge.enable(this); binding = ActivityMainBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); return insets; }); // quizDataからクイズ出題用のquizArrayを作成する for (int i = 0; i < quizData.length; i++) { // 新しいArrayListを準備 ArrayList<String> tmpArray = new ArrayList<>(); // クイズデータを追加 tmpArray.add(quizData[i][0]); // 都道府県名 tmpArray.add(quizData[i][1]); // 正解 tmpArray.add(quizData[i][2]); // 選択肢1 tmpArray.add(quizData[i][3]); // 選択肢2 tmpArray.add(quizData[i][4]); // 選択肢3 // tmpArrayをquizArrayに追加する quizArray.add(tmpArray); } Collections.shuffle(quizArray); showNextQuiz(); } private void showNextQuiz() { // クイズカウントラベルを更新 binding.countLabel.setText(getString(R.string.count_label, quizCount)); // quizArrayからクイズを1つ取り出す ArrayList<String> quiz = quizArray.get(0); // 問題文(都道府県名)を表示 binding.questionLabel.setText(quiz.get(0)); // 正解をrightAnswerにセット rightAnswer = quiz.get(1); // クイズ配列から問題文(都道府県名)を削除 quiz.remove(0); // 正解と選択肢3つをシャッフル Collections.shuffle(quiz); // 解答ボタンに正解と選択肢3つを表示 binding.answerBtn1.setText(quiz.get(0)); binding.answerBtn2.setText(quiz.get(1)); binding.answerBtn3.setText(quiz.get(2)); binding.answerBtn4.setText(quiz.get(3)); // このクイズをquizArrayから削除 quizArray.remove(0); } }
初めての質問失礼致します。
最近から勉強を始め、分かりやすく、楽しく勉強させて頂いております。
クイズアプリ開発のエラーについて2つ質問があります。
「//randomNumを使ってquizArrayからクイズをひとつ取り出す」の部分のコードの部分にエラーが出てしまいます。互換性のない型です、と出ます。どうしたら宜しいでしょうか。
また、「//正解をrightAnswerにセット」のコードでもエラーが出てしまいました。java.util.ArrayListのset(int.java.lang.String)は(int)に適用できません、と出ます。
以上となります。
初歩的な点かと思い恐縮ですが、ご教示頂けると嬉しいです。
宜しくお願い致します。
はじめまして、当サイトを見つけていただきありがとうございます!
以下のサンプルコードでテストしたところ問題ありませんでしたので、もう一度ご自身のコード(特に ArrayList 周辺)をご確認ください。
https://codeforfun.jp/android-studio-4x-quiz-game-4/#i-3
2つ目のエラーは1つ目のエラーが解決できれば解消するはずです。
サンプルコードを使ってもエラーになってしまう場合は、コードのスクリーンショット添付して頂ければと思います。
先ほどの質問した者です。
情報が抜けており失礼しました。
開発環境はwindows10、アンドロイドスタジオ(2021.11.15インストール)になります。
宜しくお願い致します。
Sara様
お世話になります。
第4回まで、なんとか出来たので実行したのですが、
4つのエラーが表示されてうまくいきませんでした。
onClick method does not exist
ボタン1~4についてこのようなエラーが生じました。
どのあたりにミスがあったのかご教示いただけませんか。
よろしくお願いいたします。
当サイトを見つけて頂きありがとうございます!
をご確認ください。
onClick 属性を使った書き方は非推奨となっていますが、この記事では考慮せずに進めています。
もし onClickListener を使ってコードをお書きになっている場合は checkAnswer メソッドではなく、onClick メソッドを書いているかをご確認ください。
開発環境が記入漏れでしたすみません。
環境はwin10proで最新のandroid studio javaで行っています。
石井
初めての質問失礼致します。
Splitの右画面がエミュレータ画面だと思うのですが、表示される問題番号が%dのままだったりjavaファイルでアレンジした配列が問題文や選択肢にちっとも反映されないのですが、何かおかしいのでしょうか?
開発環境はAndroid Studio Flamingoです(2023年4月21日ダウンロード)
当サイトを見つけていただきありがとうございます!
Splitの右側は「プレビュー画面」なので、activity_main.xml に書いたものが反映されているだけの状態です。
問題番号や問題文はアプリを実行する(エミュレータで動かす)と反映されます。
エミュレータも右側に表示されるので分かりにくいかもしれませんがご確認ください。
参考までに、エミュレータを Android Studio とは別ウィンドウで開く方法を以下のページで紹介しています。
https://codeforfun.jp/android-studio-how-to-run-emulator-in-a-separate-window/
先ほど質問したものです。
「エミュレータをAndroid Studioとは別ウィンドウで開く方法」を試してみたのですが、ただ「Launch in a tool window」の項目のチェックを外しただけなのに自分の作ったアプリが正しく動くようになりました。アドバイスありがとうございました!
ご報告ありがとうございます。
動いたとのこと良かったです!