java .lang.IndexOutOfBoundsException в Android Java - PullRequest
0 голосов
/ 03 февраля 2020

Я создаю учебное приложение, которое будет включать в себя игры. Одной из игр является викторина «истина» или «ложь», когда пользователь нажимает «истина» или «ложь», когда на экране появляется утверждение.

Некоторые из утверждений работают, когда я отвечаю «истина» или «ложь», но после пары утверждений приложение завершается с ошибкой индекса вне границ.

У меня есть класс для игры и класс для утверждений и их соответствующих ответов.

Когда я запускаю приложение, после нескольких вопросов приложение закрывается, и я получаю эти ошибки.

 Process: com.example.securityapp, PID: 28776
    java.lang.IndexOutOfBoundsException: Index: 8, Size: 8
        at java.util.ArrayList.get(ArrayList.java:437)
        at 

com.example.securityapp.industry_standards_questions.checkAnswer(industry_standards_questions.java:104)
        at com.example.securityapp.industry_standards_questions.access$000(industry_standards_questions.java:20)
        at com.example.securityapp.industry_standards_questions$2.onClick(industry_standards_questions.java:71)

package com.example.securityapp;

import androidx.annotation.StringRes;
import androidx.appcompat.app.AppCompatActivity;

import android.media.Image;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewAnimator;

import org.w3c.dom.Text;

import java.util.ArrayList;
import java.util.Collections;

public class industry_standards_questions extends AppCompatActivity {

    TextView stmnt;
    ImageView image_true, image_false;
    Button points;

    Statements tfStatements;
    int statementsLength;

    ArrayList<Item> statementList;
    int currentStatement = 0;
    int grade = 0;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_industry_standards_questions);

        stmnt = (TextView) findViewById(R.id.statement_TV);

        image_true = (ImageView) findViewById(R.id.trueImage);
        image_false = (ImageView) findViewById(R.id.falseImage);

        tfStatements = new Statements();
        statementsLength = tfStatements.tfStatements.length;

        statementList = new ArrayList<>();

        points = (Button) findViewById(R.id.final_score);

        for(int i = 0; i < statementsLength; i++){
            statementList.add(new Item(tfStatements.getStatment(i), tfStatements.getAnswer(i)));
        }

        Collections.shuffle(statementList);

        setStmnt(currentStatement);

        points.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                score();
            }
        });

        image_true.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                currentStatement++;
                if(checkAnswer(currentStatement)){
                    grade++;
                    if(currentStatement < statementsLength){
                        setStmnt(currentStatement);
                    }
                }
            }
        });

        image_false.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                currentStatement++;
                if(!checkAnswer(currentStatement)){
                    grade++;
                    if(currentStatement < statementsLength){
                        setStmnt(currentStatement);

                    }
                }

            }
        });

    }

    // show Statement
    private void setStmnt(int number){
        stmnt.setText(statementList.get(number).getStatement());
    }

    //check is answer is right
    private boolean checkAnswer(int number){
        String answer = statementList.get(number).getAnswer();
        return answer.equals("true");
    }

    public void score(){
     Toast.makeText(this, "You scored " + grade + " points!", Toast.LENGTH_LONG).show();
     grade = 0;
 }

}

package com.example.securityapp;

public class Statements {

    public String tfStatements [] = {

            "10% of U.S. companies use the Cybersecurity Framework",
            "Prevent is an element within the framework",
            "Respond is an element within the framework",
            "Access control is a future priority",
            "Risk Assessment is a current priority",
            "Asset management is a current priority",
            "The framework can be customised",
            "By 2020, an estimated 70% of U.S. companies will use the framework"
    };

    public String tfAnswers [] = {
            "false",
            "false",
            "true",
            "false",
            "true",
            "true",
            "true",
            "false"

    };

    public String getStatment (int number) {
        return tfStatements[number];
    }

    public String getAnswer (int number) {
        return tfAnswers[number];
    }



}

Это класс операторов

package com.example.securityapp;

public class Statements {

    public String tfStatements [] = {

            "10% of U.S. companies use the Cybersecurity Framework",
            "Prevent is an element within the framework",
            "Respond is an element within the framework",
            "Access control is a future priority",
            "Risk Assessment is a current priority",
            "Asset management is a current priority",
            "The framework can be customised",
            "By 2020, an estimated 70% of U.S. companies will use the framework"
    };

    public String tfAnswers [] = {
            "false",
            "false",
            "true",
            "false",
            "true",
            "true",
            "true",
            "false"

    };

    public String getStatment (int number) {
        return tfStatements[number];
    }

    public String getAnswer (int number) {
        return tfAnswers[number];
    }



}

1 Ответ

0 голосов
/ 03 февраля 2020

Я думаю, вам следует изменить onClick ваших кнопок следующим образом:

image_true.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(checkAnswer(currentStatement)){
                    grade++;
                    if(currentStatement < statementsLength -1)
                        setStmnt(currentStatement);
                }
                currentStatement++;
            }
        });

image_false.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(!checkAnswer(currentStatement)){
                    grade++;
                    if(currentStatement < statementsLength -1)
                        setStmnt(currentStatement);
                }
                currentStatement++;
            }
        });

С вашим кодом, когда пользователь отвечает на 8-й вопрос, вы проверяете ответ в позиции 8, но последний элемент вашего tfAnswers имеет индекс 7.

Однако в вашем коде есть кое-что, чего я не понимаю: эта строка:

String answer = statementList.get(number).getAnswer();

и, точно, вызов getAnswer на String, без передачи аргументов, в то время как определение метода равно

public String getAnswer (int number) {
    return tfAnswers[number];
}

То есть с параметром int, поэтому я бы назвал его следующим образом:

String answer = tfStatements.getAnswer(number);

Но я думаю, что ошибки там не заканчиваются, я бы использовал ваши методы следующим образом:

private boolean checkAnswer(int number, String givenAnswer){
    String answer = tfStatements.getAnswer(number);
    return answer.equals(givenAnswer);
}

И вызывал бы таким образом:

image_true.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(checkAnswer(currentStatement, "true"))
                    grade++;
                currentStatement++;
                if(currentStatement < statementsLength -1)
                    setStmnt(currentStatement)
            }
        });

image_false.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(checkAnswer(currentStatement, "false"))
                    grade++;
                currentStatement++;
                if(currentStatement < statementsLength -1)
                    setStmnt(currentStatement);
            }
        });

By кстати, рассмотрите возможность использования этого вместо tfAnswers:

public boolean tfAnswers [] = {
            false,
            false,
            true,
            false,
            true,
            true,
            true,
            false

    };

и использования static Statements класса.

...