package com.simplecity.amp_library.ui.fragments;
import android.content.res.Resources;
import android.support.v4.app.Fragment;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import com.simplecity.amp_library.ShuttleApplication;
import com.simplecity.amp_library.utils.AnalyticsManager;
import com.squareup.leakcanary.RefWatcher;
import java.lang.reflect.Field;
public abstract class BaseFragment extends Fragment {
private static final String TAG = "BaseFragment";
// Arbitrary value; set it to some reasonable default
private static final int DEFAULT_CHILD_ANIMATION_DURATION = 250;
@Override
public void onResume() {
super.onResume();
AnalyticsManager.logScreenName(getActivity(), screenName());
}
@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
/*
* When a fragment transaction is performed on a parent fragment containing nested children,
* the children disappear as soon as the transaction begins.. So if you're relying on some
* fancy animation for the parent, we need to ensure the child waits before performing its
* own animation.
* see https://code.google.com/p/android/issues/detail?id=55228
*/
final Fragment parent = getParentFragment();
// Apply the workaround only if this is a child fragment, and the parent
// is being removed.
if (!enter && parent != null && parent.isRemoving()) {
// This is a workaround for the bug where child fragments disappear when
// the parent is removed (as all children are first removed from the parent)
// See https://code.google.com/p/android/issues/detail?id=55228
Animation doNothingAnim = new AlphaAnimation(1, 1);
doNothingAnim.setDuration(getNextAnimationDuration(parent, DEFAULT_CHILD_ANIMATION_DURATION));
return doNothingAnim;
} else {
return super.onCreateAnimation(transit, enter, nextAnim);
}
}
/**
* Attempt to get the resource ID of the next animation that
* will be applied to the given fragment.
*
* @param fragment the parent fragment
* @param defValue default animation value
* @return the duration of the parent fragment's animation
*/
private static long getNextAnimationDuration(Fragment fragment, long defValue) {
try {
// Attempt to get the resource ID of the next animation that
// will be applied to the given fragment.
Field nextAnimField = Fragment.class.getDeclaredField("mNextAnim");
nextAnimField.setAccessible(true);
int nextAnimResource = nextAnimField.getInt(fragment);
Animation nextAnim = AnimationUtils.loadAnimation(fragment.getActivity(), nextAnimResource);
// ...and if it can be loaded, return that animation's duration
return (nextAnim == null) ? defValue : nextAnim.getDuration();
} catch (NoSuchFieldException | IllegalAccessException | Resources.NotFoundException ignored) {
return defValue;
}
}
@Override
public void onDestroy() {
super.onDestroy();
RefWatcher refWatcher = ShuttleApplication.getInstance().getRefWatcher();
refWatcher.watch(this);
}
protected abstract String screenName();
}