package com.sebastianrask.bettersubscription.activities.setup; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import androidx.core.app.ActivityCompat; import androidx.core.app.ActivityOptionsCompat; import androidx.appcompat.app.AppCompatActivity; import android.util.DisplayMetrics; import android.util.Log; import android.util.TypedValue; import android.view.View; import android.view.ViewTreeObserver; import android.view.WindowManager; import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; import android.view.animation.AnimationSet; import android.view.animation.DecelerateInterpolator; import android.view.animation.OvershootInterpolator; import android.view.animation.RotateAnimation; import android.view.animation.ScaleAnimation; import android.view.animation.TranslateAnimation; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; import com.sebastianrask.bettersubscription.R; import com.sebastianrask.bettersubscription.activities.UsageTrackingAppCompatActivity; import com.sebastianrask.bettersubscription.activities.main.MyStreamsActivity; import com.sebastianrask.bettersubscription.activities.settings.SettingsNotificationsActivity; import com.sebastianrask.bettersubscription.misc.ResizeWidthAnimation; import com.sebastianrask.bettersubscription.service.Service; import com.sebastianrask.bettersubscription.service.Settings; import io.codetail.animation.SupportAnimator; import io.codetail.animation.ViewAnimationUtils; public class NotificationActivity extends UsageTrackingAppCompatActivity { private final String LOG_TAG = getClass().getSimpleName(); private SupportAnimator transitionAnimationWhite = null; private SupportAnimator transitionAnimationBlue = null; private int mFABWidth = 0; private boolean hasCustomized = false; private boolean hasTransitioned = false; private boolean hasSingleTransition = false; private final int EXPAND_DURATION = 500; private final int REVEAL_ANIMATION_DURATION = 650; private final int REVEAL_ANIMATION_DELAY = 200; private final int HIDE_VIEW_ANIMATION_DURATION = 550; private final int SHOW_LOGO_ANIMATION_DURATION = 600; private final int SHOW_TEXT_ANIMATION_DURATION = 600; private final int SHOW_TEXT_ANIMATION_BASE_DELAY = 105; private final int SHOW_TEXT_ANIMATION_DELAY = 105; private final int SHOW_CONTINUE_ICON_DURATION = 650; private final int SHOW_CONTINUE_ICON_DELAY = 600; private final int SHOW_CUSTOMIZE_TEXT_DURATION = 300; private final int SHOW_CUSTOMIZE_TEXT_DELAY = 200; private ImageView mGearIcon, mContinueIcon; private View mContinueFAB, mContinueFABShadow, mTransitionViewWhite, mTransitionViewBlue; private TextView mLoginTextLineOne, mCustomizeText, mSkipText; private RelativeLayout mLoginTextContainer, mLayout; private FrameLayout mContinueFABContainer; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_notification); mLayout = (RelativeLayout) findViewById(R.id.layout); mLoginTextContainer = (RelativeLayout) findViewById(R.id.notification_text_container); mContinueFABContainer = (FrameLayout) findViewById(R.id.notification_continue_circle_container); mGearIcon = (ImageView) findViewById(R.id.notification_icon); mContinueIcon = (ImageView) findViewById(R.id.forward_arrow); mLoginTextLineOne = (TextView) findViewById(R.id.notification_text_line_one); mCustomizeText = (TextView) findViewById(R.id.customize_text); mSkipText = (TextView) findViewById(R.id.skip_text); mContinueFAB = findViewById(R.id.notification_continue_circle); mContinueFABShadow = findViewById(R.id.notification_continue_circle_shadow); mTransitionViewWhite = findViewById(R.id.transition_view); mTransitionViewBlue = findViewById(R.id.transition_view_blue); mContinueIcon .setVisibility(View.INVISIBLE); mLoginTextLineOne .setVisibility(View.INVISIBLE); mSkipText .setVisibility(View.INVISIBLE); mGearIcon .setVisibility(View.INVISIBLE); mTransitionViewBlue .setVisibility(View.INVISIBLE); mTransitionViewWhite.setVisibility(View.INVISIBLE); mCustomizeText .setVisibility(View.INVISIBLE); float textPosition = (int) (2.5 * (getScreenHeight() / 5)); mLoginTextContainer .setY(textPosition); mContinueFABContainer .bringToFront(); mLoginTextLineOne .bringToFront(); Service.bringToBack(mTransitionViewWhite); Service.bringToBack(mTransitionViewBlue); showLogoAnimations(); showTextLineAnimations(mLoginTextLineOne, 1); showTextLineAnimations(mSkipText, 2); /* Wait until the view has been laid out and measured THEN expand the width of the FAB */ ViewTreeObserver vto = mLayout.getViewTreeObserver(); vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { mFABWidth = mContinueFABContainer.getMeasuredWidth(); expandContinueButtonAnimations(); ViewTreeObserver obs = mLayout.getViewTreeObserver(); obs.removeGlobalOnLayoutListener(this); } }); mSkipText.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { final SupportAnimator.AnimatorListener navigateToNextActivityListener = new SupportAnimator.AnimatorListener(){ @Override public void onAnimationStart() { } @Override public void onAnimationEnd() { navigateToNextActivity(); } @Override public void onAnimationCancel() { } @Override public void onAnimationRepeat() { } }; Animation.AnimationListener transitionAnimationListener = null; if(LoginActivity.hasLoadedFollows()) { hasSingleTransition = true; transitionAnimationListener = new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { showSingleTransitionAnimation().addListener(navigateToNextActivityListener); } @Override public void onAnimationRepeat(Animation animation) { } }; } else { hasSingleTransition = false; transitionAnimationListener = new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { showTransitionAnimation().addListener(navigateToNextActivityListener); } @Override public void onAnimationRepeat(Animation animation) { } }; } collapseContinueButtonAnimations().setAnimationListener(transitionAnimationListener); } }); mContinueFABContainer.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.i(LOG_TAG, hasTransitioned + ""); if(!hasTransitioned) { hasCustomized = true; Intent intent = new Intent(getBaseContext(), SettingsNotificationsActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); ActivityOptionsCompat settingsAnim = ActivityOptionsCompat.makeCustomAnimation(NotificationActivity.this, R.anim.slide_in_right_anim, R.anim.fade_out_semi_anim); ActivityCompat.startActivity(NotificationActivity.this, intent, settingsAnim.toBundle()); } else { mSkipText.performClick(); } } }); } @Override public void onWindowFocusChanged(boolean hasFocus) { if(hasFocus && hasCustomized){ new Handler().postDelayed(new Runnable() { @Override public void run() { mSkipText.performClick(); } }, 50); } } @Override public void onResume() { super.onResume(); Log.d(LOG_TAG, "On Resumes Activity"); if(transitionAnimationWhite != null && hasTransitioned) { if(hasSingleTransition) { showSingleReverseTransitionAnimation(); } else { showReverseTransitionAnimation(); } } } @Override public void onBackPressed() { collapseContinueButtonAnimations(); hideAllViews().setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { NotificationActivity.super.onBackPressed(); // We don't want a transition when going back. The activities handle the animation themselves. overridePendingTransition(0, 0); } @Override public void onAnimationRepeat(Animation animation) { } }); } private int getScreenHeight() { WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); final DisplayMetrics displayMetrics = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(displayMetrics); return displayMetrics.heightPixels; } private void navigateToNextActivity() { hasTransitioned = true; hasCustomized = false; Settings settings = new Settings(getBaseContext()); settings.setSetup(true); if(!LoginActivity.hasLoadedFollows()) { this.startActivity(new Intent(getBaseContext(), ConfirmSetupActivity.class)); this.overridePendingTransition(0, 0); } else { this.startActivity(new Intent(getBaseContext(), MyStreamsActivity.class)); this.overridePendingTransition(0, 0); } } /** Animations from here and down */ private SupportAnimator showSingleTransitionAnimation() { // Get the center for the FAB int cx = (int) mContinueFABContainer.getX() + mContinueFABContainer.getMeasuredHeight() / 2; int cy = (int) mContinueFABContainer.getY() + mContinueFABContainer.getMeasuredWidth() / 2; // get the final radius for the clipping circle int dx = Math.max(cx, mTransitionViewWhite.getWidth() - cx); int dy = Math.max(cy, mTransitionViewWhite.getHeight() - cy); float finalRadius = (float) Math.hypot(dx, dy); mTransitionViewBlue.setLayerType(View.LAYER_TYPE_HARDWARE, null); mTransitionViewWhite.setLayerType(View.LAYER_TYPE_HARDWARE, null); final SupportAnimator whiteTransitionAnimation = ViewAnimationUtils.createCircularReveal(mTransitionViewWhite, cx, cy, 0, finalRadius); whiteTransitionAnimation.setInterpolator(new AccelerateDecelerateInterpolator()); whiteTransitionAnimation.setDuration(REVEAL_ANIMATION_DURATION); whiteTransitionAnimation.addListener(new SupportAnimator.AnimatorListener() { @Override public void onAnimationStart() { mTransitionViewWhite.bringToFront(); mTransitionViewWhite.setVisibility(View.VISIBLE); mContinueFABContainer.setClickable(false); if(mContinueIcon.getVisibility() == View.VISIBLE) { hideContinueIconAnimations(); } } @Override public void onAnimationEnd() { transitionAnimationWhite = whiteTransitionAnimation; } @Override public void onAnimationCancel() { } @Override public void onAnimationRepeat() { } }); whiteTransitionAnimation.start(); return whiteTransitionAnimation; } private SupportAnimator showSingleReverseTransitionAnimation() { mTransitionViewWhite.setLayerType(View.LAYER_TYPE_HARDWARE, null); final SupportAnimator whiteReversed = transitionAnimationWhite.reverse(); whiteReversed.setInterpolator(new AccelerateDecelerateInterpolator()); whiteReversed.addListener(new SupportAnimator.AnimatorListener() { @Override public void onAnimationStart() { mTransitionViewWhite.setVisibility(View.VISIBLE); mTransitionViewWhite.bringToFront(); } @Override public void onAnimationEnd() { Service.bringToBack(mTransitionViewWhite); mTransitionViewWhite.setLayerType(View.LAYER_TYPE_NONE, null); mTransitionViewWhite.setVisibility(View.INVISIBLE); mContinueFABContainer.setClickable(true); mContinueIcon.bringToFront(); mContinueIcon.setVisibility(View.VISIBLE); showContinueIconAnimations(360); } @Override public void onAnimationCancel() { } @Override public void onAnimationRepeat() { } }); whiteReversed.setDuration(REVEAL_ANIMATION_DURATION); new Handler().postDelayed(new Runnable() { @Override public void run() { whiteReversed.start(); } }, REVEAL_ANIMATION_DELAY); return whiteReversed; } private SupportAnimator showTransitionAnimation() { // Get the center for the FAB int cx = (int) mContinueFABContainer.getX() + mContinueFABContainer.getMeasuredHeight() / 2; int cy = (int) mContinueFABContainer.getY() + mContinueFABContainer.getMeasuredWidth() / 2; // get the final radius for the clipping circle int dx = Math.max(cx, mTransitionViewWhite.getWidth() - cx); int dy = Math.max(cy, mTransitionViewWhite.getHeight() - cy); float finalRadius = (float) Math.hypot(dx, dy); mTransitionViewBlue.setLayerType(View.LAYER_TYPE_HARDWARE, null); mTransitionViewWhite.setLayerType(View.LAYER_TYPE_HARDWARE, null); final SupportAnimator whiteTransitionAnimation = ViewAnimationUtils.createCircularReveal(mTransitionViewWhite, cx, cy, 0, finalRadius); whiteTransitionAnimation.setInterpolator(new AccelerateDecelerateInterpolator()); whiteTransitionAnimation.setDuration(REVEAL_ANIMATION_DURATION); whiteTransitionAnimation.addListener(new SupportAnimator.AnimatorListener() { @Override public void onAnimationStart() { mTransitionViewWhite.bringToFront(); mTransitionViewWhite.setVisibility(View.VISIBLE); mContinueFABContainer.setClickable(false); if (mContinueIcon.getVisibility() == View.VISIBLE) { hideContinueIconAnimations(); } } @Override public void onAnimationEnd() { transitionAnimationWhite = whiteTransitionAnimation; } @Override public void onAnimationCancel() { } @Override public void onAnimationRepeat() { } }); final SupportAnimator blueTransitionAnimation = ViewAnimationUtils.createCircularReveal(mTransitionViewBlue, cx, cy, 0, finalRadius); blueTransitionAnimation.setInterpolator(new AccelerateDecelerateInterpolator()); blueTransitionAnimation.setDuration(REVEAL_ANIMATION_DURATION); blueTransitionAnimation.addListener(new SupportAnimator.AnimatorListener() { @Override public void onAnimationStart() { mTransitionViewBlue.setVisibility(View.VISIBLE); mTransitionViewBlue.bringToFront(); mContinueFABShadow.bringToFront(); mContinueFAB.bringToFront(); } @Override public void onAnimationEnd() { mTransitionViewBlue.setLayerType(View.LAYER_TYPE_NONE, null); mTransitionViewWhite.setLayerType(View.LAYER_TYPE_NONE, null); transitionAnimationBlue = blueTransitionAnimation; } @Override public void onAnimationCancel() { } @Override public void onAnimationRepeat() { } }); whiteTransitionAnimation.start(); blueTransitionAnimation.setStartDelay(REVEAL_ANIMATION_DELAY); blueTransitionAnimation.start(); return blueTransitionAnimation; } private SupportAnimator showReverseTransitionAnimation() { mTransitionViewBlue.setLayerType(View.LAYER_TYPE_HARDWARE, null); mTransitionViewWhite.setLayerType(View.LAYER_TYPE_HARDWARE, null); SupportAnimator blueReversed = transitionAnimationBlue.reverse(); blueReversed.setInterpolator(new AccelerateDecelerateInterpolator()); blueReversed.addListener(new SupportAnimator.AnimatorListener() { @Override public void onAnimationStart() { mTransitionViewBlue.setVisibility(View.VISIBLE); mTransitionViewBlue.bringToFront(); } @Override public void onAnimationEnd() { Service.bringToBack(mTransitionViewBlue); mTransitionViewBlue.setVisibility(View.INVISIBLE); } @Override public void onAnimationCancel() { } @Override public void onAnimationRepeat() { } }); blueReversed.setDuration(REVEAL_ANIMATION_DURATION); blueReversed.start(); final SupportAnimator whiteReversed = transitionAnimationWhite.reverse(); whiteReversed.setInterpolator(new AccelerateDecelerateInterpolator()); whiteReversed.addListener(new SupportAnimator.AnimatorListener() { @Override public void onAnimationStart() { mTransitionViewWhite.setVisibility(View.VISIBLE); mTransitionViewWhite.bringToFront(); } @Override public void onAnimationEnd() { Service.bringToBack(mTransitionViewWhite); mTransitionViewBlue.setLayerType(View.LAYER_TYPE_NONE, null); mTransitionViewWhite.setLayerType(View.LAYER_TYPE_NONE, null); mTransitionViewWhite.setVisibility(View.INVISIBLE); mContinueFABContainer.setClickable(true); mContinueIcon.bringToFront(); mContinueIcon.setVisibility(View.VISIBLE); showContinueIconAnimations(360); } @Override public void onAnimationCancel() { } @Override public void onAnimationRepeat() { } }); whiteReversed.setDuration(REVEAL_ANIMATION_DURATION); whiteReversed.setStartDelay(REVEAL_ANIMATION_DELAY); whiteReversed.start(); return whiteReversed; } private AnimationSet hideAllViews() { if(mContinueIcon.getVisibility() == View.VISIBLE) { hideContinueIconAnimations(); } hideViewAnimation(mGearIcon, HIDE_VIEW_ANIMATION_DURATION); hideViewAnimation(mLoginTextLineOne, HIDE_VIEW_ANIMATION_DURATION); return hideViewAnimation(mSkipText, HIDE_VIEW_ANIMATION_DURATION); } private AnimationSet hideViewAnimation(final View view, final int DURATION) { view.setLayerType(View.LAYER_TYPE_HARDWARE, null); Animation mScaleAnimation = new ScaleAnimation(1, 0, 1, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); mScaleAnimation.setDuration(DURATION); mScaleAnimation.setInterpolator(new OvershootInterpolator(0.7f)); Animation mAlphaAnimation = new AlphaAnimation(1f, 0f); mAlphaAnimation.setDuration(DURATION/2); mAlphaAnimation.setInterpolator(new DecelerateInterpolator()); mAlphaAnimation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { view.setVisibility(View.INVISIBLE); } @Override public void onAnimationRepeat(Animation animation) { } }); final AnimationSet mViewAnimations = new AnimationSet(false); mViewAnimations.setInterpolator(new AccelerateDecelerateInterpolator()); mViewAnimations.setFillBefore(true); mViewAnimations.setFillAfter(true); mViewAnimations.addAnimation(mScaleAnimation); mViewAnimations.addAnimation(mAlphaAnimation); mViewAnimations.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { view.setLayerType(View.LAYER_TYPE_NONE, null); } @Override public void onAnimationRepeat(Animation animation) { } }); view.startAnimation(mViewAnimations); return mViewAnimations; } private AnimationSet showLogoAnimations() { mGearIcon.setLayerType(View.LAYER_TYPE_HARDWARE, null); Animation mScaleAnimation = new ScaleAnimation(0, 1, 0, 1, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); mScaleAnimation.setDuration(SHOW_LOGO_ANIMATION_DURATION); mScaleAnimation.setInterpolator(new OvershootInterpolator(0.7f)); Animation mAlphaAnimation = new AlphaAnimation(0f, 1f); mAlphaAnimation.setDuration(SHOW_LOGO_ANIMATION_DURATION); mAlphaAnimation.setInterpolator(new DecelerateInterpolator()); mAlphaAnimation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { mGearIcon.setVisibility(View.VISIBLE); } @Override public void onAnimationEnd(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } }); final AnimationSet mLogoAnimations = new AnimationSet(false); mLogoAnimations.setInterpolator(new AccelerateDecelerateInterpolator()); mLogoAnimations.setFillBefore(true); mLogoAnimations.setFillAfter(true); mLogoAnimations.addAnimation(mScaleAnimation); mLogoAnimations.addAnimation(mAlphaAnimation); mLogoAnimations.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { mGearIcon.setLayerType(View.LAYER_TYPE_NONE, null); } @Override public void onAnimationRepeat(Animation animation) { } }); mGearIcon.startAnimation(mLogoAnimations); return mLogoAnimations; } private AnimationSet showContinueIconAnimations(int toDegree) { mContinueIcon.setVisibility(View.VISIBLE); Animation mScaleAnimation = new ScaleAnimation(0, 1, 0, 1, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); Animation mRotateAnimation = new RotateAnimation( toDegree - 360, toDegree, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f ); mRotateAnimation.setRepeatCount(0); mScaleAnimation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { mContinueIcon.setVisibility(View.VISIBLE); } @Override public void onAnimationEnd(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } }); AnimationSet mAnimations = new AnimationSet(true); mAnimations.setDuration(SHOW_CONTINUE_ICON_DURATION); mAnimations.setFillAfter(true); mAnimations.setInterpolator(new OvershootInterpolator(1.5f)); mAnimations.addAnimation(mScaleAnimation); mAnimations.addAnimation(mRotateAnimation); mContinueIcon.startAnimation(mAnimations); return mAnimations; } private AnimationSet hideContinueIconAnimations() { Animation mScaleAnimation = new ScaleAnimation(1, 0, 1, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); Animation mRotateAnimation = new RotateAnimation( mContinueIcon.getRotation(), 360 - mContinueIcon.getRotation(), Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f ); mRotateAnimation.setRepeatCount(0); mRotateAnimation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { mContinueIcon.setVisibility(View.INVISIBLE); } @Override public void onAnimationRepeat(Animation animation) { } }); AnimationSet mAnimations = new AnimationSet(true); mAnimations.setDuration(SHOW_CONTINUE_ICON_DURATION); mAnimations.setFillAfter(true); mAnimations.setInterpolator(new OvershootInterpolator(1.5f)); mAnimations.addAnimation(mScaleAnimation); mAnimations.addAnimation(mRotateAnimation); mContinueIcon.startAnimation(mAnimations); return mAnimations; } private AnimationSet showTextLineAnimations(final TextView mTextLine, int lineNumber) { mTextLine.setLayerType(View.LAYER_TYPE_HARDWARE, null); int travelDistance = (lineNumber < 3) ? (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_SP, getResources().getDimension(R.dimen.welcome_text_line_three_size), getResources().getDisplayMetrics()) : 0; float overshoot = (lineNumber == 1) ? 2f : 1f; final Animation mTranslationAnimation = new TranslateAnimation(0, 0, travelDistance, 0); mTranslationAnimation.setInterpolator(new OvershootInterpolator(overshoot)); final Animation mAlphaAnimation = new AlphaAnimation(0f, 1f); mAlphaAnimation.setInterpolator(new DecelerateInterpolator()); mAlphaAnimation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { mTextLine.setVisibility(View.VISIBLE); } @Override public void onAnimationEnd(Animation animation) { mTextLine.setLayerType(View.LAYER_TYPE_NONE, null); } @Override public void onAnimationRepeat(Animation animation) { } }); final AnimationSet mWelcomeTextAnimations = new AnimationSet(false); mWelcomeTextAnimations.setDuration(SHOW_TEXT_ANIMATION_DURATION); mWelcomeTextAnimations.setInterpolator(new AccelerateDecelerateInterpolator()); mWelcomeTextAnimations.setFillBefore(true); mWelcomeTextAnimations.setFillAfter(true); mWelcomeTextAnimations.addAnimation(mAlphaAnimation); mWelcomeTextAnimations.addAnimation(mTranslationAnimation); int delay = (lineNumber < 3) ? SHOW_TEXT_ANIMATION_BASE_DELAY * lineNumber : SHOW_TEXT_ANIMATION_BASE_DELAY * (lineNumber * 2); new Handler().postDelayed(new Runnable() { @Override public void run() { mTextLine.startAnimation(mWelcomeTextAnimations); } }, delay + SHOW_TEXT_ANIMATION_DELAY); return mWelcomeTextAnimations; } private Animation expandContinueButtonAnimations() { Animation resizeAnimation = new ResizeWidthAnimation(mContinueFABContainer, (int) getResources().getDimension(R.dimen.notification_customize_width)); resizeAnimation.setDuration(EXPAND_DURATION); mContinueFABContainer.startAnimation(resizeAnimation); final Animation mAlphaAnimation = new AlphaAnimation(0f, 1f); mAlphaAnimation.setDuration(SHOW_CUSTOMIZE_TEXT_DURATION); mAlphaAnimation.setInterpolator(new DecelerateInterpolator()); mAlphaAnimation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { mCustomizeText.setVisibility(View.VISIBLE); } @Override public void onAnimationEnd(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } }); new Handler().postDelayed(new Runnable() { @Override public void run() { mCustomizeText.startAnimation(mAlphaAnimation); } }, SHOW_CUSTOMIZE_TEXT_DELAY); return resizeAnimation; } private Animation collapseContinueButtonAnimations() { Animation resizeAnimation = new ResizeWidthAnimation(mContinueFABContainer, mFABWidth); resizeAnimation.setDuration(EXPAND_DURATION); resizeAnimation.setInterpolator(new AccelerateDecelerateInterpolator()); mContinueFABContainer.startAnimation(resizeAnimation); final Animation mAlphaAnimation = new AlphaAnimation(1f, 0f); mAlphaAnimation.setDuration(SHOW_CUSTOMIZE_TEXT_DURATION); mAlphaAnimation.setInterpolator(new DecelerateInterpolator()); mAlphaAnimation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { mCustomizeText.setVisibility(View.INVISIBLE); } @Override public void onAnimationRepeat(Animation animation) { } }); if(mCustomizeText.getVisibility() == View.VISIBLE) { mCustomizeText.startAnimation(mAlphaAnimation); } return resizeAnimation; } }