package com.dpt.tbase.app.base; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentTransaction; import com.dpt.tbase.app.base.interfaces.IFraCommCB; import com.dpt.tbase.app.base.utils.LogHelper; import com.dpt.tbase.app.base.utils.TFraLruCache; import com.dpt.tbase.app.base.utils.TFragmentFactory; import com.dpt.tbase.app.fragment.AbCompatibleFragment; import com.dpt.tbase.app.fragment.AbCompatibleFragment.CompatibleListener; import com.dpt.tbase.app.fragment.TBaseFragment; /** * BaseFragmentActivity * text1 * @author dupengtao@cyou-inc.com 2014-3-20 */ public abstract class TBaseFraActivity extends FragmentActivity implements AbCompatibleFragment.CompatibleListener, IFraCommCB { private static final String TAG = "TBaseFraActivity"; protected TBaseFragment mCur, mPre; protected AbCompatibleFragment mCompatibleFra; protected boolean mSingleFragment; private int mMaxCacheSize = 4; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TFragmentFactory.initFractory(getMaxSize(), getSupportFragmentManager()); addFirstContent(); } /** * maxSize for caches * * @return maxSize */ protected int getMaxSize() { return mMaxCacheSize; } /** * when Activity onResume() will be called ,if current frgament is compatibleFragment , * it not execute callback . * * @see com.dpt.tbase.app.base.interfaces.ICustomFragmentListener#onActivityResumedLoad(int) */ @Override protected void onResume() { super.onResume(); if (isCurCompatible()) { mPre.onActivityResumedLoad(1); } else { mCur.onActivityResumedLoad(1); } } private void addFirstContent() { TBaseFragment to = getInitContent(); if (to != null) { switchContent(null, to); } else { throw new NullPointerException("The init fragment is null"); } } /** * return the init {@link TBaseFragment} * * @see #addFirstContent() */ public abstract TBaseFragment getInitContent(); /** * change cur frgment to pre fragment */ protected void switchContentBack() { if (mPre == null) { // TODO 完蛋了? 相邻的2个fra不会为空吧 } if (mPre != mCur && mPre != mCompatibleFra) { switchContent(mCur, mPre); } } // TODO 如果targetFra 为 null 要做处理 看看是否可用工厂设计模式 // switchContent(TBaseFragment fromFra, TBaseFragment targetFra) 中的targetFra 要在调用这个方法前 确定不能空 /** * change fromFragment to toFragment and add {@link TFragmentFactory},{@link TFraLruCache} * * @param fromFra usually is cur fragment * @param targetFra * @return * cur fragement equals to targetFragmet return false * commitAllowingStateLoss throw exception return false * other cases return true */ protected boolean switchContent(TBaseFragment fromFra, TBaseFragment targetFra) { if (targetFra == null) { throw new NullPointerException("The init fragment is null"); } if (mCur != targetFra) { FragmentTransaction transaction = getSupportFragmentManager() .beginTransaction(); int[] animations = getCustomAnimationsResId(); if (animations != null && animations.length >= 2) { transaction.setCustomAnimations(animations[0], animations[1]); } if (!targetFra.isAdded()) { // if not added if (fromFra != null) { transaction.hide(fromFra);// hide cur fragment mPre = fromFra; } mCur = targetFra; try { transaction.add(getReplaceLayoutResId(), targetFra).commitAllowingStateLoss(); // add and show toFra if (targetFra.isAddCache()) { TFragmentFactory.getInstance().putAndAddCache(targetFra.getKey(), targetFra.getClass()); } TFragmentFactory.getInstance().put(targetFra.getKey(), targetFra.getClass()); // mTFraCache.put(targetFra.getKey(), targetFra); // TFragmentFactory.fraKeys.put(targetFra.getKey(), targetFra.getClass()); } catch (Exception e) { LogHelper.e(TAG, "switchContent error", e); return false; } } else { if (fromFra != null) { transaction.hide(fromFra);// hide cur fragment mPre = fromFra; } mCur = targetFra; try { transaction.show(targetFra).commitAllowingStateLoss(); // show toFra TFragmentFactory.getInstance().refreshLruCache(targetFra.getKey(), targetFra); } catch (Exception e) { LogHelper.e(TAG, "switchContent error", e); return false; } } return true; } else { return false; } } /** * show no work fragment * * @see IFraCommCB#STATE_SUCCESS * @see IFraCommCB#STATE_NO_NETWORK * @see IFraCommCB#STATE_LIST_TEMPTY * @see IFraCommCB#STATE_LOAD_FAILURE * @see IFraCommCB#STATE_LOADINGT */ private void showCompatibleFra(int state) { if (mCompatibleFra == null) { mCompatibleFra = getCompatibleFragment(); } if (mPre != mCur && mCur != mCompatibleFra) { // TODO 下面代码貌似不需要 // mPre = mCur; switchContent(mCur, mCompatibleFra); mCompatibleFra.changeStyleByState(state); } else if (mSingleFragment && mCur != mCompatibleFra) {// TODO // 这个判断貌似没有用看看是否能删除 switchContent(mCur, mCompatibleFra); mCompatibleFra.changeStyleByState(state); } else if (mCur == mCompatibleFra) { if (IFraCommCB.STATE_SUCCESS == state) { switchContentBack(); } mCompatibleFra.changeStyleByState(state); mCompatibleFra.refreshComplete(); } } /** * @see CompatibleListener#onTryAgain() */ @Override public void onTryAgain() { mPre.onExceptionReLoad(); } private boolean isCurCompatible() { if (mCompatibleFra != null && mCur != null) { return mCompatibleFra == mCur; } else { return false; } } /** * @see FragmentTransaction#add(int, android.support.v4.app.Fragment) * @return replaceLayoutResId */ public abstract int getReplaceLayoutResId(); @Override public void onErrorStateListener(int state) { showCompatibleFra(state); } @Override public void onStartListener(int state) { showCompatibleFra(state); } /** * @see FragmentTransaction#setCustomAnimations(int, int) * @return Animations in xml eg.R.anim.xxx */ protected int[] getCustomAnimationsResId() { return null; } /** * get CompatibleFragment instance * * @return */ public abstract AbCompatibleFragment getCompatibleFragment(); }