使用随机数生成显示来自arraylist的图像

时间:2016-08-17 05:47:57

标签: android arraylist random android-image

简要说明:应用程序将根据单词库文件中的单词向用户显示随机图像,用户必须识别图像的名称(单个单词)。用户可以通过"通过"通过单击传递按钮或识别图像,然后单击"下一步"按钮将弹出,指示他们到下一个图像。

问题: 当我尝试按下一个按钮时,应用程序会在新的下一个按钮出现之前不断崩溃,并显示不同的图像。

我认为它与随机数生成器有关,或者与我放置的if语句有关。

我没有收到任何错误消息。我不确定是什么导致了这个问题。当我运行apk文件时,当它崩溃时它会说"不幸的是,pic停止了#34; " PIC"是应用名称。

修改 当我通过模拟器运行应用程序时,我收到了运行时错误消息,如下所示

单击下一个按钮并切换到下一个按代码随机化的图像:

        randomNum = (random.nextInt(UnSpokenList.size()) + 1);

第一个元素,包含" Word Bank:"这不是一个图像,它只是单词列表的名称,所以我做了random.nextInt(maxsize)+1,我假设避免0,第一个元素,但当它归结为arraylist的大小2

(它在此部分之前崩溃,但是当点击下一个按钮时它也会崩溃。) 在onActivityResult函数中,当它大小为2或小于2时,它将停止显示下一个按钮并显示一个不同的下一个按钮,该按钮调用函数onlastPair,它根据arraylist的最后一个元素生成图像。

主要代码: 我从与问题无关的函数中取出了一些代码,希望找到主要问题会更容易。

    public class Main extends Activity implements AdapterView.OnItemSelectedListener {

    private static final int VR_Request = 100;

    Button restart;
    Button mainMenu;
    Button pass;
    Button next;
    Button last2image;

    TextView speechInput;
    TextView matchOrNot;
    TextView passTitle;
    TextView counterDisplay;

    String[] wordBank;
    ArrayList<String> wordBANK;

    Spinner wordList;
    Spinner SpokenWords;

    ArrayList<String> UnSpokenList;
    ArrayList<String> SpokenList;
    ArrayAdapter<String> wordList_adapter;
    ArrayAdapter<String> SpokenList_adapter;

    ImageButton speechBtn;

    ImageView image;
    Resources res;
    int resID;

    Random random;
    int randomNum;

    int previous;
    int passCounter;

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

        speechInput = (TextView) findViewById(R.id.english_word1);
        matchOrNot = (TextView) findViewById(R.id.matchOrNot1);
        passTitle = (TextView) findViewById(R.id.passedTitle);
        counterDisplay = (TextView) findViewById(R.id.passCounterText);

        wordBank = getResources().getStringArray(R.array.Words);

        speechBtn = (ImageButton) findViewById(R.id.mic_pic_button1);

        wordBANK = new ArrayList<String>(Arrays.asList(wordBank));
        image = (ImageView) findViewById(R.id.imageView1);
        res = getResources();

        restart = (Button) findViewById(R.id.restartButton1);
        mainMenu = (Button) findViewById(R.id.mainMenubutton1);
        pass = (Button) findViewById(R.id.passButton);
        next = (Button) findViewById(R.id.nextButton);
        last2image = (Button) findViewById(R.id.last2);

        pass.setClickable(true);

        wordList = (Spinner) findViewById(R.id.wordsList1);
        SpokenWords = (Spinner) findViewById(R.id.spokenWords1);

        UnSpokenList = new ArrayList<String>(Arrays.asList(wordBank));
        SpokenList = new ArrayList<String>(wordBank.length+1);

        UnSpokenList.add(0, "Word Bank:");
        SpokenList.add(0,"Spoken Words:");
        wordList_adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, UnSpokenList);
        wordList_adapter.setDropDownViewResource(android.R.layout.simple_spinner_item);
        wordList.setAdapter(wordList_adapter);
        SpokenList_adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, SpokenList);
        SpokenList_adapter.setDropDownViewResource(android.R.layout.simple_spinner_item);
        SpokenWords.setAdapter(SpokenList_adapter);

        random = new Random();
        randomNum = random.nextInt(UnSpokenList.size()-1);
        resID = res.getIdentifier(UnSpokenList.get(randomNum), "drawable", getApplication().getPackageName());
        image.setImageResource(resID);

        pass.setClickable(true);
        pass.setVisibility(View.VISIBLE);
        next.setClickable(false);
        next.setVisibility(View.INVISIBLE);
        speechBtn.setClickable(true);
        last2image.setVisibility(View.INVISIBLE);
        last2image.setClickable(false);
        passCounter = 0;

        restart.setVisibility(View.INVISIBLE);
        mainMenu.setVisibility(View.INVISIBLE);


        passTitle.setVisibility(View.INVISIBLE);
        counterDisplay.setVisibility(View.INVISIBLE);
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        parent.getItemAtPosition(position);
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {

    }



    public void onMicButton(View view) {

    }

    /**
     * When the next button is pressed, this function handles the next random image to be displayed
     * @param view
     */
    public void onNext(View view){
        if(view.getId() == R.id.nextButton){
            speechInput.setText("");
            matchOrNot.setText("");

            randomNum = (random.nextInt(UnSpokenList.size()) + 1);

            resID = res.getIdentifier(UnSpokenList.get(randomNum), "drawable", getApplication().getPackageName());
            image.setImageResource(resID);

            next.setClickable(false);
            next.setVisibility(View.INVISIBLE);

            pass.setClickable(true);
            pass.setVisibility(View.VISIBLE);

            speechBtn.setClickable(true);
        }
    }

    /**
     * This function occurs when the user plays all the way to last 2 image left in game
     */
    public void onlastPair(View view){
        if(view.getId() == R.id.last2){
            if(!UnSpokenList.get(UnSpokenList.size()).contains("Word Bank:")) {
                resID = res.getIdentifier(UnSpokenList.get(UnSpokenList.size()), "drawable", getApplication().getPackageName());
                image.setImageResource(resID);

                speechBtn.setClickable(true);
                pass.setClickable(false);
                pass.setVisibility(View.INVISIBLE);
            }else {
                onGameOver();
            }
        }
    }

    public void onGameOver(){

    }

    /**
     * when the user clicks the passed button this function is called.
     * It takes the previous image and make sure it does not pop-up again for the next image and then reproduce a different image
     * @param view
     */
    public void onPass(View view){

    }

    public void onResetPic(View view){

    }

    public void reset(){

    }


    public void MainMenu(View view){
    }

    /**
     * shows speech input dialog
     */
    public void promptSpeechInput() {
        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        intent.putExtra(RecognizerIntent.ACTION_RECOGNIZE_SPEECH, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());
        intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Say a Word from our word bank!");

        try {
            startActivityForResult(intent, VR_Request);
        } catch (ActivityNotFoundException a) {
            Toast.makeText(Pictionary.this, "Oops, your device doesn't support speech recognition,", Toast.LENGTH_LONG).show();
        }
    }

    /**
     * detects and recieve speech input
     * @param requestCode
     * @param resultCode
     * @param intent
     */
    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        if(requestCode == VR_Request && resultCode == RESULT_OK) {
            ArrayList<String> result = intent.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);

            if(wordBANK.contains(result.get(0).toLowerCase()) && UnSpokenList.get(randomNum).contains(result.get(0).toLowerCase())){
                speechInput.setText(result.get(0).toUpperCase());
                matchOrNot.setTextColor(Color.GREEN);
                matchOrNot.setText("CORRECT!");
                UnSpokenList.remove(result.get(0).toLowerCase());
                SpokenList.add(result.get(0).toLowerCase());
                pass.setClickable(false);
                pass.setVisibility(View.INVISIBLE);
                speechBtn.setClickable(false);

                if(UnSpokenList.size() > 3){
                    next.setClickable(true);
                    next.setVisibility(View.VISIBLE);
                }else{
                    last2image.setVisibility(View.VISIBLE);
                    last2image.setClickable(true);
                }
            }else{
                speechInput.setText("");
                matchOrNot.setTextColor(Color.RED);
                matchOrNot.setText("TRY AGAIN!");
                pass.setVisibility(View.VISIBLE);
                pass.setClickable(true);
            }
        }
        super.onActivityResult(requestCode, resultCode, intent);
    }
}

有什么想法吗?提前谢谢!

编辑:错误消息: 每次按下last2image按钮时都会出现此错误消息,并提供崩溃消息:&#34;不幸的是,pic已停止运行&#34;

    08-17 15:58:31.083 13036-13036/com.example.speechtotext E/AndroidRuntime: FATAL EXCEPTION: main
                                                                             Process: com.example.speechtotext, PID: 13036
                                                                             java.lang.IllegalStateException: Could not execute method for android:onClick
                                                                                 at android.view.View$DeclaredOnClickListener.onClick(View.java:4452)
                                                                                 at android.view.View.performClick(View.java:5198)
                                                                                 at android.view.View$PerformClick.run(View.java:21147)
                                                                                 at android.os.Handler.handleCallback(Handler.java:739)
                                                                                 at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                 at android.os.Looper.loop(Looper.java:148)
                                                                                 at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                                 at java.lang.reflect.Method.invoke(Native Method)
                                                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                                                                              Caused by: java.lang.reflect.InvocationTargetException
                                                                                 at java.lang.reflect.Method.invoke(Native Method)
                                                                                 at android.view.View$DeclaredOnClickListener.onClick(View.java:4447)
                                                                                 at android.view.View.performClick(View.java:5198) 
                                                                                 at android.view.View$PerformClick.run(View.java:21147) 
                                                                                 at android.os.Handler.handleCallback(Handler.java:739) 
                                                                                 at android.os.Handler.dispatchMessage(Handler.java:95) 
                                                                                 at android.os.Looper.loop(Looper.java:148) 
                                                                                 at android.app.ActivityThread.main(ActivityThread.java:5417) 
                                                                                 at java.lang.reflect.Method.invoke(Native Method) 
                                                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                                                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
                                                                              Caused by: java.lang.IndexOutOfBoundsException: Invalid index 3, size is 3
                                                                                 at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
                                                                                 at java.util.ArrayList.get(ArrayList.java:308)
                                                                                 at com.example.speechtotext.Main.onlastPair(Main.java:222)
                                                                                 at java.lang.reflect.Method.invoke(Native Method) 
                                                                                 at android.view.View$DeclaredOnClickListener.onClick(View.java:4447) 
                                                                                 at android.view.View.performClick(View.java:5198) 
                                                                                 at android.view.View$PerformClick.run(View.java:21147) 
                                                                                 at android.os.Handler.handleCallback(Handler.java:739) 
                                                                                 at android.os.Handler.dispatchMessage(Handler.java:95) 
                                                                                 at android.os.Looper.loop(Looper.java:148) 
                                                                                 at android.app.ActivityThread.main(ActivityThread.java:5417) 
                                                                                 at java.lang.reflect.Method.invoke(Native Method) 
                                                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                                                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
08-17 15:58:33.495 13036-13036/com.example.speechtotext I/Process: Sending signal. PID: 13036 SIG: 9
08-17 15:58:33.966 17345-17345/com.example.speechtotext W/System: ClassLoader referenced unknown path: /data/app/com.example.speechtotext-2/lib/x86
08-17 15:58:34.302 17345-17345/com.example.speechtotext W/System: ClassLoader referenced unknown path: /data/app/com.example.speechtotext-2/lib/x86
08-17 15:58:34.673 17345-17345/com.example.speechtotext W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
08-17 15:58:34.748 17345-17386/com.example.speechtotext D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true

                                                                             [ 08-17 15:58:34.759 17345:17345 D/         ]
                                                                             HostConnection::get() New Host Connection established 0xaa23f4c0, tid 17345
08-17 15:58:34.828 17345-17386/com.example.speechtotext I/OpenGLRenderer: Initialized EGL, version 1.4
08-17 15:58:34.885 17345-17386/com.example.speechtotext W/EGL_emulation: eglSurfaceAttrib not implemented
08-17 15:58:34.888 17345-17386/com.example.speechtotext W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xaa23e540, error=EGL_SUCCESS

单击按钮时运行的函数是onlastPair()函数,

public void onlastPair(View view){
        if(view.getId() == R.id.last2){
            if(!UnSpokenList.get(UnSpokenList.size()).contains("Word Bank:")) {
                resID = res.getIdentifier(UnSpokenList.get(UnSpokenList.size()), "drawable", getApplication().getPackageName());
                image.setImageResource(resID);

                speechBtn.setClickable(true);
                pass.setClickable(false);
                pass.setVisibility(View.INVISIBLE);
            }else {
                onGameOver();
            }
        }
    }

最初将错误消息定向到以下两行,作为错误的一部分:

  if(!UnSpokenList.get(UnSpokenList.size()).contains("Word Bank:")) {
                    resID = res.getIdentifier(UnSpokenList.get(UnSpokenList.size()), "drawable", getApplication().getPackageName());

所以我决定改变下面显示的功能,

    public void onlastPair(View view){
    if(view.getId() == R.id.last2){
        if(!UnSpokenList.get(1).isEmpty()) {
            int max = UnSpokenList.size();

            resID = res.getIdentifier(UnSpokenList.get(max), "drawable", getApplication().getPackageName());
            image.setImageResource(resID);

            speechBtn.setClickable(true);
            pass.setClickable(false);
            pass.setVisibility(View.INVISIBLE);
        }else {
            onGameOver();
        }
    }
}

但现在它仍然给我一个错误,这次是指向这一行:

        int max = UnSpokenList.size();

我不确定这是什么错误,也许这是我的逻辑,但它似乎对我有意义或者我失踪的东西。任何想法都会有所帮助,谢谢!

1 个答案:

答案 0 :(得分:1)

randomNum = (random.nextInt(UnSpokenList.size()) + 1);不正确

nextInt(15)给出#0-14

如果您的UnSpokenList.size() == 15,则表示其标记为0-14

所以,如果你做random.nextInt(UnSpokenList.size()) + 1),你实际上就是数字,15 + 1,这将是0-15

15 将超出您的0-14岁指标

忽略您的UnSpokenList(0) ...

您需要将其更改为:random.nextInt(UnSpokenList.size() - 1) + 1

大小15-1将为0-13,然后为+1,将使其为1-14,这对于UnSpokenList(1) - UnSpokenList(14)来说是完美的

我们可以对UnSpokenList.size() = 2

进行测试

random.nextInt(2 - 1) + 1 =仅-0 + 1 =仅-1

修改

if(!UnSpokenList.get(1).isEmpty())您要检查您的列表是否包含多个商品?如果是这样,你的可以抛出索引错误,它应该是if (UnSpokenList.size() > 1)

然后再次int max = UnSpokenList.size() ... UnSpokenList.get(max)你给它一个超出范围的索引,0-14但你得到(15),它不会起作用