com.rubengees.introduction.IntroductionActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.rubengees.introduction.IntroductionActivity.java

Source

/*
 *   Copyright 2015 Ruben Gees
 *
 *   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 com.rubengees.introduction;

import android.annotation.TargetApi;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.view.OnApplyWindowInsetsListener;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.ViewPager;
import android.support.v4.view.WindowInsetsCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.AppCompatImageButton;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.FrameLayout;

import com.rubengees.introduction.adapter.PagerAdapter;
import com.rubengees.introduction.common.DotIndicatorManager;
import com.rubengees.introduction.entity.Option;
import com.rubengees.introduction.entity.Slide;
import com.rubengees.introduction.interfaces.IndicatorManager;
import com.rubengees.introduction.style.Style;
import com.rubengees.introduction.util.ButtonManager;
import com.rubengees.introduction.util.OrientationUtils;

import java.util.ArrayList;
import java.util.Collections;

import static com.rubengees.introduction.IntroductionBuilder.BUNDLE_ALLOW_BACK_PRESS;
import static com.rubengees.introduction.IntroductionBuilder.BUNDLE_ORIENTATION;
import static com.rubengees.introduction.IntroductionBuilder.BUNDLE_SHOW_INDICATOR;
import static com.rubengees.introduction.IntroductionBuilder.BUNDLE_SHOW_PREVIOUS_BUTTON;
import static com.rubengees.introduction.IntroductionBuilder.BUNDLE_SKIP_RESOURCE;
import static com.rubengees.introduction.IntroductionBuilder.BUNDLE_SKIP_STRING;
import static com.rubengees.introduction.IntroductionBuilder.BUNDLE_SLIDES;
import static com.rubengees.introduction.IntroductionBuilder.BUNDLE_STYLE;
import static com.rubengees.introduction.IntroductionBuilder.ORIENTATION_BOTH;
import static com.rubengees.introduction.IntroductionBuilder.ORIENTATION_LANDSCAPE;
import static com.rubengees.introduction.IntroductionBuilder.ORIENTATION_PORTRAIT;

/**
 * The Activity which shows the introduction finally to the user.
 *
 * @author Ruben Gees
 */
public class IntroductionActivity extends AppCompatActivity {

    public static final String OPTION_RESULT = "introduction_option_result";
    public static final String STATE_PREVIOUS_PAGER_POSITION = "previous_pager_position";

    private ArrayList<Slide> slides;
    private Style style;

    private ViewPager pager;
    private AppCompatImageButton previous;
    private AppCompatImageButton next;
    private FrameLayout indicatorContainer;
    private Button skip;

    private IntroductionConfiguration configuration;

    private ButtonManager buttonManager;
    private IndicatorManager indicatorManager;

    private boolean showPreviousButton;
    private boolean showIndicator;
    private String skipText;
    private boolean allowBackPress;

    private int orientation;

    private int previousPagerPosition;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        getFieldsFromBundle();
        applyStyle();

        super.onCreate(savedInstanceState);
        setContentView(R.layout.introduction_activity);

        configuration = IntroductionConfiguration.getInstance();

        findViews();
        initSlides();
        initManagers();
        initViews();

        if (savedInstanceState == null) {
            select(0);
            pager.setCurrentItem(rtlAwarePosition(0));
        } else {
            previousPagerPosition = savedInstanceState.getInt(STATE_PREVIOUS_PAGER_POSITION);

            select(previousPagerPosition);
        }

        //Workaround for fitsSystemWindows in a ViewPager
        ViewCompat.setOnApplyWindowInsetsListener(pager, new OnApplyWindowInsetsListener() {
            @Override
            public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
                WindowInsetsCompat newInsets = ViewCompat.onApplyWindowInsets(v, insets);

                if (newInsets.isConsumed()) {
                    return newInsets;
                }

                boolean consumed = false;

                if (newInsets.isConsumed()) {
                    consumed = true;
                }

                for (int i = 0; i < pager.getChildCount(); i++) {
                    ViewCompat.dispatchApplyWindowInsets(pager.getChildAt(i), newInsets);

                    if (newInsets.isConsumed()) {
                        consumed = true;
                    }
                }

                return consumed ? newInsets.consumeSystemWindowInsets() : newInsets;
            }
        });
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        outState.putInt(STATE_PREVIOUS_PAGER_POSITION, previousPagerPosition);
    }

    @NonNull
    Style getStyle() {
        return style;
    }

    private void getFieldsFromBundle() {
        Bundle bundle = getIntent().getExtras();

        if (bundle == null) {
            bundle = new Bundle();
        }

        slides = bundle.getParcelableArrayList(BUNDLE_SLIDES);
        style = (Style) bundle.getSerializable(BUNDLE_STYLE);
        orientation = bundle.getInt(BUNDLE_ORIENTATION, ORIENTATION_BOTH);
        showPreviousButton = bundle.getBoolean(BUNDLE_SHOW_PREVIOUS_BUTTON, true);
        showIndicator = bundle.getBoolean(BUNDLE_SHOW_INDICATOR, true);
        skipText = bundle.getString(BUNDLE_SKIP_STRING);
        allowBackPress = bundle.getBoolean(BUNDLE_ALLOW_BACK_PRESS, false);

        if (slides == null) {
            slides = new ArrayList<>();
        }

        if (skipText == null) {
            int skipResource = bundle.getInt(BUNDLE_SKIP_RESOURCE, 0);

            if (skipResource != 0) {
                skipText = this.getString(skipResource);
            }
        }
    }

    @TargetApi(Build.VERSION_CODES.KITKAT)
    private void applyStyle() {
        if (style != null) {
            style.applyStyle(this);

            if (orientation == ORIENTATION_PORTRAIT) {
                OrientationUtils.setOrientationPortrait(this);
            } else if (orientation == ORIENTATION_LANDSCAPE) {
                OrientationUtils.setOrientationLandscape(this);
            }
        }
    }

    private void findViews() {
        ViewGroup root = (ViewGroup) findViewById(R.id.introduction_activity_root);
        pager = (ViewPager) findViewById(R.id.introduction_activity_pager);
        indicatorContainer = (FrameLayout) findViewById(R.id.introduction_activity_container_indicator);
        skip = (Button) findViewById(R.id.introduction_activity_skip);

        if (OrientationUtils.isRTL(this)) {
            previous = (AppCompatImageButton) findViewById(R.id.introduction_activity_button_next);
            next = (AppCompatImageButton) findViewById(R.id.introduction_activity_button_previous);
        } else {
            previous = (AppCompatImageButton) findViewById(R.id.introduction_activity_button_previous);
            next = (AppCompatImageButton) findViewById(R.id.introduction_activity_button_next);
        }

        if (style != null) {
            style.applyStyleOnActivityView(this, root);
        }
    }

    private void initSlides() {
        if (OrientationUtils.isRTL(this)) {
            Collections.reverse(slides);
        }

        for (int i = 0; i < slides.size(); i++) {
            Slide slide = slides.get(i);

            slide.init(this, i);
        }
    }

    private void initManagers() {
        buttonManager = new ButtonManager(previous, next, skip, showPreviousButton, skipText != null,
                slides.size());
        indicatorManager = configuration.getIndicatorManager();

        if (indicatorManager == null && showIndicator) {
            indicatorManager = new DotIndicatorManager();
        }

        if (indicatorManager != null) {
            indicatorContainer
                    .addView(indicatorManager.init(LayoutInflater.from(this), indicatorContainer, slides.size()));

            indicatorManager.setListener(new IndicatorManager.OnUserSelectionListener() {
                @Override
                public void onSelection(int position) {
                    pager.setCurrentItem(position);
                }
            });
        }
    }

    private void initViews() {
        next.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final int currentIndex = pager.getCurrentItem();

                if (currentIndex == rtlAwarePosition(slides.size() - 1)) {
                    handleFinish();
                } else {
                    pager.setCurrentItem(nextPosition(currentIndex), true);
                }
            }
        });

        previous.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                pager.setCurrentItem(previousPosition(pager.getCurrentItem()), true);
            }
        });

        pager.setAdapter(new PagerAdapter(getSupportFragmentManager(), slides));
        pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                // Not needed
            }

            @Override
            public void onPageSelected(int position) {
                if (position != previousPagerPosition) {
                    select(position);

                    IntroductionConfiguration.getInstance().callOnSlideChanged(previousPagerPosition,
                            rtlAwarePosition(position));
                    previousPagerPosition = position;
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {
                // Not needed
            }
        });

        previous.bringToFront();
        next.bringToFront();

        if (configuration.getPageTransformer() != null) {
            pager.setPageTransformer(true, configuration.getPageTransformer());
        }

        if (skipText != null) {
            skip.setText(skipText);
            skip.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    handleFinish();
                }
            });
        }
    }

    private void select(int position) {
        if (indicatorManager != null) {
            indicatorManager.select(rtlAwarePosition(position));
        }

        if (buttonManager != null) {
            buttonManager.select(rtlAwarePosition(position));
        }
    }

    @Override
    public void onBackPressed() {
        if (pager.getCurrentItem() == rtlAwarePosition(0)) {
            if (allowBackPress) {
                handleFinishCancelled();
            }
        } else {
            pager.setCurrentItem(previousPosition(pager.getCurrentItem()));
        }
    }

    private void handleFinish() {
        clean();
        ArrayList<Option> options = new ArrayList<>();

        for (Slide slide : slides) {
            if (slide.getOption() != null) {
                options.add(slide.getOption());
            }
        }

        Intent result = new Intent();

        result.putParcelableArrayListExtra(OPTION_RESULT, options);
        setResult(RESULT_OK, result);
        finish();
    }

    private void handleFinishCancelled() {
        clean();
        setResult(RESULT_CANCELED);
        finish();
    }

    private void clean() {
        if (indicatorManager != null) {
            indicatorManager.setListener(null);
        }

        IntroductionConfiguration.destroy();
    }

    private int rtlAwarePosition(final int position) {
        if (OrientationUtils.isRTL(this)) {
            return slides.size() - position - 1;
        } else {
            return position;
        }
    }

    private int nextPosition(final int position) {
        return OrientationUtils.isRTL(this) ? position - 1 : position + 1;
    }

    private int previousPosition(final int position) {
        return OrientationUtils.isRTL(this) ? position + 1 : position - 1;
    }
}