blob: 7d47548d71ea64b99186f669cb52e85c7ab6551a [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.common.ui.setup;
import android.app.Fragment;
import android.os.Bundle;
import android.support.annotation.IntDef;
import android.transition.Transition;
import android.transition.Transition.TransitionListener;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import com.android.tv.common.ui.setup.animation.FadeAndShortSlide;
import com.android.tv.common.ui.setup.animation.SetupAnimationHelper;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/** A fragment which slides when it is entering/exiting. */
public abstract class SetupFragment extends Fragment {
@Retention(RetentionPolicy.SOURCE)
@IntDef(
flag = true,
value = {
FRAGMENT_ENTER_TRANSITION,
FRAGMENT_EXIT_TRANSITION,
FRAGMENT_REENTER_TRANSITION,
FRAGMENT_RETURN_TRANSITION
}
)
public @interface FragmentTransitionType {}
public static final int FRAGMENT_ENTER_TRANSITION = 0x01;
public static final int FRAGMENT_EXIT_TRANSITION = FRAGMENT_ENTER_TRANSITION << 1;
public static final int FRAGMENT_REENTER_TRANSITION = FRAGMENT_ENTER_TRANSITION << 2;
public static final int FRAGMENT_RETURN_TRANSITION = FRAGMENT_ENTER_TRANSITION << 3;
private boolean mEnterTransitionRunning;
private final TransitionListener mTransitionListener =
new TransitionListener() {
@Override
public void onTransitionStart(Transition transition) {
mEnterTransitionRunning = true;
}
@Override
public void onTransitionEnd(Transition transition) {
mEnterTransitionRunning = false;
onEnterTransitionEnd();
}
@Override
public void onTransitionCancel(Transition transition) {}
@Override
public void onTransitionPause(Transition transition) {}
@Override
public void onTransitionResume(Transition transition) {}
};
/** Returns {@code true} if the enter/reenter transition is running. */
protected boolean isEnterTransitionRunning() {
return mEnterTransitionRunning;
}
/** Called when the enter/reenter transition ends. */
protected void onEnterTransitionEnd() {}
public SetupFragment() {
setAllowEnterTransitionOverlap(false);
setAllowReturnTransitionOverlap(false);
enableFragmentTransition(
FRAGMENT_ENTER_TRANSITION
| FRAGMENT_EXIT_TRANSITION
| FRAGMENT_REENTER_TRANSITION
| FRAGMENT_RETURN_TRANSITION);
}
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(getLayoutResourceId(), container, false);
// After the transition animation, we need to request the focus. If not, this fragment
// doesn't have the focus.
view.requestFocus();
return view;
}
/** Returns the layout resource ID for this fragment. */
protected abstract int getLayoutResourceId();
protected void setOnClickAction(View view, final String category, final int actionId) {
view.setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View view) {
onActionClick(category, actionId);
}
});
}
protected boolean onActionClick(String category, int actionId) {
return SetupActionHelper.onActionClick(this, category, actionId);
}
protected boolean onActionClick(String category, int actionId, Bundle params) {
return SetupActionHelper.onActionClick(this, category, actionId, params);
}
@Override
public void setEnterTransition(Transition transition) {
super.setEnterTransition(transition);
if (transition != null) {
transition.addListener(mTransitionListener);
}
}
@Override
public void setReenterTransition(Transition transition) {
super.setReenterTransition(transition);
if (transition != null) {
transition.addListener(mTransitionListener);
}
}
/**
* Enables fragment transition according to the given {@code mask}.
*
* @param mask This value is the combination of {@link #FRAGMENT_ENTER_TRANSITION}, {@link
* #FRAGMENT_EXIT_TRANSITION}, {@link #FRAGMENT_REENTER_TRANSITION}, and {@link
* #FRAGMENT_RETURN_TRANSITION}.
*/
public void enableFragmentTransition(@FragmentTransitionType int mask) {
setEnterTransition(
(mask & FRAGMENT_ENTER_TRANSITION) == 0 ? null : createTransition(Gravity.END));
setExitTransition(
(mask & FRAGMENT_EXIT_TRANSITION) == 0 ? null : createTransition(Gravity.START));
setReenterTransition(
(mask & FRAGMENT_REENTER_TRANSITION) == 0 ? null : createTransition(Gravity.START));
setReturnTransition(
(mask & FRAGMENT_RETURN_TRANSITION) == 0 ? null : createTransition(Gravity.END));
}
/** Sets the transition with the given {@code slidEdge}. */
public void setFragmentTransition(@FragmentTransitionType int transitionType, int slideEdge) {
switch (transitionType) {
case FRAGMENT_ENTER_TRANSITION:
setEnterTransition(createTransition(slideEdge));
break;
case FRAGMENT_EXIT_TRANSITION:
setExitTransition(createTransition(slideEdge));
break;
case FRAGMENT_REENTER_TRANSITION:
setReenterTransition(createTransition(slideEdge));
break;
case FRAGMENT_RETURN_TRANSITION:
setReturnTransition(createTransition(slideEdge));
break;
}
}
private Transition createTransition(int slideEdge) {
return new SetupAnimationHelper.TransitionBuilder()
.setSlideEdge(slideEdge)
.setParentIdsForDelay(getParentIdsForDelay())
.setExcludeIds(getExcludedTargetIds())
.build();
}
/** Changes the move distance of the transitions to short distance. */
public void setShortDistance(@FragmentTransitionType int mask) {
if ((mask & FRAGMENT_ENTER_TRANSITION) != 0) {
Transition transition = getEnterTransition();
if (transition instanceof FadeAndShortSlide) {
SetupAnimationHelper.setShortDistance((FadeAndShortSlide) transition);
}
}
if ((mask & FRAGMENT_EXIT_TRANSITION) != 0) {
Transition transition = getExitTransition();
if (transition instanceof FadeAndShortSlide) {
SetupAnimationHelper.setShortDistance((FadeAndShortSlide) transition);
}
}
if ((mask & FRAGMENT_REENTER_TRANSITION) != 0) {
Transition transition = getReenterTransition();
if (transition instanceof FadeAndShortSlide) {
SetupAnimationHelper.setShortDistance((FadeAndShortSlide) transition);
}
}
if ((mask & FRAGMENT_RETURN_TRANSITION) != 0) {
Transition transition = getReturnTransition();
if (transition instanceof FadeAndShortSlide) {
SetupAnimationHelper.setShortDistance((FadeAndShortSlide) transition);
}
}
}
/**
* Returns the ID's of the view's whose descendants will perform delayed move.
*
* @see com.android.tv.common.ui.setup.animation.SetupAnimationHelper.TransitionBuilder
* #setParentIdsForDelay
*/
protected int[] getParentIdsForDelay() {
return null;
}
/**
* Sets the ID's of the views which will not be included in the transition.
*
* @see com.android.tv.common.ui.setup.animation.SetupAnimationHelper.TransitionBuilder
* #setExcludeIds
*/
protected int[] getExcludedTargetIds() {
return null;
}
/**
* Returns the ID's of the shared elements.
*
* <p>Note that the shared elements should have their own transition names.
*/
public int[] getSharedElementIds() {
return null;
}
}