1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.tv.ui; 18 19 import android.animation.TimeInterpolator; 20 import android.app.Dialog; 21 import android.content.Context; 22 import android.os.Handler; 23 import android.util.AttributeSet; 24 import android.util.Log; 25 import android.view.View; 26 import android.view.ViewTreeObserver; 27 import android.view.animation.AnimationUtils; 28 import android.widget.FrameLayout; 29 30 import com.android.tv.MainActivity; 31 import com.android.tv.R; 32 import com.android.tv.dialog.FullscreenDialogFragment; 33 34 public class FullscreenDialogView extends FrameLayout 35 implements FullscreenDialogFragment.DialogView { 36 private static final String TAG = "FullscreenDialogView"; 37 private static final boolean DEBUG = false; 38 39 private static final int FADE_IN_DURATION_MS = 400; 40 private static final int FADE_OUT_DURATION_MS = 250; 41 private static final int TRANSITION_INTERVAL_MS = 300; 42 43 private MainActivity mActivity; 44 private Dialog mDialog; 45 private boolean mSkipEnterAlphaAnimation; 46 private boolean mSkipExitAlphaAnimation; 47 48 private final TimeInterpolator mLinearOutSlowIn; 49 private final TimeInterpolator mFastOutLinearIn; 50 FullscreenDialogView(Context context)51 public FullscreenDialogView(Context context) { 52 this(context, null, 0); 53 } 54 FullscreenDialogView(Context context, AttributeSet attrs)55 public FullscreenDialogView(Context context, AttributeSet attrs) { 56 this(context, attrs, 0); 57 } 58 FullscreenDialogView(Context context, AttributeSet attrs, int defStyle)59 public FullscreenDialogView(Context context, AttributeSet attrs, int defStyle) { 60 super(context, attrs, defStyle); 61 mLinearOutSlowIn = AnimationUtils.loadInterpolator(context, 62 android.R.interpolator.linear_out_slow_in); 63 mFastOutLinearIn = AnimationUtils.loadInterpolator(context, 64 android.R.interpolator.fast_out_linear_in); 65 getViewTreeObserver().addOnGlobalLayoutListener( 66 new ViewTreeObserver.OnGlobalLayoutListener() { 67 @Override 68 public void onGlobalLayout() { 69 getViewTreeObserver().removeOnGlobalLayoutListener(this); 70 startEnterAnimation(); 71 } 72 }); 73 } 74 getActivity()75 protected MainActivity getActivity() { 76 return mActivity; 77 } 78 79 /** 80 * Gets the host {@link Dialog}. 81 */ getDialog()82 protected Dialog getDialog() { 83 return mDialog; 84 } 85 86 /** 87 * Dismisses the host {@link Dialog}. 88 */ dismiss()89 protected void dismiss() { 90 startExitAnimation(new Runnable() { 91 @Override 92 public void run() { 93 mDialog.dismiss(); 94 } 95 }); 96 } 97 98 @Override initialize(MainActivity activity, Dialog dialog)99 public void initialize(MainActivity activity, Dialog dialog) { 100 mActivity = activity; 101 mDialog = dialog; 102 } 103 104 @Override onBackPressed()105 public void onBackPressed() { } 106 107 @Override onDestroy()108 public void onDestroy() { } 109 110 /** 111 * Transitions to another view inside the host {@link Dialog}. 112 */ transitionTo(final FullscreenDialogView v)113 public void transitionTo(final FullscreenDialogView v) { 114 mSkipExitAlphaAnimation = true; 115 v.mSkipEnterAlphaAnimation = true; 116 v.initialize(mActivity, mDialog); 117 startExitAnimation(new Runnable() { 118 @Override 119 public void run() { 120 new Handler().postDelayed(new Runnable() { 121 @Override 122 public void run() { 123 v.initialize(getActivity(), getDialog()); 124 getDialog().setContentView(v); 125 } 126 }, TRANSITION_INTERVAL_MS); 127 } 128 }); 129 } 130 131 /** 132 * Called when an enter animation starts. Sub-view specific animation can be implemented. 133 */ onStartEnterAnimation(TimeInterpolator interpolator, long duration)134 protected void onStartEnterAnimation(TimeInterpolator interpolator, long duration) { 135 } 136 137 /** 138 * Called when an exit animation starts. Sub-view specific animation can be implemented. 139 */ onStartExitAnimation(TimeInterpolator interpolator, long duration, Runnable onAnimationEnded)140 protected void onStartExitAnimation(TimeInterpolator interpolator, long duration, 141 Runnable onAnimationEnded) { 142 } 143 startEnterAnimation()144 private void startEnterAnimation() { 145 if (DEBUG) Log.d(TAG, "start an enter animation"); 146 View backgroundView = findViewById(R.id.background); 147 if (!mSkipEnterAlphaAnimation) { 148 backgroundView.setAlpha(0); 149 backgroundView.animate() 150 .alpha(1.0f) 151 .setInterpolator(mLinearOutSlowIn) 152 .setDuration(FADE_IN_DURATION_MS) 153 .withLayer() 154 .start(); 155 } 156 onStartEnterAnimation(mLinearOutSlowIn, FADE_IN_DURATION_MS); 157 } 158 startExitAnimation(final Runnable onAnimationEnded)159 private void startExitAnimation(final Runnable onAnimationEnded) { 160 if (DEBUG) Log.d(TAG, "start an exit animation"); 161 View backgroundView = findViewById(R.id.background); 162 if (!mSkipExitAlphaAnimation) { 163 backgroundView.animate() 164 .alpha(0.0f) 165 .setInterpolator(mFastOutLinearIn) 166 .setDuration(FADE_OUT_DURATION_MS) 167 .withLayer() 168 .start(); 169 } 170 onStartExitAnimation(mFastOutLinearIn, FADE_OUT_DURATION_MS, onAnimationEnded); 171 } 172 } 173