Java tutorial
/* * 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.app.Activity; import android.content.Intent; import android.graphics.Typeface; import android.os.Bundle; import android.support.annotation.IntDef; import android.support.annotation.NonNull; import android.support.annotation.Size; import android.support.annotation.StringRes; import android.support.v4.view.ViewPager; import com.rubengees.introduction.entity.Slide; import com.rubengees.introduction.exception.IntroductionConfigurationException; import com.rubengees.introduction.interfaces.IndicatorManager; import com.rubengees.introduction.style.Style; import com.rubengees.introduction.style.TranslucentStyle; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * A Builder class with method chaining to create the IntroductionActivity. * * @author Ruben Gees */ public class IntroductionBuilder { public static final int INTRODUCTION_REQUEST_CODE = 32142; public static final int ORIENTATION_PORTRAIT = 0; public static final int ORIENTATION_LANDSCAPE = 1; public static final int ORIENTATION_BOTH = 2; static final String BUNDLE_SLIDES = "introduction_slides"; static final String BUNDLE_STYLE = "introduction_style"; static final String BUNDLE_ORIENTATION = "introduction_orientation"; static final String BUNDLE_SHOW_PREVIOUS_BUTTON = "introduction_show_previous_button"; static final String BUNDLE_SHOW_INDICATOR = "introduction_show_indicator"; static final String BUNDLE_SKIP_STRING = "introduction_skip_string"; static final String BUNDLE_SKIP_RESOURCE = "introduction_skip_resource"; static final String BUNDLE_ALLOW_BACK_PRESS = "introduction_allow_back_press"; private static final String EXCEPTION_SLIDE_AMOUNT_MESSAGE = "You must add at least one slide."; private static final String EXCEPTION_NO_SLIDES_MESSAGE = "You need to add slides."; private Activity context; private ArrayList<Slide> slides; private Style style; private Boolean showPreviousButton; private Boolean showIndicator; private String skipString; private Integer skipResource; private Boolean allowBackPress; @Orientation private Integer orientation; /** * The Activity the Introduction should start from. Any Callbacks are delivered to that one. * * @param context The Activity. */ public IntroductionBuilder(@NonNull Activity context) { this.context = context; this.slides = new ArrayList<>(); } /** * The Slides to display. * * @param slides A List of Slides. * @return The current instance. * @throws IllegalArgumentException If an empty list was passed. */ @NonNull public IntroductionBuilder withSlides(@NonNull @Size(min = 1) List<Slide> slides) { if (slides.isEmpty()) { throw new IntroductionConfigurationException(EXCEPTION_SLIDE_AMOUNT_MESSAGE); } this.slides.addAll(new ArrayList<>(slides)); return this; } /** * The Slides to display. * * @param slides A List of Slides. * @return The current instance. * @throws IllegalArgumentException If an empty list was passed. */ @NonNull public IntroductionBuilder withSlides(Slide... slides) { return withSlides(Arrays.asList(slides)); } /** * Sets the Style of the Activity. Currently are Translucent and Fullscreen available. * If this Method was not called, Translucent is selected as default. * * @param style The style. * @return The current instance. * @throws IllegalArgumentException If the provided int was not one of the available styles. */ @NonNull public IntroductionBuilder withStyle(@NonNull Style style) { this.style = style; return this; } /** * Assigns a custom IndicatorManager. If this Method is not called, the * {@link com.rubengees.introduction.common.DotIndicatorManager} will be used by default. * * @param manager The IndicatorManager. * @return The current instance. */ @NonNull public IntroductionBuilder withIndicatorManager(@NonNull IndicatorManager manager) { IntroductionConfiguration.getInstance().setIndicatorManager(manager); return this; } /** * Enables or disables the button to go back a Slide. This is just for design, it is still * possible to go back with swiping. If this Method is not called, the button will be enabled * by default. * * @param enabled True if the button should enabled, false otherwise. * @return The current instance. */ @NonNull public IntroductionBuilder withPreviousButtonEnabled(boolean enabled) { this.showPreviousButton = enabled; return this; } /** * Enables or disables the indicator. This method has a higher priority than * {@link #withIndicatorManager(IndicatorManager)}, so there will be no indicator, even if you * provided your own Manager. * * @param enabled True if indicators should disabled. * @return The current instance. */ @NonNull public IntroductionBuilder withIndicatorEnabled(boolean enabled) { this.showIndicator = enabled; return this; } /** * Specifies whether to show a skip button or not. * If you specified a resource earlier it will be overridden. * * @param text The text to show. * @return The current instance. */ @NonNull public IntroductionBuilder withSkipEnabled(@NonNull String text) { this.skipString = text; this.skipResource = null; return this; } /** * Specifies whether to show a skip button or not. * If you specified a text earlier it will be overridden. * * @param resource The resource to show. * @return The current instance. */ @NonNull public IntroductionBuilder withSkipEnabled(@StringRes int resource) { this.skipResource = resource; this.skipString = null; return this; } /** * Sets if t is allowed for the user to press the back button at the first slide to cancel the * introduction. The default value is false. * * @param allow If the back button cancels the introduction. * @return The current instance. */ public IntroductionBuilder withAllowBackPress(boolean allow) { this.allowBackPress = allow; return this; } /** * Forces an orientation for the Activity. Available are portrait, landscape and both. * If this Method is not called, there will be no forced orientation. * * @param orientation The orientation. * @return The current instance. * @throws IllegalArgumentException If the passed int is not one of the available orientations. */ @NonNull public IntroductionBuilder withForcedOrientation(@Orientation int orientation) { this.orientation = orientation; return this; } /** * Assigns a * {@link com.rubengees.introduction.IntroductionConfiguration.OnSlideListener} to the * Activity. * * @param onSlideChangedListener The listener. * @return The current instance. */ @NonNull public IntroductionBuilder withOnSlideListener( @NonNull IntroductionConfiguration.OnSlideListener onSlideChangedListener) { IntroductionConfiguration.getInstance().setOnSlideChangedListener(onSlideChangedListener); return this; } /** * Applies a PageTransformer to the Activity. You can * find some implementations in the commons package. * * @param pageTransformer The transformer. * @return The current instance. */ @NonNull public IntroductionBuilder withPageTransformer(@NonNull ViewPager.PageTransformer pageTransformer) { IntroductionConfiguration.getInstance().setPageTransformer(pageTransformer); return this; } /** * Sets a global typeface to apply on the titles and descriptions of slides. * * @param typeface The typeface. * @return The current instance. */ @NonNull public IntroductionBuilder withTypeface(@NonNull Typeface typeface) { IntroductionConfiguration.getInstance().setTitleTypeface(typeface); IntroductionConfiguration.getInstance().setDescriptionTypeface(typeface); return this; } /** * Sets a global typeface to apply only on titles of slides. * * @param typeface The typeface. * @return The current instance. */ @NonNull public IntroductionBuilder withTitleTypeface(@NonNull Typeface typeface) { IntroductionConfiguration.getInstance().setTitleTypeface(typeface); return this; } /** * Sets a global typeface to apply only on descriptions of slides. * * @param typeface The typeface. * @return The current instance. */ @NonNull public IntroductionBuilder withDescriptionTypeface(@NonNull Typeface typeface) { IntroductionConfiguration.getInstance().setDescriptionTypeface(typeface); return this; } private void check() { if (slides == null) { throw new IntroductionConfigurationException(EXCEPTION_NO_SLIDES_MESSAGE); } if (style == null) { style = new TranslucentStyle(); } if (orientation == null) { orientation = ORIENTATION_BOTH; } if (showPreviousButton == null) { showPreviousButton = true; } if (showIndicator == null) { showIndicator = true; } if (allowBackPress == null) { allowBackPress = false; } } /** * This Method finally start the Activity and displays the provided data. */ public void introduceMyself() { check(); Intent intent = new Intent(context, IntroductionActivity.class); Bundle bundle = new Bundle(); bundle.putParcelableArrayList(BUNDLE_SLIDES, slides); bundle.putSerializable(BUNDLE_STYLE, style); bundle.putInt(BUNDLE_ORIENTATION, orientation); bundle.putBoolean(BUNDLE_SHOW_PREVIOUS_BUTTON, showPreviousButton); bundle.putBoolean(BUNDLE_SHOW_INDICATOR, showIndicator); bundle.putString(BUNDLE_SKIP_STRING, skipString); bundle.putBoolean(BUNDLE_ALLOW_BACK_PRESS, allowBackPress); if (skipResource != null) { bundle.putInt(BUNDLE_SKIP_RESOURCE, skipResource); } intent.putExtras(bundle); Activity parent = context.getParent(); if (parent != null) { context = parent; } context.startActivityForResult(intent, INTRODUCTION_REQUEST_CODE); } @Retention(RetentionPolicy.SOURCE) @IntDef({ ORIENTATION_PORTRAIT, ORIENTATION_LANDSCAPE, ORIENTATION_BOTH }) public @interface Orientation { } }