2017-06-26 63 views
0

製作一個簡單的BrainTrain應用程序,updateAnswer方法給出了問題的隨機答案,但是每當我調用optionsPressed方法並嘗試獲取任何對象時,問題就會出現,arrayList會給出IndexOutOfBoundsException爲什麼數組列表被稱爲optionPressed方法時清空自身?

package com.example.nishantsaini.braintrain; 

import android.graphics.Color; 
import android.graphics.drawable.ColorDrawable; 
import android.graphics.drawable.Drawable; 
import android.os.CountDownTimer; 
import android.support.v4.content.ContextCompat; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 
import android.widget.Button; 
import android.widget.LinearLayout; 
import android.widget.TextView; 

import java.util.ArrayList; 
import java.util.Random; 

import static android.R.color.black; 
import static android.R.color.holo_blue_bright; 
import static android.R.color.holo_blue_dark; 
import static android.R.color.holo_blue_light; 
import static android.R.color.holo_green_light; 



public class MainActivity extends AppCompatActivity { 

Random rnd = new Random(); 
boolean gameisActive = false; 
int count = 0; 
CountDownTimer cd; 
int var1,var2; 
ArrayList<Button> options; 




@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    cd = new CountDownTimer(30000, 1000) { 
     @Override 
     public void onTick(long l) { 
      Log.i("Time Left:", Long.toString(l/1000)); 
      TextView timer = (TextView) findViewById(R.id.timer); 
      timer.setText("0:" + String.format("%02d", (l/1000))); 

     } 

     @Override 
     public void onFinish() { 
      TextView score = (TextView) findViewById(R.id.Score); 
      LinearLayout onFinishLayout = (LinearLayout) findViewById(R.id.onFinishLayout); 
      /*score.setText("You got " + getScore() + "right!"); 
      */ 

     } 
    }; 
    options = new ArrayList<>(); 
    options.add((Button) findViewById(R.id.option2)); 
    options.add((Button) findViewById(R.id.option1)); 
    options.add((Button) findViewById(R.id.option3)); 
    options.add((Button) findViewById(R.id.option4)); 
} 

public void start(View view) { 



    cd.start(); 

    Button start = (Button) findViewById(R.id.start); 
    updateQuestion(); 
    updateAnswers(options); 

    start.setText("Replay"); 

} 

public void optionPressed(View view){ 

    ColorDrawable blue_d = new ColorDrawable(getResources().getColor(R.color.blue_b)); 
    ColorDrawable blue_l = new ColorDrawable(getResources().getColor(R.color.blue_l)); 
    ColorDrawable blue_b = new ColorDrawable(getResources().getColor(R.color.blue_b)); 
    ColorDrawable green = new ColorDrawable(getResources().getColor(R.color.green)); 

    Drawable color = blue_b; 
    while(options.size() > 0) { 
     int index = rnd.nextInt(options.size()); 
     Button b = options.get(index); 

     if (color == blue_b){ 
      color = blue_d; 
      b.setBackground(color); 
     } 
     else if (color == blue_d){ 
      color = green; 
      b.setBackground(color); 

     } 
     else if (color == green){ 
      color = blue_l; 
      b.setBackground(color); 

     } 
     else if (color == blue_l) 
     { 
      color = blue_b; 
      b.setBackground(color); 
     } 
     options.remove(index); 
    } 

    updateQuestion(); 
    updateScore(); 
    updateAnswers(options); 

} 

public void updateQuestion(){ 
    var1 = 5 + (int)(Math.random()*20); 
    var2 = 5 + (int)(Math.random()*20); 
    TextView question = (TextView) findViewById(R.id.question); 
    question.setText(Integer.toString(var1) +" + " + Integer.toString(var2) + " = "); 
    question.setPadding(0,50,0,0); 
} 

public void updateScore(){ 

    count++; 
    int correct = 0; 
    TextView score = (TextView) findViewById(R.id.points); 
    score.setText(Integer.toString(correct) + "/" + Integer.toString(count)); 
} 

public void updateAnswers(ArrayList<Button> arrayList){ 

    Button b; 
    int answer = var1 + var2; 
    int indexAtWhichRealAnswerGoes = 1+ (int) (Math.random()*3); 
    int id ; 
    Log.i("arraylist size",Integer.toString(options.size())); 

    b = arrayList.get(indexAtWhichRealAnswerGoes); 
    b.setText(Integer.toString(answer)); 
    id = b.getId(); 
    arrayList.remove(indexAtWhichRealAnswerGoes); 
    for (int i = 0; i < arrayList.size(); i++) { 
     int randomanswer = (answer-7) + (int)(Math.random()*(answer+7)); 
     b = arrayList.get(i); 
     b.setText(Integer.toString(randomanswer)); 

    } 
    arrayList.add((Button) findViewById(id)); 
    Log.i("arraylist size",Integer.toString(arrayList.size())); 

} 
} 
+1

請張貼堆棧跟蹤任何影響更新列表copyOptions,但我敢肯定,這來自'INT indexAtWhichRealAnswerGoes = 1 +(INT )(Math.random()* 3); ... arrayList.get(indexAtWhichRealAnswerGoes);'在'while(options.size()> 0){.. options.remove(randomIndex);}'清空的列表上''檢查那裏的邏輯。但是你清楚地清除了該列表中的所有選項。 – AxelH

+0

從哪裏調用'optionPressed'這個方法? –

+1

伴隨異常的細節消息和堆棧跟蹤是第一個要看的東西,甚至在代碼之前。如果你想要我們的幫助,那麼至少要提供那些幫助然而,一般來說,我們希望看到[mcve]。從GUI應用程序生成這可能有點棘手,但從另一方面來看,構建一個應用程序的過程很有可能幫助您發現自己的錯誤。 –

回答

0

所以,你使用以前清空

while(options.size() > 0) { 
    int index = rnd.nextInt(options.size()); 
    ... 
    options.remove(index); 
} 
... 
updateAnswers(options); 

此時列表調用updateAnswers(options);,列表是空的。

在該方法中,您放心使用for (int i = 0; i < arrayList.size(); i++) {,以防止任何錯誤之前,我們看到

int indexAtWhichRealAnswerGoes = 1+ (int) (Math.random()*3); 
... 
b = arrayList.get(indexAtWhichRealAnswerGoes); 

你得到的是不檢查列表的大小隨機指數。 (List在那一點是空的)。


如果你想保持列表中,其價值,但邏輯不能改變,因此remove是必要的,你需要做的名單的副本上一個工作,並通過原來的方法updateAnswers

List<Button> copyOptions = new ArrayList<>(options); 

將共享相同的實例,但你可以不必在options

+0

是的,這個工作很完美,非常感謝 –