#android #arrays #static #indexoutofboundsexception
#Android #массивы #статический #исключение indexoutofboundsexception
Вопрос:
Я добавил действие для викторины в свое приложение. Я использую целочисленный массив selected_options
для хранения параметров, выбранных пользователем. Тест показывает пользователю 5 вопросов за попытку и сохраняет их в массиве, затем я добавил действие «Решения», в котором параметры, выбранные пользователем, отображаются красным цветом, если ответ неправильный, и зеленым в противном случае. У меня нет проблем с отображением зеленого цвета, поскольку я напрямую вызываю ответ из базы данных и выделяю соответствующим образом.
Но я сталкиваюсь с проблемой при выделении неправильных параметров, выбранных пользователем, поскольку selected_options
массив работает не так, как я хочу. Кроме того, я получаю java.lang.ArrayIndexOutOfBoundsException: length=4; index=4
сообщение об ошибке, когда я достигаю нижней части ScrollView в активности solutions, и активность завершается сбоем.
Вот как я объявляю переменную selected_options
:
public static final ArrayList<questionObject> selected_questions = new ArrayList<>();
public static int[] selected_options;
public ArrayList<questionObject> resu<
public ArrayList<questionObject> seen_questions;
TextView question, option1_text, option2_text, option3_text, option4_text, qCount;
ConstraintLayout[] options = new ConstraintLayout[4];
DatabaseReference databaseReference;
String currentUserID;
private Dialog loadingDialog;
private int quesNum;
private int score;
Вот как я инициализирую его в onCreate()
функции:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStatusBarGradiant(this);
setContentView(R.layout.quiz_activity);
seen_questions = new ArrayList<>();
result = new ArrayList<>();
selected_options = new int[5];
question = findViewById(R.id.question_text);
qCount = findViewById(R.id.quest_num);
Вот как я добавляю выбранные параметры в onClick()
метод:
public void onClick(View view) {
int selectedOption = 0;
switch (view.getId()) {
case R.id.option_1_tile:
selectedOption = 1;
break;
case R.id.option_2_tile:
selectedOption = 2;
break;
case R.id.option_3_tile:
selectedOption = 3;
break;
case R.id.option_4_tile:
selectedOption = 4;
break;
default:
}
selected_options[quesNum] = selectedOption;
checkAnswer(selectedOption, view);
}
И вот как я пытаюсь использовать его в quizAdater
:
class questionAdapter extends BaseAdapter {
TextView question, option1_text, option2_text, option3_text, option4_text, explanation, source;
ConstraintLayout[] options = new ConstraintLayout[4];
private Context context;
private ArrayList<questionObject> questions = quizActivity.selected_questions;
private int[] optionsSelected = quizActivity.selected_options;
public questionAdapter(Context context, ArrayList<questionObject> arrayList) {
this.context = context;
this.questions = arrayList;
}
@Override
public int getCount() {
return questions.size();
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = LayoutInflater.from(context).inflate(R.layout.quiz_solutions_row, parent, false);
question = convertView.findViewById(R.id.question_text);
option1_text = convertView.findViewById(R.id.option_1_text);
option2_text = convertView.findViewById(R.id.option_2_text);
option3_text = convertView.findViewById(R.id.option_3_text);
option4_text = convertView.findViewById(R.id.option_4_text);
explanation = convertView.findViewById(R.id.explanation);
source = convertView.findViewById(R.id.source_button);
options[0] = convertView.findViewById(R.id.option_1_tile);
options[1] = convertView.findViewById(R.id.option_2_tile);
options[2] = convertView.findViewById(R.id.option_3_tile);
options[3] = convertView.findViewById(R.id.option_4_tile);
question.setText(questions.get(position).getQuestion());
option1_text.setText(questions.get(position).getOption1());
option2_text.setText(questions.get(position).getOption2());
option3_text.setText(questions.get(position).getOption3());
option4_text.setText(questions.get(position).getOption4());
explanation.setText("Explanation: " questions.get(position).getExplanation());
source.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent i = new Intent(context, urlActivity.class);
i.putExtra("url", questions.get(position).getSource());
i.putExtra("name", "Information Source");
context.startActivity(i);
}
});
if (optionsSelected[position] != questions.get(position).getAnswer()) {
options[position].setBackgroundTintList(ColorStateList.valueOf(Color.RED));
}
switch (questions.get(position).getAnswer()) {
case 1:
options[0].setBackgroundTintList(ColorStateList.valueOf(Color.GREEN));
break;
case 2:
options[1].setBackgroundTintList(ColorStateList.valueOf(Color.GREEN));
break;
case 3:
options[2].setBackgroundTintList(ColorStateList.valueOf(Color.GREEN));
break;
case 4:
options[3].setBackgroundTintList(ColorStateList.valueOf(Color.GREEN));
break;
}
return convertView;
}
}
Вот фиктивный код, запрошенный пользователем:
-
объявите целочисленную переменную массива
selected_options
в классе quizActivity -
Инициализируйте целочисленный массив в
onCreate()
методе какselected_options = new int[5];
-
Добавьте выбранный пользователем вариант (пользователю показывается 5 вопросов, и у каждого есть 4 варианта) как 1 — для варианта A, 2 — для варианта 2 и так далее
-
В
quizAdapter
классе инициируйте целочисленный массивoptionsSelected
и сохраните в нем значения массива переменныхselected_options
из класса quizActivity, используяprivate int[] optionsSelected = quizActivity.selected_options;
-
Если пользователь выбрал неправильную опцию, отобразите выбранную им опцию красным цветом в упражнении решения, используя
if (optionsSelected[position] != questions.get(position).getAnswer()) {
options[position].setBackgroundTintList(ColorStateList.valueOf(Color.RED)); }
Я проверил журналы, и переменная quesNum
правильно меняется с 0 на 4, и selected_options
массив также работает должным образом, поэтому я не могу отладить то, что может быть причиной проблемы
Комментарии:
1.
selected_options = new int[4];
2. правильна ли остальная часть реализации для моего варианта использования? И почему
int[4]
?3. У меня есть 5 вопросов за попытку, так что не должно быть
[5]
? И это приводит к сбою теста по самому последнему вопросу4.
doing that crashes the quiz on the last question itself
какая строка? вы отлаживали?5.
java.lang.ArrayIndexOutOfBoundsException: length=4; index=4 at inspire2connect.inspire2connect.quiz.quizActivity.onClick(quizActivity.java:345)
selected_options[quesNum] = selectedOption;
в строкеonClick()
метода, который я привел выше
Ответ №1:
Добавьте проверку перед установкой selectedOption в список, как показано ниже —
if(quesNum < 4){
selected_options[quesNum] = selectedOption;
checkAnswer(selectedOption, view);
}
Проверьте, когда и где вы увеличиваете значение quesNum . Попробуйте вывести его значение перед получением индекса из списка. Это 4, поэтому происходит сбой, потому что значение индекса больше размера списка.
Комментарии:
1. не должно ли это быть
(quesNum < 5)
потому, что у меня всего 5 вопросов, которые нужно показать?2. Согласно вашим журналам сбоев, происходит сбой для индекса 4. Вот почему я попросил напечатать значение для quesNum. Вы узнаете точное значение и проблему.
3. он регистрируется только как 0, 1, 2, 3, 4. В чем тогда может быть проблема?
4. Теперь проверьте, попробуйте напечатать размер списка selected_options. Если размер списка печатает 5, нам нужно отладить код. Но если размер списка напечатает 4, то сбой очевиден.
5.
2020-09-30 15:27:23.281 32701-32701/inspire2connect.inspire2connect D/Size: Value: 5 2020-09-30 15:27:44.652 32701-32701/inspire2connect.inspire2connect D/Size: Value: 5 2020-09-30 15:27:48.467 32701-32701/inspire2connect.inspire2connect D/Size: Value: 5 2020-09-30 15:27:52.678 32701-32701/inspire2connect.inspire2connect D/Size: Value: 5 2020-09-30 15:27:55.101 32701-32701/inspire2connect.inspire2connect D/Size: Value: 5