sg.fxl.topekaport.QuizFragment.java Source code

Java tutorial

Introduction

Here is the source code for sg.fxl.topekaport.QuizFragment.java

Source

/*
 * Copyright 2015 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package sg.fxl.topekaport;

import android.annotation.TargetApi;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.animation.FastOutLinearInInterpolator;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterViewAnimator;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

import java.util.List;

import sg.fxl.topeka.adapter.QuizAdapter;
import sg.fxl.topeka.adapter.ScoreAdapter;
import sg.fxl.topeka.helper.ApiLevelHelper;
import sg.fxl.topeka.model.Quiz;
import sg.fxl.topeka.model.Theme;
import sg.fxl.topeka.model.quiz.QuizQuestion;
import sg.fxl.topeka.widget.AvatarView;
import sg.fxl.topeka.widget.quiz.AbsQuizView;

/**
 * Encapsulates QuizQuestion solving and displays it to the user.
 */
public class QuizFragment extends android.support.v4.app.Fragment {

    private static final String KEY_USER_INPUT = "USER_INPUT";
    private TextView progressText;
    private int quizSize;
    private ProgressBar progressBar;
    private Quiz quiz;
    private QuizSetting quizSetting;
    private AdapterViewAnimator quizView;
    private ScoreAdapter scoreAdapter;
    private QuizAdapter quizAdapter;
    private SolvedStateListener solvedStateListener;

    public static QuizFragment newInstance(Quiz quiz, QuizSetting quizSetting,
            SolvedStateListener solvedStateListener) {
        if (quiz == null) {
            throw new IllegalArgumentException("The quiz can not be null");
        }
        QuizFragment fragment = new QuizFragment();
        if (solvedStateListener != null) {
            fragment.solvedStateListener = solvedStateListener;
        }
        fragment.quiz = quiz;
        fragment.quizSetting = quizSetting;
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
            @Nullable Bundle savedInstanceState) {
        // Create a themed Context and custom LayoutInflater
        // to get nicely themed views in this Fragment.
        final Theme theme = quiz.getTheme();
        final ContextThemeWrapper context = new ContextThemeWrapper(getActivity(), theme.getStyleId());
        final LayoutInflater themedInflater = LayoutInflater.from(context);
        return themedInflater.inflate(R.layout.fragment_quiz, container, false);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        quizView = (AdapterViewAnimator) view.findViewById(R.id.quiz_view);
        decideOnViewToDisplay();
        setQuizViewAnimations();
        final AvatarView avatar = (AvatarView) view.findViewById(R.id.avatar);
        setAvatarDrawable(avatar);
        initProgressToolbar(view);
        super.onViewCreated(view, savedInstanceState);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void setQuizViewAnimations() {
        if (ApiLevelHelper.isLowerThan(Build.VERSION_CODES.LOLLIPOP)) {
            return;
        }
        quizView.setInAnimation(getActivity(), R.animator.slide_in_bottom);
        quizView.setOutAnimation(getActivity(), R.animator.slide_out_top);
    }

    private void initProgressToolbar(View view) {
        final int firstUnsolvedQuizPosition = quiz.getFirstUnsolvedQuizPosition();
        final List<QuizQuestion> quizzes = quiz.getQuizzes();
        quizSize = quizzes.size();
        progressText = (TextView) view.findViewById(R.id.progress_text);
        progressBar = ((ProgressBar) view.findViewById(R.id.progress));
        progressBar.setMax(quizSize);

        setProgress(firstUnsolvedQuizPosition);
    }

    private void setProgress(int currentQuizPosition) {
        if (!isAdded()) {
            return;
        }
        progressText.setText(getString(R.string.quiz_of_quizzes, currentQuizPosition, quizSize));
        progressBar.setProgress(currentQuizPosition);
    }

    @SuppressWarnings("ConstantConditions")
    private void setAvatarDrawable(AvatarView avatarView) {
        avatarView.setAvatar(R.drawable.avatar_1);
        ViewCompat.animate(avatarView).setInterpolator(new FastOutLinearInInterpolator()).setStartDelay(500)
                .scaleX(1).scaleY(1).start();
    }

    private void decideOnViewToDisplay() {
        final boolean isSolved = quiz.isSolved();
        if (isSolved) {
            showSummary();
            if (null != solvedStateListener) {
                solvedStateListener.onCategorySolved();
            }
        } else {
            quizView.setAdapter(getQuizAdapter());
            quizView.setSelection(quiz.getFirstUnsolvedQuizPosition());
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        View focusedChild = quizView.getFocusedChild();
        if (focusedChild instanceof ViewGroup) {
            View currentView = ((ViewGroup) focusedChild).getChildAt(0);
            if (currentView instanceof AbsQuizView) {
                outState.putBundle(KEY_USER_INPUT, ((AbsQuizView) currentView).getUserInput());
            }
        }
        super.onSaveInstanceState(outState);
    }

    @Override
    public void onViewStateRestored(Bundle savedInstanceState) {
        restoreQuizState(savedInstanceState);
        super.onViewStateRestored(savedInstanceState);
    }

    private void restoreQuizState(final Bundle savedInstanceState) {
        if (null == savedInstanceState) {
            return;
        }
        quizView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
            @Override
            public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop,
                    int oldRight, int oldBottom) {
                quizView.removeOnLayoutChangeListener(this);
                View currentChild = quizView.getChildAt(0);
                if (currentChild instanceof ViewGroup) {
                    final View potentialQuizView = ((ViewGroup) currentChild).getChildAt(0);
                    if (potentialQuizView instanceof AbsQuizView) {
                        ((AbsQuizView) potentialQuizView)
                                .setUserInput(savedInstanceState.getBundle(KEY_USER_INPUT));
                    }
                }
            }
        });

    }

    private QuizAdapter getQuizAdapter() {
        if (null == quizAdapter) {
            quizAdapter = new QuizAdapter(getActivity(), quiz, quizSetting);
        }
        return quizAdapter;
    }

    /**
     * Displays the next page.
     *
     * @return <code>true</code> if there's another quiz to solve, else <code>false</code>.
     */
    public boolean showNextPage() {
        if (null == quizView) {
            return false;
        }
        int nextItem = quizView.getDisplayedChild() + 1;
        setProgress(nextItem);
        final int count = quizView.getAdapter().getCount();
        if (nextItem < count) {
            quizView.showNext();
            return true;
        }
        //Mark category as solved
        quiz.setSolved(true);
        return false;
    }

    public void showSummary() {
        @SuppressWarnings("ConstantConditions")
        final ListView scorecardView = (ListView) getView().findViewById(R.id.scorecard);
        scoreAdapter = getScoreAdapter();
        scorecardView.setAdapter(scoreAdapter);
        scorecardView.setVisibility(View.VISIBLE);
        quizView.setVisibility(View.GONE);
    }

    public boolean hasSolvedStateListener() {
        return solvedStateListener != null;
    }

    public void setSolvedStateListener(SolvedStateListener solvedStateListener) {
        this.solvedStateListener = solvedStateListener;
        if (quiz.isSolved() && null != this.solvedStateListener) {
            this.solvedStateListener.onCategorySolved();
        }
    }

    private ScoreAdapter getScoreAdapter() {
        if (null == scoreAdapter) {
            scoreAdapter = new ScoreAdapter(quiz);
        }
        return scoreAdapter;
    }

    /**
     * Interface definition for a callback to be invoked when the quiz is started.
     */
    public interface SolvedStateListener {

        /**
         * This method will be invoked when the category has been solved.
         */
        void onCategorySolved();
    }
}