package com.alexvasilkov.android.commons.utils;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Fragment;
import android.content.Intent;
import android.os.Build;
import com.alexvasilkov.android.commons.R;
/**
* Helper class to navigate between activities with animation.
* <p/>
* Sample usage: <br/>
* {@code NavHelper.from(activity).forResult(requestCode).animate(NavHelper.FADE).start(MyActivity.class)}
*/
public class NavHelper {
public static final NavTransition DEFAULT = null;
public static final NavTransition NONE = new NavTransition(0, 0, 0, 0);
public static final NavTransition FADE = new NavTransition(
R.anim.commons_fade_in, R.anim.commons_hold, R.anim.commons_hold, R.anim.commons_fade_out);
public static final NavTransition SLIDE_BOTTOM = new NavTransition(
R.anim.commons_slide_bottom_to_up, R.anim.commons_hold, R.anim.commons_hold, R.anim.commons_slide_up_to_bottom);
public static final NavTransition SLIDE_LEFT = new NavTransition(
R.anim.commons_slide_from_right, R.anim.commons_slide_to_left, R.anim.commons_slide_from_left, R.anim.commons_slide_to_right);
public static final NavTransition ZOOM = new NavTransition(
R.anim.commons_zoom_enter, R.anim.commons_zoom_exit, R.anim.commons_zoom_enter, R.anim.commons_zoom_exit);
private static final int NO_RESULT_CODE = Integer.MIN_VALUE;
private final Activity mActivity;
private final Fragment mFragment;
private final android.support.v4.app.Fragment mFragmentSupport;
private int mRequestCode = NO_RESULT_CODE;
private NavTransition mTransition;
private NavHelper(Activity activity, Fragment fragment, android.support.v4.app.Fragment fragmentSupport) {
mActivity = activity;
mFragment = fragment;
mFragmentSupport = fragmentSupport;
}
/**
* Initiates navigation starting from given activity
*/
public static NavHelper from(Activity activity) {
return new NavHelper(activity, null, null);
}
/**
* Initiates navigation starting from given fragment
*/
public static NavHelper from(Fragment fragment) {
return new NavHelper(null, fragment, null);
}
/**
* Initiates navigation starting from given fragment
*/
public static NavHelper from(android.support.v4.app.Fragment fragment) {
return new NavHelper(null, null, fragment);
}
/**
* Sets activity request code. If request code is provided method
* {@link android.app.Activity#startActivityForResult(android.content.Intent, int)} will be used
* to start next activity
*/
public NavHelper forResult(int requestCode) {
mRequestCode = requestCode;
return this;
}
/**
* Sets animation to be played when activity is entered / finished
*/
public NavHelper animate(NavTransition transition) {
mTransition = transition;
return this;
}
/**
* Actually starts activity by activity class
*/
public void start(Class<? extends Activity> activityClass) {
start(new Intent(getActivity(), activityClass));
}
/**
* Actually starts activity by intent
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void start(Intent intent) {
check();
if (mActivity != null) {
if (mRequestCode == NO_RESULT_CODE) {
mActivity.startActivity(intent);
} else {
mActivity.startActivityForResult(intent, mRequestCode);
}
} else if (mFragment != null) {
if (mRequestCode == NO_RESULT_CODE) {
mFragment.startActivity(intent);
} else {
mFragment.startActivityForResult(intent, mRequestCode);
}
} else if (mFragmentSupport != null) {
if (mRequestCode == NO_RESULT_CODE) {
mFragmentSupport.startActivity(intent);
} else {
mFragmentSupport.startActivityForResult(intent, mRequestCode);
}
}
setTransition(false);
}
/**
* Finishes current activity
*/
public void finish() {
check();
getActivity().finish();
setTransition(true);
}
/**
* Finishes current activity with provided result code
*/
public void finish(int resultCode) {
finish(resultCode, null);
}
/**
* Finishes current activity with provided result code and data
*/
public void finish(int resultCode, Intent data) {
check();
Activity activity = getActivity();
activity.setResult(resultCode, data);
activity.finish();
setTransition(true);
}
/**
* Navigates up to specified activity in the back stack skipping intermediate activities
*/
public void navigateUp(Class<? extends Activity> activityClass) {
navigateUp(new Intent(getActivity(), activityClass));
}
/**
* Navigates up to specified activity in the back stack skipping intermediate activities
*/
public void navigateUp(Intent upIntent) {
upIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
start(upIntent);
finish();
}
/* Helper methods */
private void check() {
if (getActivity() == null) throw new NullPointerException("No activity or fragment instance");
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private Activity getActivity() {
if (mActivity != null) {
return mActivity;
} else if (mFragment != null) {
return mFragment.getActivity();
} else if (mFragmentSupport != null) {
return mFragmentSupport.getActivity();
}
return null;
}
private void setTransition(boolean isFinishing) {
if (mTransition != null) {
if (isFinishing) {
getActivity().overridePendingTransition(mTransition.finishEnterAnim, mTransition.finishExitAnim);
} else {
getActivity().overridePendingTransition(mTransition.startEnterAnim, mTransition.startExitAnim);
}
}
}
/**
* Animations resources holder
*/
public static class NavTransition {
private final int startEnterAnim, startExitAnim;
private final int finishEnterAnim, finishExitAnim;
public NavTransition(int startEnterAnim, int startExitAnim, int finishEnterAnim, int finishExitAnim) {
this.startEnterAnim = startEnterAnim;
this.startExitAnim = startExitAnim;
this.finishEnterAnim = finishEnterAnim;
this.finishExitAnim = finishExitAnim;
}
}
}