package org.xbmc.android.view; import android.app.Activity; import android.support.v4.app.Fragment; import android.util.Log; import org.xbmc.android.view.RelativePagerFragment.OnStatusChangeListener; import java.util.HashMap; /** * Caches fragments for the {@link RelativePagerFragment}. */ public class FragmentStateManager { private final static String TAG = FragmentStateManager.class.getSimpleName(); private final HashMap<String, Fragment> fragments = new HashMap<String, Fragment>(); private RelativePagerAdapter onStatusChangeListener; public FragmentStateManager() { } /** * Returns fragment from cache if found, otherwise instantiates it. * * Typically called on {@link RelativePagerFragment#hasNext()} and * {@link RelativePagerFragment#hasPrev()} * * @param klass Type of the fragment * @return Fragment instance */ public RelativePagerFragment getFragment(Class<? extends RelativePagerFragment> klass) { Log.d(TAG, "Getting fragment " + klass.getSimpleName() + " from cache."); if (!fragments.containsKey(klass.getName())) { Log.d(TAG, "Nothing found, instantiating " + klass.getSimpleName() + " manually."); final RelativePagerFragment fragment = instantiateFragment(klass); fragments.put(klass.getName(), fragment); return fragment; } return (RelativePagerFragment)fragments.get(klass.getName()); } /** * Removes a fragment from the cache. This is sometimes desireable if a fragment contains a * complex state that otherwise would have to be manually reset. In this case, removing the * fragment will force a re-instantiation and thus a clean state. */ public void removeFragment(Class<? extends RelativePagerFragment> klass) { if (fragments.containsKey(klass.getName())) { fragments.remove(klass.getName()); } } /** * Use this to instantiate the frame state manager. */ public static FragmentStateManager get(Activity activity) { if (activity == null) { throw new IllegalArgumentException("Activity for fragment state manager must not be null."); } if (!(activity instanceof FragmentStateManageable)) { throw new IllegalArgumentException("Activity must implement FragmentStateManageable."); } return ((FragmentStateManageable)activity).getFragmentStateManager(); } /** * Instantiates a fragment by class name. */ private RelativePagerFragment instantiateFragment(Class<? extends RelativePagerFragment> klass) { try { return klass.newInstance(); } catch (InstantiationException e) { throw new RuntimeException("Error instantiating fragment " + klass.getSimpleName(), e); } catch (IllegalAccessException e) { throw new RuntimeException("Error instantiating fragment " + klass.getSimpleName(), e); } } /** * Sets the {@link OnStatusChangeListener}, used by the pager. */ public void setOnStatusChangeListener(RelativePagerAdapter onStatusChangeListener) { this.onStatusChangeListener = onStatusChangeListener; } /** * Returns the {@link OnStatusChangeListener}. */ public RelativePagerAdapter getOnStatusChangeListener() { return onStatusChangeListener; } /** * An activity that contains an instance of this class. */ public interface FragmentStateManageable { /** * Returns the fragment state manager. */ public FragmentStateManager getFragmentStateManager(); } }