/* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.tv.ui; import android.animation.TimeInterpolator; import android.app.Dialog; import android.content.Context; import android.os.Handler; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.view.ViewTreeObserver; import android.view.animation.AnimationUtils; import android.widget.FrameLayout; import com.android.tv.MainActivity; import com.android.tv.R; import com.android.tv.dialog.FullscreenDialogFragment; public class FullscreenDialogView extends FrameLayout implements FullscreenDialogFragment.DialogView { private static final String TAG = "FullscreenDialogView"; private static final boolean DEBUG = false; private static final int FADE_IN_DURATION_MS = 400; private static final int FADE_OUT_DURATION_MS = 250; private static final int TRANSITION_INTERVAL_MS = 300; private MainActivity mActivity; private Dialog mDialog; private boolean mSkipEnterAlphaAnimation; private boolean mSkipExitAlphaAnimation; private final TimeInterpolator mLinearOutSlowIn; private final TimeInterpolator mFastOutLinearIn; public FullscreenDialogView(Context context) { this(context, null, 0); } public FullscreenDialogView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public FullscreenDialogView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); mLinearOutSlowIn = AnimationUtils.loadInterpolator(context, android.R.interpolator.linear_out_slow_in); mFastOutLinearIn = AnimationUtils.loadInterpolator(context, android.R.interpolator.fast_out_linear_in); getViewTreeObserver() .addOnGlobalLayoutListener( new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { getViewTreeObserver().removeOnGlobalLayoutListener(this); startEnterAnimation(); } }); } protected MainActivity getActivity() { return mActivity; } /** Gets the host {@link Dialog}. */ protected Dialog getDialog() { return mDialog; } /** Dismisses the host {@link Dialog}. */ protected void dismiss() { startExitAnimation(() -> mDialog.dismiss()); } @Override public void initialize(MainActivity activity, Dialog dialog) { mActivity = activity; mDialog = dialog; } @Override public void onBackPressed() {} @Override public void onDestroy() {} /** Transitions to another view inside the host {@link Dialog}. */ public void transitionTo(final FullscreenDialogView v) { mSkipExitAlphaAnimation = true; v.mSkipEnterAlphaAnimation = true; v.initialize(mActivity, mDialog); startExitAnimation( () -> new Handler() .postDelayed( new Runnable() { @Override public void run() { v.initialize(getActivity(), getDialog()); getDialog().setContentView(v); } }, TRANSITION_INTERVAL_MS)); } /** Called when an enter animation starts. Sub-view specific animation can be implemented. */ protected void onStartEnterAnimation(TimeInterpolator interpolator, long duration) {} /** Called when an exit animation starts. Sub-view specific animation can be implemented. */ protected void onStartExitAnimation( TimeInterpolator interpolator, long duration, Runnable onAnimationEnded) {} private void startEnterAnimation() { if (DEBUG) Log.d(TAG, "start an enter animation"); View backgroundView = findViewById(R.id.background); if (!mSkipEnterAlphaAnimation) { backgroundView.setAlpha(0); backgroundView .animate() .alpha(1.0f) .setInterpolator(mLinearOutSlowIn) .setDuration(FADE_IN_DURATION_MS) .withLayer() .start(); } onStartEnterAnimation(mLinearOutSlowIn, FADE_IN_DURATION_MS); } private void startExitAnimation(final Runnable onAnimationEnded) { if (DEBUG) Log.d(TAG, "start an exit animation"); View backgroundView = findViewById(R.id.background); if (!mSkipExitAlphaAnimation) { backgroundView .animate() .alpha(0.0f) .setInterpolator(mFastOutLinearIn) .setDuration(FADE_OUT_DURATION_MS) .withLayer() .start(); } onStartExitAnimation(mFastOutLinearIn, FADE_OUT_DURATION_MS, onAnimationEnded); } }