1bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee/* This file is auto-generated from OnboardingFragment.java. DO NOT MODIFY. */ 2bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee 3bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee/* 4bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * Copyright (C) 2015 The Android Open Source Project 5bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * 6bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * Licensed under the Apache License, Version 2.0 (the "License"); 7bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * you may not use this file except in compliance with the License. 8bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * You may obtain a copy of the License at 9bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * 10bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * http://www.apache.org/licenses/LICENSE-2.0 11bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * 12bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * Unless required by applicable law or agreed to in writing, software 13bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * distributed under the License is distributed on an "AS IS" BASIS, 14bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * See the License for the specific language governing permissions and 16bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * limitations under the License. 17bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee */ 18bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee 19bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Leepackage android.support.v17.leanback.app; 20bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee 21bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Leeimport android.animation.Animator; 22bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Leeimport android.animation.AnimatorInflater; 23bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Leeimport android.animation.AnimatorListenerAdapter; 24bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Leeimport android.animation.AnimatorSet; 25bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Leeimport android.animation.ObjectAnimator; 26bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Leeimport android.animation.TimeInterpolator; 27e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Leeimport android.support.v4.app.FragmentActivity; 28bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Leeimport android.support.v4.app.Fragment; 29bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Leeimport android.os.Bundle; 30bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Leeimport android.support.annotation.Nullable; 31bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Leeimport android.support.v17.leanback.R; 32bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Leeimport android.support.v17.leanback.widget.PagingIndicator; 33e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Leeimport android.util.Log; 34e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Leeimport android.util.TypedValue; 35e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Leeimport android.view.ContextThemeWrapper; 36bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Leeimport android.view.Gravity; 37bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Leeimport android.view.KeyEvent; 38bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Leeimport android.view.LayoutInflater; 39bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Leeimport android.view.View; 40bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Leeimport android.view.View.OnClickListener; 41bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Leeimport android.view.View.OnKeyListener; 42bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Leeimport android.view.ViewGroup; 43bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Leeimport android.view.ViewTreeObserver.OnPreDrawListener; 44bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Leeimport android.view.animation.AccelerateInterpolator; 45bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Leeimport android.view.animation.DecelerateInterpolator; 46bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Leeimport android.widget.ImageView; 47bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Leeimport android.widget.TextView; 48bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee 49bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Leeimport java.util.ArrayList; 50bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Leeimport java.util.List; 51bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee 52bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee/** 53dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * An OnboardingSupportFragment provides a common and simple way to build onboarding screen for 54dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * applications. 55bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * <p> 56bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * <h3>Building the screen</h3> 57bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * The view structure of onboarding screen is composed of the common parts and custom parts. The 58bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * common parts are composed of title, description and page navigator and the custom parts are 59bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * composed of background, contents and foreground. 60bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * <p> 61bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * To build the screen views, the inherited class should override: 62bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * <ul> 63bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * <li>{@link #onCreateBackgroundView} to provide the background view. Background view has the same 64bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * size as the screen and the lowest z-order.</li> 65bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * <li>{@link #onCreateContentView} to provide the contents view. The content view is located in 66bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * the content area at the center of the screen.</li> 67bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * <li>{@link #onCreateForegroundView} to provide the foreground view. Foreground view has the same 68bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * size as the screen and the highest z-order</li> 69bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * </ul> 70bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * <p> 71bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * Each of these methods can return {@code null} if the application doesn't want to provide it. 72bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * <p> 73bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * <h3>Page information</h3> 74bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * The onboarding screen may have several pages which explain the functionality of the application. 75bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * The inherited class should provide the page information by overriding the methods: 76bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * <p> 77bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * <ul> 78bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * <li>{@link #getPageCount} to provide the number of pages.</li> 79bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * <li>{@link #getPageTitle} to provide the title of the page.</li> 80bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * <li>{@link #getPageDescription} to provide the description of the page.</li> 81bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * </ul> 82bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * <p> 83dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * Note that the information is used in {@link #onCreateView}, so should be initialized before 84ebe4901e5e467a8ff9a4e2a203a589f9755de329Chulwoo Lee * calling {@code super.onCreateView}. 85bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * <p> 86bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * <h3>Animation</h3> 87dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * Onboarding screen has three kinds of animations: 88dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * <p> 89dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * <h4>Logo Splash Animation</a></h4> 90dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * When onboarding screen appears, the logo splash animation is played by default. The animation 91dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * fades in the logo image, pauses in a few seconds and fades it out. 92bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * <p> 93dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * In most cases, the logo animation needs to be customized because the logo images of applications 94dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * are different from each other, or some applications may want to show their own animations. 95dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * <p> 96dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * The logo animation can be customized in two ways: 97bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * <ul> 98dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * <li>The simplest way is to provide the logo image by calling {@link #setLogoResourceId} to show 99dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * the default logo animation. This method should be called in {@link Fragment#onCreateView}.</li> 100dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * <li>If the logo animation is complex, then override {@link #onCreateLogoAnimation} and return the 101dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * {@link Animator} object to run.</li> 102bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * </ul> 103bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * <p> 104dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * If the inherited class provides neither the logo image nor the animation, the logo animation will 105dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * be omitted. 106dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * <h4>Page enter animation</h4> 107dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * After logo animation finishes, page enter animation starts. The application can provide the 108dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * animations of custom views by overriding {@link #onCreateEnterAnimation}. 109dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * <h4>Page change animation</h4> 110dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * When the page changes, the default animations of the title and description are played. The 111dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * inherited class can override {@link #onPageChanged} to start the custom animations. 112dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * <p> 113bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * <h3>Finishing the screen</h3> 114bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * <p> 115bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * If the user finishes the onboarding screen after navigating all the pages, 116bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * {@link #onFinishFragment} is called. The inherited class can override this method to show another 117bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * fragment or activity, or just remove this fragment. 118e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee * <p> 119e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee * <h3>Theming</h3> 120e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee * <p> 121e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee * OnboardingSupportFragment must have access to an appropriate theme. Specifically, the fragment must 122e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee * receive {@link R.style#Theme_Leanback_Onboarding}, or a theme whose parent is set to that theme. 123e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee * Themes can be provided in one of three ways: 124e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee * <ul> 125e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee * <li>The simplest way is to set the theme for the host Activity to the Onboarding theme or a theme 126e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee * that derives from it.</li> 127e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee * <li>If the Activity already has a theme and setting its parent theme is inconvenient, the 128e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee * existing Activity theme can have an entry added for the attribute 129e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee * {@link R.styleable#LeanbackOnboardingTheme_onboardingTheme}. If present, this theme will be used 130e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee * by OnboardingSupportFragment as an overlay to the Activity's theme.</li> 131e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee * <li>Finally, custom subclasses of OnboardingSupportFragment may provide a theme through the 132e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee * {@link #onProvideTheme} method. This can be useful if a subclass is used across multiple 133e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee * Activities.</li> 134e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee * </ul> 135e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee * <p> 136e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee * If the theme is provided in multiple ways, the onProvideTheme override has priority, followed by 137e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee * the Activity's theme. (Themes whose parent theme is already set to the onboarding theme do not 138e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee * need to set the onboardingTheme attribute; if set, it will be ignored.) 139bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * 140ebe4901e5e467a8ff9a4e2a203a589f9755de329Chulwoo Lee * @attr ref R.styleable#LeanbackOnboardingTheme_onboardingTheme 141ebe4901e5e467a8ff9a4e2a203a589f9755de329Chulwoo Lee * @attr ref R.styleable#LeanbackOnboardingTheme_onboardingHeaderStyle 142ebe4901e5e467a8ff9a4e2a203a589f9755de329Chulwoo Lee * @attr ref R.styleable#LeanbackOnboardingTheme_onboardingTitleStyle 143ebe4901e5e467a8ff9a4e2a203a589f9755de329Chulwoo Lee * @attr ref R.styleable#LeanbackOnboardingTheme_onboardingDescriptionStyle 144ebe4901e5e467a8ff9a4e2a203a589f9755de329Chulwoo Lee * @attr ref R.styleable#LeanbackOnboardingTheme_onboardingNavigatorContainerStyle 145ebe4901e5e467a8ff9a4e2a203a589f9755de329Chulwoo Lee * @attr ref R.styleable#LeanbackOnboardingTheme_onboardingPageIndicatorStyle 146ebe4901e5e467a8ff9a4e2a203a589f9755de329Chulwoo Lee * @attr ref R.styleable#LeanbackOnboardingTheme_onboardingStartButtonStyle 147ebe4901e5e467a8ff9a4e2a203a589f9755de329Chulwoo Lee * @attr ref R.styleable#LeanbackOnboardingTheme_onboardingLogoStyle 148bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee */ 149bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Leeabstract public class OnboardingSupportFragment extends Fragment { 150e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee private static final String TAG = "OnboardingSupportFragment"; 151e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee private static final boolean DEBUG = false; 152e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee 153bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee private static final long LOGO_SPLASH_PAUSE_DURATION_MS = 1333; 154bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee private static final long START_DELAY_TITLE_MS = 33; 155bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee private static final long START_DELAY_DESCRIPTION_MS = 33; 156bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee 157bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee private static final long HEADER_ANIMATION_DURATION_MS = 417; 158bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee private static final long DESCRIPTION_START_DELAY_MS = 33; 159bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee private static final long HEADER_APPEAR_DELAY_MS = 500; 160bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee private static final int SLIDE_DISTANCE = 60; 161bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee 162bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee private static int sSlideDistance; 163bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee 164bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee private static final TimeInterpolator HEADER_APPEAR_INTERPOLATOR = new DecelerateInterpolator(); 165bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee private static final TimeInterpolator HEADER_DISAPPEAR_INTERPOLATOR 166bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee = new AccelerateInterpolator(); 167bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee 168dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee // Keys used to save and restore the states. 169dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee private static final String KEY_CURRENT_PAGE_INDEX = "leanback.onboarding.current_page_index"; 170dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee 171e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee private ContextThemeWrapper mThemeWrapper; 172e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee 173bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee private PagingIndicator mPageIndicator; 174bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee private View mStartButton; 175bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee private ImageView mLogoView; 176bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee private TextView mTitleView; 177bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee private TextView mDescriptionView; 178bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee 1796cb24d438e700ceb0a8b7d5a93683b19eae6c1b5Chulwoo Lee private boolean mIsLtr; 180e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee 181dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee // No need to save/restore the logo resource ID, because the logo animation will not appear when 182dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee // the fragment is restored. 183dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee private int mLogoResourceId; 184bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee private boolean mEnterTransitionFinished; 185bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee private int mCurrentPageIndex; 186bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee 187bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee private AnimatorSet mAnimator; 188bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee 189bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee private final OnClickListener mOnClickListener = new OnClickListener() { 190bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee @Override 191bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee public void onClick(View view) { 192bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee if (!mEnterTransitionFinished) { 193bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee // Do not change page until the enter transition finishes. 194bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee return; 195bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 196bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee if (mCurrentPageIndex == getPageCount() - 1) { 197bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee onFinishFragment(); 198bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } else { 1996cb24d438e700ceb0a8b7d5a93683b19eae6c1b5Chulwoo Lee moveToNextPage(); 200bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 201bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 202bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee }; 203bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee 204bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee private final OnKeyListener mOnKeyListener = new OnKeyListener() { 205bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee @Override 206bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee public boolean onKey(View v, int keyCode, KeyEvent event) { 207bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee if (!mEnterTransitionFinished) { 208bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee // Ignore key event until the enter transition finishes. 209bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee return keyCode != KeyEvent.KEYCODE_BACK; 210bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 211bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee if (event.getAction() == KeyEvent.ACTION_DOWN) { 212bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee return false; 213bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 214bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee switch (keyCode) { 215bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee case KeyEvent.KEYCODE_BACK: 216bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee if (mCurrentPageIndex == 0) { 217bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee return false; 218bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 2196cb24d438e700ceb0a8b7d5a93683b19eae6c1b5Chulwoo Lee moveToPreviousPage(); 2206cb24d438e700ceb0a8b7d5a93683b19eae6c1b5Chulwoo Lee return true; 221bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee case KeyEvent.KEYCODE_DPAD_LEFT: 2226cb24d438e700ceb0a8b7d5a93683b19eae6c1b5Chulwoo Lee if (mIsLtr) { 2236cb24d438e700ceb0a8b7d5a93683b19eae6c1b5Chulwoo Lee moveToPreviousPage(); 2246cb24d438e700ceb0a8b7d5a93683b19eae6c1b5Chulwoo Lee } else { 2256cb24d438e700ceb0a8b7d5a93683b19eae6c1b5Chulwoo Lee moveToNextPage(); 226bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 227bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee return true; 228bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee case KeyEvent.KEYCODE_DPAD_RIGHT: 2296cb24d438e700ceb0a8b7d5a93683b19eae6c1b5Chulwoo Lee if (mIsLtr) { 2306cb24d438e700ceb0a8b7d5a93683b19eae6c1b5Chulwoo Lee moveToNextPage(); 2316cb24d438e700ceb0a8b7d5a93683b19eae6c1b5Chulwoo Lee } else { 2326cb24d438e700ceb0a8b7d5a93683b19eae6c1b5Chulwoo Lee moveToPreviousPage(); 233bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 234bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee return true; 235bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 236bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee return false; 237bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 238bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee }; 239bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee 2406cb24d438e700ceb0a8b7d5a93683b19eae6c1b5Chulwoo Lee private void moveToPreviousPage() { 2416cb24d438e700ceb0a8b7d5a93683b19eae6c1b5Chulwoo Lee if (mCurrentPageIndex > 0) { 2426cb24d438e700ceb0a8b7d5a93683b19eae6c1b5Chulwoo Lee --mCurrentPageIndex; 2436cb24d438e700ceb0a8b7d5a93683b19eae6c1b5Chulwoo Lee onPageChangedInternal(mCurrentPageIndex + 1); 2446cb24d438e700ceb0a8b7d5a93683b19eae6c1b5Chulwoo Lee } 2456cb24d438e700ceb0a8b7d5a93683b19eae6c1b5Chulwoo Lee } 2466cb24d438e700ceb0a8b7d5a93683b19eae6c1b5Chulwoo Lee private void moveToNextPage() { 2476cb24d438e700ceb0a8b7d5a93683b19eae6c1b5Chulwoo Lee if (mCurrentPageIndex < getPageCount() - 1) { 2486cb24d438e700ceb0a8b7d5a93683b19eae6c1b5Chulwoo Lee ++mCurrentPageIndex; 2496cb24d438e700ceb0a8b7d5a93683b19eae6c1b5Chulwoo Lee onPageChangedInternal(mCurrentPageIndex - 1); 2506cb24d438e700ceb0a8b7d5a93683b19eae6c1b5Chulwoo Lee } 2516cb24d438e700ceb0a8b7d5a93683b19eae6c1b5Chulwoo Lee } 2526cb24d438e700ceb0a8b7d5a93683b19eae6c1b5Chulwoo Lee 253bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee @Nullable 254bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee @Override 255bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee public View onCreateView(LayoutInflater inflater, final ViewGroup container, 256bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee Bundle savedInstanceState) { 257e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee resolveTheme(); 258e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee LayoutInflater localInflater = getThemeInflater(inflater); 2591e0f144c00c249ce3673ae10c1398537cd354f15Chulwoo Lee final ViewGroup view = (ViewGroup) localInflater.inflate(R.layout.lb_onboarding_fragment, 260e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee container, false); 2616cb24d438e700ceb0a8b7d5a93683b19eae6c1b5Chulwoo Lee mIsLtr = getResources().getConfiguration().getLayoutDirection() 2626cb24d438e700ceb0a8b7d5a93683b19eae6c1b5Chulwoo Lee == View.LAYOUT_DIRECTION_LTR; 263bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee mPageIndicator = (PagingIndicator) view.findViewById(R.id.page_indicator); 264bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee mPageIndicator.setOnClickListener(mOnClickListener); 265bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee mPageIndicator.setOnKeyListener(mOnKeyListener); 266bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee mStartButton = view.findViewById(R.id.button_start); 267bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee mStartButton.setOnClickListener(mOnClickListener); 268bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee mStartButton.setOnKeyListener(mOnKeyListener); 269bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee mLogoView = (ImageView) view.findViewById(R.id.logo); 270bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee mTitleView = (TextView) view.findViewById(R.id.title); 271bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee mDescriptionView = (TextView) view.findViewById(R.id.description); 272bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee if (sSlideDistance == 0) { 273bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee sSlideDistance = (int) (SLIDE_DISTANCE * getActivity().getResources() 274bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee .getDisplayMetrics().scaledDensity); 275bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 276dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee if (savedInstanceState == null) { 277dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee mCurrentPageIndex = 0; 278dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee mEnterTransitionFinished = false; 279dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee mPageIndicator.onPageSelected(0, false); 2801e0f144c00c249ce3673ae10c1398537cd354f15Chulwoo Lee view.getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() { 281bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee @Override 282bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee public boolean onPreDraw() { 2831e0f144c00c249ce3673ae10c1398537cd354f15Chulwoo Lee view.getViewTreeObserver().removeOnPreDrawListener(this); 284dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee if (!startLogoAnimation()) { 285dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee startEnterAnimation(); 286dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee } 287bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee return true; 288bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 289bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee }); 290bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } else { 291dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee mEnterTransitionFinished = true; 292dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee mCurrentPageIndex = savedInstanceState.getInt(KEY_CURRENT_PAGE_INDEX); 293dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee initializeViews(view); 294bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 295dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee view.requestFocus(); 296bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee return view; 297bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 298bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee 299dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee @Override 300dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee public void onSaveInstanceState(Bundle outState) { 301dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee super.onSaveInstanceState(outState); 302dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee outState.putInt(KEY_CURRENT_PAGE_INDEX, mCurrentPageIndex); 303dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee } 304dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee 305dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee /** 306e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee * Returns the theme used for styling the fragment. The default returns -1, indicating that the 307e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee * host Activity's theme should be used. 308e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee * 309e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee * @return The theme resource ID of the theme to use in this fragment, or -1 to use the host 310e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee * Activity's theme. 311e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee */ 312e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee public int onProvideTheme() { 313e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee return -1; 314e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee } 315e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee 316e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee private void resolveTheme() { 317e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee FragmentActivity activity = getActivity(); 318e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee int theme = onProvideTheme(); 319e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee if (theme == -1) { 320e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee // Look up the onboardingTheme in the activity's currently specified theme. If it 321e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee // exists, wrap the theme with its value. 322e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee int resId = R.attr.onboardingTheme; 323e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee TypedValue typedValue = new TypedValue(); 324e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee boolean found = activity.getTheme().resolveAttribute(resId, typedValue, true); 325e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee if (DEBUG) Log.v(TAG, "Found onboarding theme reference? " + found); 326e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee if (found) { 327e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee mThemeWrapper = new ContextThemeWrapper(activity, typedValue.resourceId); 328e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee } 329e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee } else { 330e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee mThemeWrapper = new ContextThemeWrapper(activity, theme); 331e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee } 332e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee } 333e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee 334e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee private LayoutInflater getThemeInflater(LayoutInflater inflater) { 335e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee return mThemeWrapper == null ? inflater : inflater.cloneInContext(mThemeWrapper); 336e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee } 337e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee 338e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee /** 339dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * Sets the resource ID of the splash logo image. If the logo resource id set, the default logo 340dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * splash animation will be played. 341dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * 342dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * @param id The resource ID of the logo image. 343dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee */ 344dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee public final void setLogoResourceId(int id) { 345dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee mLogoResourceId = id; 346dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee } 347dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee 348dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee /** 349dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * Returns the resource ID of the splash logo image. 350dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * 351dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * @return The resource ID of the splash logo image. 352dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee */ 353dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee public final int getLogoResourceId() { 354dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee return mLogoResourceId; 355dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee } 356dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee 357dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee /** 358dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * Called to have the inherited class create its own logo animation. 359dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * <p> 360dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * This is called only if the logo image resource ID is not set by {@link #setLogoResourceId}. 361dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * If this returns {@code null}, the logo animation is skipped. 362dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * 363dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * @return The {@link Animator} object which runs the logo animation. 364dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee */ 365dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee @Nullable 366dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee protected Animator onCreateLogoAnimation() { 367dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee return null; 368dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee } 369dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee 370dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee private boolean startLogoAnimation() { 371dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee Animator animator = null; 372dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee if (mLogoResourceId != 0) { 373dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee mLogoView.setVisibility(View.VISIBLE); 374dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee mLogoView.setImageResource(mLogoResourceId); 375dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee Animator inAnimator = AnimatorInflater.loadAnimator(getActivity(), 376dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee R.animator.lb_onboarding_logo_enter); 377dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee Animator outAnimator = AnimatorInflater.loadAnimator(getActivity(), 378dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee R.animator.lb_onboarding_logo_exit); 379dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee outAnimator.setStartDelay(LOGO_SPLASH_PAUSE_DURATION_MS); 380dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee AnimatorSet logoAnimator = new AnimatorSet(); 381dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee logoAnimator.playSequentially(inAnimator, outAnimator); 382dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee logoAnimator.setTarget(mLogoView); 383dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee animator = logoAnimator; 384dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee } else { 385dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee animator = onCreateLogoAnimation(); 386dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee } 387dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee if (animator != null) { 388dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee animator.addListener(new AnimatorListenerAdapter() { 389dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee @Override 390dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee public void onAnimationEnd(Animator animation) { 391dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee if (getActivity() != null) { 392dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee startEnterAnimation(); 393dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee } 394bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 395dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee }); 396dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee animator.start(); 397dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee return true; 398dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee } 399dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee return false; 400dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee } 401dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee 402dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee /** 403dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * Called to have the inherited class create its enter animation. The start animation runs after 404dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * logo animation ends. 405dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * 406dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * @return The {@link Animator} object which runs the page enter animation. 407dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee */ 408dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee @Nullable 409dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee protected Animator onCreateEnterAnimation() { 410dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee return null; 411bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 412bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee 413dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee private void initializeViews(View container) { 414bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee mLogoView.setVisibility(View.GONE); 415bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee // Create custom views. 416e22092227572db7e749e5cbb8139aa79a18fecd5Chulwoo Lee LayoutInflater inflater = getThemeInflater(LayoutInflater.from(getActivity())); 417dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee ViewGroup backgroundContainer = (ViewGroup) container.findViewById( 418bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee R.id.background_container); 419bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee View background = onCreateBackgroundView(inflater, backgroundContainer); 420bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee if (background != null) { 421bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee backgroundContainer.setVisibility(View.VISIBLE); 422bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee backgroundContainer.addView(background); 423bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 424dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee ViewGroup contentContainer = (ViewGroup) container.findViewById(R.id.content_container); 425bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee View content = onCreateContentView(inflater, contentContainer); 426bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee if (content != null) { 427bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee contentContainer.setVisibility(View.VISIBLE); 428bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee contentContainer.addView(content); 429bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 430dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee ViewGroup foregroundContainer = (ViewGroup) container.findViewById( 431bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee R.id.foreground_container); 432bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee View foreground = onCreateForegroundView(inflater, foregroundContainer); 433bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee if (foreground != null) { 434bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee foregroundContainer.setVisibility(View.VISIBLE); 435bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee foregroundContainer.addView(foreground); 436bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 437bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee // Make views visible which were invisible while logo animation is running. 438dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee container.findViewById(R.id.page_container).setVisibility(View.VISIBLE); 439dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee container.findViewById(R.id.content_container).setVisibility(View.VISIBLE); 440dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee if (getPageCount() > 1) { 441dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee mPageIndicator.setPageCount(getPageCount()); 442dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee mPageIndicator.onPageSelected(mCurrentPageIndex, false); 443dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee } 444dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee if (mCurrentPageIndex == getPageCount() - 1) { 445bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee mStartButton.setVisibility(View.VISIBLE); 446bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } else { 447bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee mPageIndicator.setVisibility(View.VISIBLE); 448bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 449dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee // Header views. 450dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee mTitleView.setText(getPageTitle(mCurrentPageIndex)); 451dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee mDescriptionView.setText(getPageDescription(mCurrentPageIndex)); 452dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee } 453dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee 454dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee private void startEnterAnimation() { 455dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee mEnterTransitionFinished = true; 456dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee initializeViews(getView()); 457dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee List<Animator> animators = new ArrayList<>(); 458dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee Animator animator = AnimatorInflater.loadAnimator(getActivity(), 459dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee R.animator.lb_onboarding_page_indicator_enter); 460dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee animator.setTarget(getPageCount() <= 1 ? mStartButton : mPageIndicator); 461bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee animators.add(animator); 462bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee // Header title 463bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee View view = getActivity().findViewById(R.id.title); 464bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee view.setAlpha(0); 465bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee animator = AnimatorInflater.loadAnimator(getActivity(), 466bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee R.animator.lb_onboarding_title_enter); 467bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee animator.setStartDelay(START_DELAY_TITLE_MS); 468bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee animator.setTarget(view); 469bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee animators.add(animator); 470bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee // Header description 471bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee view = getActivity().findViewById(R.id.description); 472bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee view.setAlpha(0); 473bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee animator = AnimatorInflater.loadAnimator(getActivity(), 474bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee R.animator.lb_onboarding_description_enter); 475bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee animator.setStartDelay(START_DELAY_DESCRIPTION_MS); 476bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee animator.setTarget(view); 477bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee animators.add(animator); 478dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee // Customized animation by the inherited class. 479dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee Animator customAnimator = onCreateEnterAnimation(); 480dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee if (customAnimator != null) { 481dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee animators.add(customAnimator); 482dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee } 483bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee mAnimator = new AnimatorSet(); 484bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee mAnimator.playTogether(animators); 485bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee mAnimator.start(); 486bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee // Search focus and give the focus to the appropriate child which has become visible. 487bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee getView().requestFocus(); 488bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 489bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee 490bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee /** 491bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * Returns the page count. 492bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * 493bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * @return The page count. 494bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee */ 495bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee abstract protected int getPageCount(); 496bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee 497bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee /** 498bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * Returns the title of the given page. 499bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * 500bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * @param pageIndex The page index. 501bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * 502bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * @return The title of the page. 503bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee */ 504ebe4901e5e467a8ff9a4e2a203a589f9755de329Chulwoo Lee abstract protected CharSequence getPageTitle(int pageIndex); 505bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee 506bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee /** 507bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * Returns the description of the given page. 508bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * 509bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * @param pageIndex The page index. 510bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * 511bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * @return The description of the page. 512bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee */ 513ebe4901e5e467a8ff9a4e2a203a589f9755de329Chulwoo Lee abstract protected CharSequence getPageDescription(int pageIndex); 514bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee 515bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee /** 516bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * Returns the index of the current page. 517bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * 518bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * @return The index of the current page. 519bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee */ 520bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee protected final int getCurrentPageIndex() { 521bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee return mCurrentPageIndex; 522bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 523bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee 524bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee /** 525bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * Called to have the inherited class create background view. This is optional and the fragment 526bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * which doesn't have the background view can return {@code null}. This is called inside 527bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * {@link #onCreateView}. 528bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * 529bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * @param inflater The LayoutInflater object that can be used to inflate the views, 530bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * @param container The parent view that the additional views are attached to.The fragment 531bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * should not add the view by itself. 532bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * 533bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * @return The background view for the onboarding screen, or {@code null}. 534bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee */ 535bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee @Nullable 536bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee abstract protected View onCreateBackgroundView(LayoutInflater inflater, ViewGroup container); 537bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee 538bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee /** 539bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * Called to have the inherited class create content view. This is optional and the fragment 540bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * which doesn't have the content view can return {@code null}. This is called inside 541bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * {@link #onCreateView}. 542bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * 543bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * <p>The content view would be located at the center of the screen. 544bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * 545bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * @param inflater The LayoutInflater object that can be used to inflate the views, 546bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * @param container The parent view that the additional views are attached to.The fragment 547bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * should not add the view by itself. 548bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * 549bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * @return The content view for the onboarding screen, or {@code null}. 550bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee */ 551bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee @Nullable 552bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee abstract protected View onCreateContentView(LayoutInflater inflater, ViewGroup container); 553bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee 554bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee /** 555bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * Called to have the inherited class create foreground view. This is optional and the fragment 556bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * which doesn't need the foreground view can return {@code null}. This is called inside 557bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * {@link #onCreateView}. 558bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * 559bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * <p>This foreground view would have the highest z-order. 560bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * 561bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * @param inflater The LayoutInflater object that can be used to inflate the views, 562bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * @param container The parent view that the additional views are attached to.The fragment 563bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * should not add the view by itself. 564bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * 565bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * @return The foreground view for the onboarding screen, or {@code null}. 566bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee */ 567bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee @Nullable 568bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee abstract protected View onCreateForegroundView(LayoutInflater inflater, ViewGroup container); 569bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee 570bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee /** 571bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * Called when the onboarding flow finishes. 572bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee */ 573bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee protected void onFinishFragment() { } 574bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee 575bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee /** 576bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee * Called when the page changes. 577bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee */ 578dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee private void onPageChangedInternal(int previousPage) { 579bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee if (mAnimator != null) { 580bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee mAnimator.end(); 581bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 582bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee mPageIndicator.onPageSelected(mCurrentPageIndex, true); 583bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee 584bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee List<Animator> animators = new ArrayList<>(); 585bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee // Header animation 586bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee Animator fadeAnimator = null; 587bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee if (previousPage < getCurrentPageIndex()) { 588bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee // sliding to left 589bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee animators.add(createAnimator(mTitleView, false, Gravity.START, 0)); 590bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee animators.add(fadeAnimator = createAnimator(mDescriptionView, false, Gravity.START, 591bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee DESCRIPTION_START_DELAY_MS)); 592bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee animators.add(createAnimator(mTitleView, true, Gravity.END, 593bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee HEADER_APPEAR_DELAY_MS)); 594bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee animators.add(createAnimator(mDescriptionView, true, Gravity.END, 595bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee HEADER_APPEAR_DELAY_MS + DESCRIPTION_START_DELAY_MS)); 596bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } else { 597bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee // sliding to right 598bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee animators.add(createAnimator(mTitleView, false, Gravity.END, 0)); 599bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee animators.add(fadeAnimator = createAnimator(mDescriptionView, false, Gravity.END, 600bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee DESCRIPTION_START_DELAY_MS)); 601bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee animators.add(createAnimator(mTitleView, true, Gravity.START, 602bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee HEADER_APPEAR_DELAY_MS)); 603bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee animators.add(createAnimator(mDescriptionView, true, Gravity.START, 604bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee HEADER_APPEAR_DELAY_MS + DESCRIPTION_START_DELAY_MS)); 605bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 606bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee final int currentPageIndex = getCurrentPageIndex(); 607bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee fadeAnimator.addListener(new AnimatorListenerAdapter() { 608bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee @Override 609bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee public void onAnimationEnd(Animator animation) { 610bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee mTitleView.setText(getPageTitle(currentPageIndex)); 611bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee mDescriptionView.setText(getPageDescription(currentPageIndex)); 612bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 613bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee }); 614bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee 615bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee // Animator for switching between page indicator and button. 616bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee if (getCurrentPageIndex() == getPageCount() - 1) { 617bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee mStartButton.setVisibility(View.VISIBLE); 618bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee Animator navigatorFadeOutAnimator = AnimatorInflater.loadAnimator(getActivity(), 619bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee R.animator.lb_onboarding_page_indicator_fade_out); 620bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee navigatorFadeOutAnimator.setTarget(mPageIndicator); 621bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee navigatorFadeOutAnimator.addListener(new AnimatorListenerAdapter() { 622bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee @Override 623bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee public void onAnimationEnd(Animator animation) { 624bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee mPageIndicator.setVisibility(View.GONE); 625bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 626bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee }); 6275740176a71133eeafeed3733c28470fbb590aac7Chulwoo Lee animators.add(navigatorFadeOutAnimator); 6285740176a71133eeafeed3733c28470fbb590aac7Chulwoo Lee Animator buttonFadeInAnimator = AnimatorInflater.loadAnimator(getActivity(), 6295740176a71133eeafeed3733c28470fbb590aac7Chulwoo Lee R.animator.lb_onboarding_start_button_fade_in); 6305740176a71133eeafeed3733c28470fbb590aac7Chulwoo Lee buttonFadeInAnimator.setTarget(mStartButton); 631bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee animators.add(buttonFadeInAnimator); 632bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } else if (previousPage == getPageCount() - 1) { 633bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee mPageIndicator.setVisibility(View.VISIBLE); 634bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee Animator navigatorFadeInAnimator = AnimatorInflater.loadAnimator(getActivity(), 635bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee R.animator.lb_onboarding_page_indicator_fade_in); 636bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee navigatorFadeInAnimator.setTarget(mPageIndicator); 6375740176a71133eeafeed3733c28470fbb590aac7Chulwoo Lee animators.add(navigatorFadeInAnimator); 638bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee Animator buttonFadeOutAnimator = AnimatorInflater.loadAnimator(getActivity(), 639bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee R.animator.lb_onboarding_start_button_fade_out); 640bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee buttonFadeOutAnimator.setTarget(mStartButton); 641bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee buttonFadeOutAnimator.addListener(new AnimatorListenerAdapter() { 642bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee @Override 643bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee public void onAnimationEnd(Animator animation) { 644bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee mStartButton.setVisibility(View.GONE); 645bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 646bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee }); 6475740176a71133eeafeed3733c28470fbb590aac7Chulwoo Lee animators.add(buttonFadeOutAnimator); 648bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 649bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee mAnimator = new AnimatorSet(); 650bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee mAnimator.playTogether(animators); 651bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee mAnimator.start(); 652dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee onPageChanged(mCurrentPageIndex, previousPage); 653bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 654bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee 655dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee /** 656dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * Called when the page has been changed. 657dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * 658dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * @param newPage The new page. 659dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee * @param previousPage The previous page. 660dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee */ 661dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee protected void onPageChanged(int newPage, int previousPage) { } 662dd667f84d7dc1c24207cb6e66ffa0e91caa640a3Chulwoo Lee 663bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee private Animator createAnimator(View view, boolean fadeIn, int slideDirection, 664bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee long startDelay) { 665bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee boolean isLtr = getView().getLayoutDirection() == View.LAYOUT_DIRECTION_LTR; 666bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee boolean slideRight = (isLtr && slideDirection == Gravity.END) 667bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee || (!isLtr && slideDirection == Gravity.START) 668bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee || slideDirection == Gravity.RIGHT; 669bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee Animator fadeAnimator; 670bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee Animator slideAnimator; 671bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee if (fadeIn) { 672bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee fadeAnimator = ObjectAnimator.ofFloat(view, View.ALPHA, 0.0f, 1.0f); 673bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee slideAnimator = ObjectAnimator.ofFloat(view, View.TRANSLATION_X, 674bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee slideRight ? sSlideDistance : -sSlideDistance, 0); 675bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee fadeAnimator.setInterpolator(HEADER_APPEAR_INTERPOLATOR); 676bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee slideAnimator.setInterpolator(HEADER_APPEAR_INTERPOLATOR); 677bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } else { 678bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee fadeAnimator = ObjectAnimator.ofFloat(view, View.ALPHA, 1.0f, 0.0f); 679bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee slideAnimator = ObjectAnimator.ofFloat(view, View.TRANSLATION_X, 0, 680bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee slideRight ? sSlideDistance : -sSlideDistance); 681bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee fadeAnimator.setInterpolator(HEADER_DISAPPEAR_INTERPOLATOR); 682bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee slideAnimator.setInterpolator(HEADER_DISAPPEAR_INTERPOLATOR); 683bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 684bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee fadeAnimator.setDuration(HEADER_ANIMATION_DURATION_MS); 685bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee fadeAnimator.setTarget(view); 686bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee slideAnimator.setDuration(HEADER_ANIMATION_DURATION_MS); 687bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee slideAnimator.setTarget(view); 688bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee AnimatorSet animator = new AnimatorSet(); 689bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee animator.playTogether(fadeAnimator, slideAnimator); 690bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee if (startDelay > 0) { 691bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee animator.setStartDelay(startDelay); 692bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 693bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee return animator; 694bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee } 695bc69c4a046bdabeaa72c28fcca0ceeb72517a81fChulwoo Lee} 696