Dialog Fragment不起作用?

时间:2017-12-14 06:38:34

标签: java android android-fragments

Iam在Dialog片段中收到运行时错误。在程序的运行时工作顺利,但当谈到对话框外观时,程序崩溃了...........有人告诉我错误在哪里我无法解决我的问题。

I am posting a LogCat Image because of body limit is crossed

MainActivity.java

import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Typeface;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

import java.util.Set;

public class MainActivity extends AppCompatActivity {

    public static final String GUESSES = "settings_numberOfGuesses";
    public static final String ANIMALS_TYPE = "settings_animalType";
    public static final String QUIZ_BACKGROUND_COLOR = "settings_quiz_background_color";
    public static final String QUIZ_FONT = "settings_quiz_font";

    private boolean isSettingsChanged = false;

    static Typeface azkiaDemo;
    static Typeface chunkFive;
    static Typeface fontleroyBrown;
    static Typeface hauntedEyes;
    static Typeface knightBrushDemo;
    static Typeface wonderbarDemo;

    MainActivityFragment myAnimalQuizFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        azkiaDemo = Typeface.createFromAsset(getAssets(),"fonts/Azkia demo.otf");
        chunkFive = Typeface.createFromAsset(getAssets(),"fonts/Chunkfive.otf");
        fontleroyBrown = Typeface.createFromAsset(getAssets(),"fonts/FontleroyBrown.ttf");
        hauntedEyes = Typeface.createFromAsset(getAssets(),"fonts/Haunted Eyes.otf");
        knightBrushDemo = Typeface.createFromAsset(getAssets(),"fonts/Knight Brush Demo.otf");
        wonderbarDemo = Typeface.createFromAsset(getAssets(),"fonts/Wonderbar Demo.otf");

        PreferenceManager.setDefaultValues(this, R.xml.quiz_preferences, false);

        PreferenceManager.getDefaultSharedPreferences(this).
                registerOnSharedPreferenceChangeListener(settingsChangedListener);

        myAnimalQuizFragment = (MainActivityFragment) getSupportFragmentManager().findFragmentById(R.id.animalQuizFragment);


        myAnimalQuizFragment.modifyAnimalGuessRows(PreferenceManager.getDefaultSharedPreferences(this));
        myAnimalQuizFragment.modifyTypeofAnimals(PreferenceManager.getDefaultSharedPreferences(this));
        myAnimalQuizFragment.modifyQuizFont(PreferenceManager.getDefaultSharedPreferences(this));
        myAnimalQuizFragment.modifyBackgroundColor(PreferenceManager.getDefaultSharedPreferences(this));
        myAnimalQuizFragment.resetAnimalQuiz();
        isSettingsChanged = false;

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        Intent preferencesIntent = new Intent(this,SettingsActivity.class);
        startActivity(preferencesIntent);


        return super.onOptionsItemSelected(item);
    }

    private SharedPreferences.OnSharedPreferenceChangeListener settingsChangedListener =
            new SharedPreferences.OnSharedPreferenceChangeListener() {
                @Override
                public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {

                    isSettingsChanged = true;

                    if (key.equals(GUESSES)){

                        myAnimalQuizFragment.modifyAnimalGuessRows(sharedPreferences);
                        myAnimalQuizFragment.resetAnimalQuiz();

                    }else if (key.equals(ANIMALS_TYPE)){

                        Set<String> animalTypes = sharedPreferences.getStringSet(ANIMALS_TYPE,null);

                        if (animalTypes != null && animalTypes.size() > 0){

                            myAnimalQuizFragment.modifyTypeofAnimals(sharedPreferences);
                            myAnimalQuizFragment.resetAnimalQuiz();
                        }else {

                            SharedPreferences.Editor editor = sharedPreferences.edit();
                            animalTypes.add(getString(R.string.default_animal_type));
                            editor.putStringSet(ANIMALS_TYPE, animalTypes);      // here we provided default value also.......
                            editor.apply();

                            Toast.makeText(MainActivity.this, R.string.default_animalType_message, Toast.LENGTH_SHORT).show();
                        }
                    }else if (key.equals(QUIZ_FONT)){

                        myAnimalQuizFragment.modifyQuizFont(sharedPreferences);
                        myAnimalQuizFragment.resetAnimalQuiz();

                    }else if (key.equals(QUIZ_BACKGROUND_COLOR)){

                        myAnimalQuizFragment.modifyBackgroundColor(sharedPreferences);
                        myAnimalQuizFragment.resetAnimalQuiz();
                    }

                    Toast.makeText(MainActivity.this, R.string.toast_message , Toast.LENGTH_SHORT).show();


                }
            };

    public void showDialog(){

        ExampleDialog exampleDialog = new ExampleDialog();
        exampleDialog.setCancelable(false);
        exampleDialog.show(getFragmentManager(),"Animal_Quiz_Result");

    }    
}

这是MainActivityFragment.java类

import android.animation.Animator;
    import android.content.SharedPreferences;
    import android.content.res.AssetManager;
    import android.graphics.Color;
    import android.graphics.drawable.Drawable;
    import android.os.Bundle;
    import android.os.Handler;
    import android.support.v4.app.Fragment;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewAnimationUtils;
    import android.view.ViewGroup;
    import android.view.animation.Animation;
    import android.view.animation.AnimationUtils;
    import android.widget.Button;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import android.widget.TextView;

    import java.io.IOException;
    import java.io.InputStream;
    import java.security.SecureRandom;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    import java.util.Set;


public class MainActivityFragment extends Fragment {

    public static final int NUMBER_OF_ANIMALS_INCLUDED_IN_QUIZ = 10;

    private List<String> allAnimalsNameList;
    private List<String> animalNamesQuizList;
    private Set<String> animalTypesInQuiz;
    private String correctAnimalsAnswer;
    public static int numberOfAllGuesses;
    private int numberOfAnimalGuessRows;
    private int numberOfRightAnswers;
    private SecureRandom secureRandomNumber;
    private Handler handler;
    private Animation wrongAnswerAnimation;

    private LinearLayout animalQuizLinearLayout;
    private TextView txtQuestionNumber;
    private ImageView imgAnimal;
    private LinearLayout[] rowsOfGuessButtonsInAnimalQuiz;
    private TextView txtAnswer;

    public MainActivityFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_main, container, false);

        allAnimalsNameList = new ArrayList<>();
        animalNamesQuizList = new ArrayList<>();
        secureRandomNumber = new SecureRandom();
        handler = new Handler();

        wrongAnswerAnimation = AnimationUtils.loadAnimation(getActivity(), R.anim.wrong_animation);
        wrongAnswerAnimation.setRepeatCount(1);

        animalQuizLinearLayout = view.findViewById(R.id.animalQuizLinearLayout);
        txtQuestionNumber = view.findViewById(R.id.txtQuestionNumber);
        imgAnimal = view.findViewById(R.id.imgAnimal);
        rowsOfGuessButtonsInAnimalQuiz = new LinearLayout[3];
        rowsOfGuessButtonsInAnimalQuiz[0] = view.findViewById(R.id.firstRowLinearLayout);
        rowsOfGuessButtonsInAnimalQuiz[1] = view.findViewById(R.id.secondRowLinearLayout);
        rowsOfGuessButtonsInAnimalQuiz[2] = view.findViewById(R.id.thirdRowLinearLayout);
        txtAnswer = view.findViewById(R.id.txtAnswer);

        for (LinearLayout row : rowsOfGuessButtonsInAnimalQuiz) {

            for (int column = 0; column < row.getChildCount(); column++) {

                Button btnGuess = (Button) row.getChildAt(column);
                btnGuess.setOnClickListener(btnGuessListener);
                btnGuess.setTextSize(24);
            }
        }

        txtQuestionNumber.setText(getString(R.string.question_text, 1, NUMBER_OF_ANIMALS_INCLUDED_IN_QUIZ));

        // getString is extends fragment...........


        return view;
    }

    private View.OnClickListener btnGuessListener = new View.OnClickListener() {

        @Override
        public void onClick(View view) {

            Button btnGuess = ((Button) view);
            String guessValue = btnGuess.getText().toString();
            String answerValue = getTheExactAnimalName(correctAnimalsAnswer);
            ++numberOfAllGuesses;

            if (guessValue.equals(answerValue)) {

                ++numberOfRightAnswers;

                txtAnswer.setText(answerValue + " ! " + " RIGHT");

                disableQuizGuessButton();

                if (numberOfRightAnswers == NUMBER_OF_ANIMALS_INCLUDED_IN_QUIZ) {

                    MainActivity mainActivity = new MainActivity();
                    mainActivity.showDialog();

                } else {
                    handler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            animateAnimalQuiz(true);
                        }
                    }, 1000); //1000 milliseconds for 1 second delay.......
                }

            } else {
                imgAnimal.startAnimation(wrongAnswerAnimation);
                txtAnswer.setText(R.string.wrong_answer_message);
                btnGuess.setEnabled(false);
            }

        }
    };

    public static String getTheExactAnimalName(String animalName) {

        return animalName.substring(animalName.indexOf('-') + 1).replace('_', ' ');

    }// this method changes the actual name of image for example removes or starts after tame_animal- through index of method
    //  and after that removes _ between the names of animals...........

    private void disableQuizGuessButton() {

        for (int row = 0; row < numberOfAnimalGuessRows; row++) {

            LinearLayout guessRowLinearLayout = rowsOfGuessButtonsInAnimalQuiz[row];

            for (int buttonIndex = 0; buttonIndex < guessRowLinearLayout.getChildCount(); buttonIndex++) {

                guessRowLinearLayout.getChildAt(buttonIndex).setEnabled(false);

            }

        }
    }

    public void resetAnimalQuiz() {

        AssetManager assets = getActivity().getAssets();
        allAnimalsNameList.clear();

        try {

            for (String animalType : animalTypesInQuiz) {

                String[] animalImagePathsInQuiz = assets.list(animalType);

                for (String animalImagePathInQuiz : animalImagePathsInQuiz) {

                    allAnimalsNameList.add(animalImagePathInQuiz.replace(".png", ""));
                }

            }

        } catch (IOException e) {
            Log.e("AnimalQuiz", "Error", e);
        }

        numberOfRightAnswers = 0;       // this variable holds the right guesses must be 0 because we reset the game.
        numberOfAllGuesses = 0;         // this variable holds no. of all guesses whether it is right or wrong have to be 0.
        animalNamesQuizList.clear();    // this variable holds randomly generated quiz paths must be 0 to generate new paths......

        int counter = 1;
        int numberOfAvailableAnimal = allAnimalsNameList.size();// this variable holds number of available animals or the size or length of paths

        while (counter <= NUMBER_OF_ANIMALS_INCLUDED_IN_QUIZ) {

            int randomIndex = secureRandomNumber.nextInt(numberOfAvailableAnimal);

            String animalImageName = allAnimalsNameList.get(randomIndex);

            if (!animalNamesQuizList.contains(animalImageName)) {

                animalNamesQuizList.add(animalImageName);
                ++counter;

            }
        }

        showNextAnimal();

    }

    private void animateAnimalQuiz(boolean animateOutAnimalImage) {

        if (numberOfRightAnswers == 0) {

            return;
        }

        int xTopLeft = 0;
        int yTopLeft = 0;

        int xBottomRight = animalQuizLinearLayout.getLeft() + animalQuizLinearLayout.getRight();
        int yBottomRight = animalQuizLinearLayout.getTop() + animalQuizLinearLayout.getBottom();

        //Here is max value for radius
        int radius = Math.max(animalQuizLinearLayout.getWidth(), animalQuizLinearLayout.getHeight());

        Animator animator;

        if (animateOutAnimalImage) {

            animator = ViewAnimationUtils.createCircularReveal(animalQuizLinearLayout, xBottomRight, yBottomRight, radius, 0);

            animator.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animation) {

                }

                @Override
                public void onAnimationEnd(Animator animation) {

                    showNextAnimal();

                }

                @Override
                public void onAnimationCancel(Animator animation) {

                }

                @Override
                public void onAnimationRepeat(Animator animation) {

                }
            });

        } else {
            animator = ViewAnimationUtils.createCircularReveal(animalQuizLinearLayout, xTopLeft, yTopLeft, 0, radius);
        }

        animator.setDuration(700);
        animator.start();

    }

    private void showNextAnimal() {

        String nextAnimalImageName = animalNamesQuizList.remove(0);
        correctAnimalsAnswer = nextAnimalImageName;
        txtAnswer.setText("");

        txtQuestionNumber.setText(getString(R.string.question_text, (numberOfRightAnswers + 1), NUMBER_OF_ANIMALS_INCLUDED_IN_QUIZ));

        String animalType = nextAnimalImageName.substring(0, nextAnimalImageName.indexOf("-"));  // it holds the animal type whether it is
        // Tame animal or Wild Animal
        AssetManager assets = getActivity().getAssets();

        try (InputStream stream = assets.open(animalType + "/" + nextAnimalImageName + ".png")) {

            Drawable animalImage = Drawable.createFromStream(stream, nextAnimalImageName);
            imgAnimal.setImageDrawable(animalImage);

            animateAnimalQuiz(false);

        } catch (IOException e) {
            Log.e("AnimalQuiz", "There is an Error Getting" + nextAnimalImageName, e);
        }

        Collections.shuffle(allAnimalsNameList);    // this method is a predefined method in java which helps to shuffle the list of data

        int correctAnimalNameIndex = allAnimalsNameList.indexOf(correctAnimalsAnswer);
        String correctAnimalName = allAnimalsNameList.remove(correctAnimalNameIndex);
        allAnimalsNameList.add(correctAnimalName);

        for (int row = 0; row < numberOfAnimalGuessRows; row++) {

            for (int column = 0; column < rowsOfGuessButtonsInAnimalQuiz[row].getChildCount(); column++) {

                Button btnGuess = (Button) rowsOfGuessButtonsInAnimalQuiz[row].getChildAt(column);
                btnGuess.setEnabled(true);

                String animalImageName = allAnimalsNameList.get((row * 2) + column);
                btnGuess.setText(getTheExactAnimalName(animalImageName));

            }

        }

        int row = secureRandomNumber.nextInt(numberOfAnimalGuessRows);
        int column = secureRandomNumber.nextInt(2);
        LinearLayout randomRow = rowsOfGuessButtonsInAnimalQuiz[row];
        String correctAnimalImageName = getTheExactAnimalName(correctAnimalsAnswer);
        ((Button) randomRow.getChildAt(column)).setText(correctAnimalImageName);

    }

    public void modifyAnimalGuessRows(SharedPreferences sharedPreferences){

        final String NUMBER_OF_GUESS_OPTION = sharedPreferences.getString(GUESSES,null);
        numberOfAnimalGuessRows = Integer.parseInt(NUMBER_OF_GUESS_OPTION)/2;

        for (LinearLayout horizontalLinearLayout : rowsOfGuessButtonsInAnimalQuiz){

            horizontalLinearLayout.setVisibility(View.GONE);

        }

        for (int row = 0; row < numberOfAnimalGuessRows; row++){

            rowsOfGuessButtonsInAnimalQuiz[row].setVisibility(View.VISIBLE);

        }

    }

    public void modifyTypeofAnimals(SharedPreferences sharedPreferences){

        animalTypesInQuiz = sharedPreferences.getStringSet(ANIMALS_TYPE,null);

    }

    public void modifyQuizFont(SharedPreferences sharedPreferences){

        String fontStringValue = sharedPreferences.getString(QUIZ_FONT,null);

        switch (fontStringValue){

            case "Chunkfive.otf":
                for (LinearLayout row : rowsOfGuessButtonsInAnimalQuiz){

                    for (int column = 0; column < row.getChildCount(); column++) {

                        Button button = (Button) row.getChildAt(column);
                        button.setTypeface(chunkFive);
                    }
                }
                break;
            case "Azkia demo.otf":
                for (LinearLayout row : rowsOfGuessButtonsInAnimalQuiz){

                    for (int column = 0; column < row.getChildCount(); column++) {

                        Button button = (Button) row.getChildAt(column);
                        button.setTypeface(azkiaDemo);
                    }
                }
                break;
            case "FontleroyBrown.otf":
                for (LinearLayout row : rowsOfGuessButtonsInAnimalQuiz){

                    for (int column = 0; column < row.getChildCount(); column++) {

                        Button button = (Button) row.getChildAt(column);
                        button.setTypeface(fontleroyBrown);
                    }
                }
                break;
            case "Haunted Eyes.otf":
                for (LinearLayout row : rowsOfGuessButtonsInAnimalQuiz){

                    for (int column = 0; column < row.getChildCount(); column++) {

                        Button button = (Button) row.getChildAt(column);
                        button.setTypeface(hauntedEyes);
                    }
                }
                break;
            case "Knight Brush Demo.otf":
                for (LinearLayout row : rowsOfGuessButtonsInAnimalQuiz){

                    for (int column = 0; column < row.getChildCount(); column++) {

                        Button button = (Button) row.getChildAt(column);
                        button.setTypeface(knightBrushDemo);
                    }
                }
                break;
            case "Wonderbar Demo.otf":
                for (LinearLayout row : rowsOfGuessButtonsInAnimalQuiz){

                    for (int column = 0; column < row.getChildCount(); column++) {

                        Button button = (Button) row.getChildAt(column);
                        button.setTypeface(wonderbarDemo);
                    }
                }
                break;
        }
    }

    public void modifyBackgroundColor(SharedPreferences sharedPreferences){

        String backgroundColor = sharedPreferences.getString(QUIZ_BACKGROUND_COLOR,null);

        switch (backgroundColor){

            case "White":
                animalQuizLinearLayout.setBackgroundColor(Color.WHITE);
                for (LinearLayout row : rowsOfGuessButtonsInAnimalQuiz){

                    for (int column = 0; column < row.getChildCount(); column++){

                        Button button = (Button) row.getChildAt(column);
                        button.setBackgroundColor(Color.rgb(34,167,240));
                        button.setTextColor(Color.WHITE);

                    }

                }
                txtQuestionNumber.setTextColor(Color.BLACK);
                txtAnswer.setTextColor(Color.rgb(34,167,240));
                break;

            case "Black":
                animalQuizLinearLayout.setBackgroundColor(Color.BLACK);
                for (LinearLayout row : rowsOfGuessButtonsInAnimalQuiz){

                    for (int column = 0; column < row.getChildCount(); column++){

                        Button button = (Button) row.getChildAt(column);
                        button.setBackgroundColor(Color.rgb(247,202,24));
                        button.setTextColor(Color.BLACK);

                    }

                }
                txtQuestionNumber.setTextColor(Color.WHITE);
                txtAnswer.setTextColor(Color.WHITE);
                break;

            case "Green":
                animalQuizLinearLayout.setBackgroundColor(Color.rgb(38,166,91));
                for (LinearLayout row : rowsOfGuessButtonsInAnimalQuiz){

                    for (int column = 0; column < row.getChildCount(); column++){

                        Button button = (Button) row.getChildAt(column);
                        button.setBackgroundColor(Color.rgb(34,167,240));
                        button.setTextColor(Color.WHITE);

                    }

                }
                txtQuestionNumber.setTextColor(Color.rgb(247,202,24));
                txtAnswer.setTextColor(Color.WHITE);
                break;

            case "Yellow":
                animalQuizLinearLayout.setBackgroundColor(Color.rgb(247,202,24));
                for (LinearLayout row : rowsOfGuessButtonsInAnimalQuiz){

                    for (int column = 0; column < row.getChildCount(); column++){

                        Button button = (Button) row.getChildAt(column);
                        button.setBackgroundColor(Color.BLACK);
                        button.setTextColor(Color.WHITE);

                    }

                }
                txtQuestionNumber.setTextColor(Color.BLACK);
                txtAnswer.setTextColor(Color.BLACK);
                break;

            case "Red":
                animalQuizLinearLayout.setBackgroundColor(Color.rgb(240,52,52));
                for (LinearLayout row : rowsOfGuessButtonsInAnimalQuiz){

                    for (int column = 0; column < row.getChildCount(); column++){

                        Button button = (Button) row.getChildAt(column);
                        button.setBackgroundColor(Color.rgb(34,167,240));
                        button.setTextColor(Color.WHITE);

                    }

                }
                txtQuestionNumber.setTextColor(Color.WHITE);
                txtAnswer.setTextColor(Color.WHITE);
                break;

            case "Blue":
                animalQuizLinearLayout.setBackgroundColor(Color.rgb(34,167,240));
                for (LinearLayout row : rowsOfGuessButtonsInAnimalQuiz){

                    for (int column = 0; column < row.getChildCount(); column++){

                        Button button = (Button) row.getChildAt(column);
                        button.setBackgroundColor(Color.rgb(240,52,52));
                        button.setTextColor(Color.WHITE);

                    }

                }
                txtQuestionNumber.setTextColor(Color.WHITE);
                txtAnswer.setTextColor(Color.WHITE);
                break;


        }
    }
}

这是ExampleDialog.java类

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.os.Bundle;

import static com.example.narayanmaity.app61animal_quiz.MainActivityFragment.numberOfAllGuesses;

/**
 * Created by Narayan Maity on 12/14/2017.
 */

public class ExampleDialog extends DialogFragment {

    MainActivityFragment myAnimalQuizFragment;

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setMessage(getString(R.string.results_string_value, numberOfAllGuesses,
                (1000 / (double) numberOfAllGuesses)));

        builder.setPositiveButton(R.string.result_animal_quiz, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {

                myAnimalQuizFragment.resetAnimalQuiz();
            }
        });

        return builder.create();
    }   
}

1 个答案:

答案 0 :(得分:0)

问题在于此行。从代码

移除下面一行
 MainActivity mainActivity = new MainActivity();
                mainActivity.showDialog();

您永远不会使用new运算符创建Activity的实例。它的android Component类使用Intent自动初始化。 android中的所有活动必须经历一个生命周期,以便它们附加有效的上下文。阅读Activity

解决此问题的方法。

 if(getActivity()!=null){
        ((MainActivity)getActivity()).showDialog()
    }

您在评论中提到的新问题。 您永远不会指定 myAnimalQuizFragment ,因此无论如何它都会为您提供NullPointerException。从您的MainActivity访问它。

((MainActivity)getActivity()).myAnimalQuizFragment.resetAnimalQuiz();

在MainActivity中将myAnimalQuizFragment设为公共。