blob: d3fec824dcbccadb9e818746de5cc3a84bae059c [file] [log] [blame]
/*
* 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);
}
}