简体   繁体   English

Android / Eclipse代码错误

[英]Error in Android/Eclipse code

I have a project due and I cannot find my error. 我有一个到期的项目,但找不到我的错误。 Please take pity on a finals week idiot. 请怜悯决赛周的白痴。 :) Android/Eclipse project has errors. :) Android / Eclipse项目有错误。 I think it's a missed } but I can't seem to find it. 我认为这是漏掉的},但似乎找不到。 Entire project is here: http://www.andrewadcock.com/flag.zip Though I think it's just an error in the code below. 整个项目在这里: http : //www.andrewadcock.com/flag.zip尽管我认为这只是下面代码中的错误。 Thank you very much for any help, I've spent about 4 hours looking for the issue(s). 非常感谢您的帮助,我已经花费了大约4个小时来查找问题。

First error is on line 306. 第一个错误在第306行。

//FlagQuizGame.java
//Main Activity Flag Quiz game app
package com.deitel.flagquizgame;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.AssetManager;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TableLayout ;
import android.widget.TableRow;
import android.widget.TextView;

public class FlagQuizGame extends Activity
{
    // String used when logging error messages
    private static final String TAG = "FlagQuizGame Activity" ;

    private List<String> fileNameList; //flag filenames
    private List<String> quizCountriesList;// names of countries
    private Map<String, Boolean> regionsMap; //enabled regions
    private String correctAnswer; // correct country per current flag
    private int totalGuesses; // guesses made
    private int correctAnswers; // correct guesses
    private int guessRows; // no. of rows w/ choices
    private Random random; // random number gen
    private Handler handler; //used to delay next flag load
    private Animation shakeAnimation ; //incorrect guess animation

    private TextView answerTextView ; // Displays In/Correct
    private TextView questionNumberTextView; //shows current question #
    private ImageView flagImageView ; //displays a flag
    private TableLayout buttonTableLayout; // table of answer buttons

    // called upon creation
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState); //call superclass method
        setContentView(R.layout.main); //inflate GUI

        fileNameList = new ArrayList<String>();
        quizCountriesList = new ArrayList<String>();
        regionsMap = new HashMap<String, Boolean>();
        guessRows = 1; //default to one row of choices
        random = new Random(); //initialize the random number gen.
        handler = new Handler(); // performs delayed oper.

        //load shake animation for incorrect guesses
        shakeAnimation = 
            AnimationUtils.loadAnimation(this, R.anim.incorrect_shake);
        shakeAnimation.setRepeatCount(3);//animation repeats 3 times

        //get array of world regions from strings.xml
        String[] regionNames =
            getResources().getStringArray(R.array.regionsList);

        //by default countries are all chosen from all regions
        for (String region : regionNames)
            regionsMap.put(region, true);

        //get references to GUI components
        questionNumberTextView = 
            (TextView) findViewById(R.id.questionNumberTextView);
        flagImageView = (ImageView) findViewById(R.id.flagImageView);
        buttonTableLayout = 
                (TableLayout) findViewById(R.id.buttonTableLayout);
        answerTextView = (TextView) findViewById(R.id.answerTextView);

        //set questionNumberTextView's text
        questionNumberTextView.setText(
            getResources().getString(R.string.question) + " 1 " +
            getResources().getString(R.string.of) + " 10");

        resetQuiz(); // start quiz anew
    }//end of method onCreate

    //set up & start next quiz
    private void resetQuiz()
    {
        //use the AssetManage to get image flag
        //file names for the enabled regions
        AssetManager assets = getAssets(); //get the app's AssetManager
        fileNameList.clear(); //empty list

        try
        {
            Set<String> regions = regionsMap.keySet();

            //loop through each region
            for (String region : regions)
            {
                if (regionsMap.get(region))//if region is enabled
                {
                    //get list of all flag image files in this region
                    String[] paths = assets.list(region);

                    for (String path : paths)
                        fileNameList.add(path.replace(".png", ""));
                }//end if
            }//end for
        }//end try
        catch (IOException e)
        {
            Log.e(TAG, "Error loading image file names", e);
        }//end catch

        correctAnswers = 0; //reset the number of correct answers to 0
        totalGuesses = 0; //reset the total number of guesses to 0
        quizCountriesList.clear();//clear the prior list

        //add 10 random file names the quizCountriesList
        int flagCounter = 1;
        int numberOfFlags = fileNameList.size();//get number of flags

        while (flagCounter <= 10)
        {
            int randomIndex = random.nextInt(numberOfFlags);//random index

            //get random file name
            String fileName = fileNameList.get(randomIndex);

            //if the region is enabled and it hasn't already been chosen
            if (!quizCountriesList.contains(fileName))
            {
                quizCountriesList.add(fileName);
                ++flagCounter;
            }//end if
        }//end while

        loadNextFlag();//start the quiz by loading the first flag
    }//end method resetQuiz

    //after user guesses a correct flag, load the next one
    private void loadNextFlag()
    {
        //get file name of next flag and remove it from list
        String nextImageName = quizCountriesList.remove(0);
        correctAnswer = nextImageName; //update the correct answer

        answerTextView.setText(""); //clear answerTextView

        //displays the number of current question
        questionNumberTextView.setText(
            getResources().getString(R.string.question) + " " +
            (correctAnswers + 1) + " " +
            getResources().getString(R.string.of) + " 10");

        //extract the region from the next image's name
        String region =
            nextImageName.substring(0, nextImageName.indexOf('~'));

        //use AssetManager to load next image from assets folder
        AssetManager assets = getAssets();
        InputStream stream; //used to read flag images

        try
        {
            //get an InputStream to the asset representing the next flag
            stream = assets.open(region + "/" + nextImageName + ".png");

            //load the asset as a drawable display on the flagImageView
            Drawable flag = Drawable.createFromStream(stream, nextImageName);
            flagImageView.setImageDrawable(flag);
        }//end try
        catch (IOException e)
        {
            Log.e(TAG, "Error loading "+ nextImageName, e);
        }//end catch

    // clear prior answer Buttons f r om TableRol'I'!oo
    for (int row = 0; row < buttonTableLayout.getChildCount(); ++row)
        ((TableRow) buttonTableLayout.getChildAt(row)).removeAllViews();

    Collections.shuffle(fileNameList);

    //put the correct answer aht the end of FileNameList
    int correct = fileNameList.indexOf(correctAnswer);
    fileNameList.add(fileNameList.remove(correct));

    //get a reference to the LayoutInflater service
    LayoutInflater inflater = (LayoutInflater) getSystemService(
        Context.LAYOUT_INFLATER_SERVICE);

    // add 3, 6, or 9 answer buttons based on the value of guess rows
    for (int row = 0; row < guessRows; row++)
    {
        TableRow currentTableRow = getTableRow(row);

    //place Buttons in currentTableRow
        for (int column = 0; column < 3; column ++)
        {
            //inflate guess_button.xml to create new Button
            Button newGuessButton = 
                (Button) inflater.inflate(R.layout.guess_button, null);

            //get country name and set it as newGuessButton's text
            String fileName = fileNameList.get((row * 3) + column);
            newGuessButton.setText(getCountryName(fileName));

            //register answerButtonListener to respond to button
            newGuessButton.setOnClickListener(guessButtonListener);
            currentTableRow.addView(newGuessButton);
        }//end for
    } //end for

        //randomly replace on Button with the correct answer
        int row = random.nextInt(guessRows);//pick random row
        int column = random.nextInt(3);//pick random column
        TableRow randomTableRow = getTableRow(row); // get the table row
        String countryName = getCountryName(correctAnswer);
        ((Button)randomTableRow.getChildAt(column)).setText(countryName);
    }

    //returns the specified TableRow
    private TableRow getTableRow(int row)
    {
        return (TableRow) buttonTableLayout.getChildAt(row);
    }//end method getTableRow

    //parses the country flag file name and returns the country name
    private String getCountryName(String name)
    {
        return name.substring(name.indexOf('-') + 1).replace('_', ' ');
    }//end method getCountryName

    // called when the user selects an answer
    private void submitGuess(Button guessButton)
    {
        String guess = guessButton.getText().toString();
        String answer = getCountryName(correctAnswer);
        ++totalGuesses; //increment the number of guesses the user has made

        //if the guess is correct
        if (guess.equals(answer))
        {
            ++correctAnswers; //increment score

            //display "Correct!" in the green text
            answerTextView.setText(answer + "!");
            answerTextView.setTextColor(
                getResources().getColor(R.color.correct_answer));

            disableButtons(); //disable all answer buttons

            //if the user has correctly identified 10 flags
            if (correctAnswers == 10)
            {
                //create an AlertDialog Builder
                AlertDialog.Builder builder = new AlertDialog.Builder(this);

                builder.setTitle(R.string.reset_quiz);//title bar string

                //set AlertDialog's message to display game results
                builder.setMessage(String.format("%d %s, %.02f%% %s",
                    totalGuesses, getResources().getString(R.string.guesses),
                    (1000 / (double) totalGuesses),
                    getResources().getString(R.string.correct)));

                builder.setCancelable(false);

                //add "Reset Quiz" Button
                builder.setPositiveButton(R.string.reset_quiz,
                    new DialogInterface.OnClickListener()
                    {
                        public void onClick(DialogInterface dialog, int id)
                        {
                            resetQuiz();
                        }//end method OnClick
                    }//end anon. inner class
                );//end call to setPositiveButton

    //create AlertDialog from the Builder
        AlertDialog resetDialog = builder.create();
        resetDialog.show(); //display the Dialog
    } //end if
    else //answer is correct but quiz is incomplete
    {
        //load the next flag after 1second delay
        handler.postDelayed(
            new Runnable()
            {
                @Override
                public void run()
                {
                    loadNextFlag();
                }
            }, 1000); // 1000 milliseconds for 1-second delay
        }//end else
    }//end if
    else // guess was incorrect
    {
        //play the animation
        flagImageView.startAnimation(shakeAnimation);

        //display "Incorrect!" in red
        answerTextView.setText(R.string.incorrect_answer);
        answerTextView.setTextColor(
            getResources().getColor(R.color.incorrect_answer));
        guessButton.setEnabled(false);//disable the incorrect answer
    }//end else
    }//end method submitGuess

    //utility method disables all answer buttons
    private void disableButtons()
    {
        for (int row = 0; row < buttonTableLayout.getChildCount(); ++row)
        {
            TableRow tableRow = (TableRow) buttonTableLayout.getChildAt(row);
            for (int i = 0; i < tableRow.getChildCount(); ++i)
                tableRow.getChildAt(i).setEnabled(false);
        }//end outer for
    }//end method disableButtons

    //create constants for each menu id
    private final int CHOICES_MENU_ID = Menu.FIRST;
    private final int REGIONS_MENU_ID = Menu.FIRST + 1;

    //called when the user accesses the options menu
    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        super.onCreateOptionsMenu(menu);

        //add two options to the menu - "Choices" and "Regions"
        menu.add(Menu.NONE, CHOICES_MENU_ID, Menu.NONE, R.string.choices);
        menu.add(Menu.NONE, REGIONS_MENU_ID, Menu.NONE, R.string.regions);

        return true; //display the menu
    }//end method onCreateOptionsMenu 

    //called when the user selects an option from the menu
    @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {
        //switch the menu id of the user-selected option
        switch (item.getItemId())
        {
        case CHOICES_MENU_ID:
            //create a list of the possible numbers of answer choices
            final String[] possibleChoices =
                getResources().getStringArray(R.array.guessesList);

            //create a new AlertDialog Builder and set its title
            AlertDialog.Builder choicesBuilder =
                new AlertDialog.Builder(this);
            choicesBuilder.setTitle(R.string.choices);

            //add possibleChoices items to the dialog and set the
            //behavior for when one of them is clicked
            choicesBuilder.setItems(R.array.guessesList,
                new DialogInterface.OnClickListener()
                {
                    public void onClick(DialogInterface dialog, int item)
                    {
                        //update guessRows to match the user's choice
                        guessRows = Integer.parseInt(
                            possibleChoices[item].toString()) / 3;
                        resetQuiz(); //reset the quiz
                    }//end method onClick
                }//end anon. inner class
            ); //end call to setItems

            //create an AlertDialog from the Builder
            AlertDialog choicesDialog = choicesBuilder.create();
            choicesDialog.show(); // show the Dialog
            return true;

        case REGIONS_MENU_ID:
            //get array of world regions
            final String[] regionNames = 
                regionsMap.keySet().toArray(new String[regionsMap.size()]);

            //boolean array representing whether each region is enabled
            boolean[] regionsEnabled = new boolean[regionsMap.size()];
            for (int i=0; i < regionsEnabled.length;++i)
                regionsEnabled[i] = regionsMap.get(regionNames[i]);

            //create an AlertDialog Builder and set the dialog's title
            AlertDialog.Builder regionsBuilder = 
                new AlertDialog.Builder(this);
            regionsBuilder.setTitle(R.string.regions);

            //replace_with the space in the region names for display purposes
            String[] displayNames = new String[regionNames.length];
            for(int i=0; i<regionNames.length; ++i)
                displayNames[i]=regionNames[i].replace('_',' ');

        //add displayNames to the Dialog and set behavior
        //when one of the new items is clicked
        regionsBuilder.setMultiChoiceItems(
            displayNames, regionsEnabled,
            new DialogInterface.OnMultiChoiceClickListener()
            {
                @Override
                public void onClick(DialogInterface dialog, int which,
                    boolean isChecked)
                {
                    //include ot exclude the clicked region
                    //depending on whether or not it's checked
                    regionsMap.put(
                        regionNames[which].toString(), isChecked);
                }//end method onClick
            }//end anon. inner class
        );//end call to setMultiChoiceItems

    //resets quiz when user presses "Reset Quiz" button
    regionsBuilder.setPositiveButton(R.string.reset_quiz,
        new DialogInterface.OnClickListener()
        {
            @Override
            public void onClick(DialogInterface dialog, int button)
            {
                resetQuiz();//reset the quiz
            }//end method OnClick
        }//end anon. inner class
    );//end call to method setPositiveButton

        //create a dialog from the Builder
        AlertDialog regionsDialog = regionsBuilder.create();
        regionsDialog.show();//display the Dialog
        return true;
    }// end switch

        return super.onOptionsItemSelected(item);
    }//end method onOptionsItemSelected
        //called when a guess Button is touched
        private OnClickListener guessButtonListener = OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                submitGuess((Button) v);//pass selected button to submitGuess
            }//end method onClick
        };//end answerButtonListener
}//end FlagQuizGame

If you get Eclipse to reformat all your code, I think you'll find the problem. 如果让Eclipse重新格式化所有代码,我想您会发现问题。 I suspect it's at around line 210-229: 怀疑它在210-229行附近:

for (int row = 0; row < guessRows; row++)
{
    TableRow currentTableRow = getTableRow(row);
}
//place Buttons in currentTableRow
    for (int column = 0; column < 3; column ++)
    {
        //inflate guess_button.xml to create new Button
        Button newGuessButton = 
            (Button) inflater.inflate(R.layout.guess_button, null);

        //get country name and set it as newGuessButton's text
        String fileName = fileNameList.get((row * 3) + column);
        newGuessButton.setText(getCountryName(fileName));

        //register answerButtonListener to respond to button
        newGuessButton.setOnClickListener(guessButtonListener);
        currentTableRow.addView(newGuessButton);
    }//end for
}//end for

Note how the indentation is wrong after the first short for loop (which just declares a variable, and then does nothing with it. 请注意,在第一个short for循环( 声明一个变量,然后对其不执行任何操作)之后,缩进是错误的。

My guess is that you didn't mean the closing brace on that fourth line. 我的猜测是,您并不是说第四行的结尾括号。 But it's really important to try to be able to work out things like this on your own. 但是,尝试能够自己解决类似问题非常重要。 I suggest that: 我建议:

  • You always use braces for if/for/etc statements, even when the body is just a single line 即使主体只是单行,也始终对if / for / etc语句使用花括号
  • You ask Eclipse to format your code for you, particularly when you've run into problems like this 您要求Eclipse为您格式化代码,尤其是遇到此类问题时
  • You try to keep your methods shorter; 您尝试使方法更短; this makes it easier to find problems 这使得发现问题更加容易

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM