Back to project page Resonos-Android-Framework.
The source code is released under:
Apache License
If you think the Android project Resonos-Android-Framework listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package com.resonos.apps.library; //from www.j ava2 s. c o m import java.util.ArrayList; import java.util.Map; import android.app.Activity; import android.content.Intent; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.actionbarsherlock.app.SherlockFragment; import com.actionbarsherlock.view.Menu; import com.actionbarsherlock.view.MenuInflater; import com.actionbarsherlock.view.MenuItem; import com.actionbarsherlock.view.MenuItem.OnActionExpandListener; import com.actionbarsherlock.widget.ShareActionProvider; import com.actionbarsherlock.widget.ShareActionProvider.OnShareTargetSelectedListener; import com.resonos.app.library.R; import com.resonos.apps.library.AlertFragment.Result; import com.resonos.apps.library.util.LifecycleTaskQueue; import com.resonos.apps.library.util.ParameterList; /** * This is the base class for all Fragments to be used in this framework. * @author Chris Newhouse */ public abstract class BaseFragment extends SherlockFragment { /** an enum for identifying the four possible fragment show/hide animations */ public enum FragmentAnimation {ENTER_FORWARD, ENTER_BACKWARD, EXIT_FORWARD, EXIT_BACKWARD}; // constants public static final String STATE_TRANSACTION_ID = "transactionID"; // context public FragmentBaseActivity mActivity; // temporary state private boolean isAttached = false, isCreated = false, isActivityCreated = false, // isViewCreated = false, // super not usually called, so we can't do this one isStarted = false, isResumed = false; // objects private ArrayList<Action> mMenuItems = new ArrayList<Action>(); private int mTransactionID; private LifecycleTaskQueue mTaskQueue = new LifecycleTaskQueue(); // params public enum Param { /** this parameter indicates a fragment that will not be placed in the main fragment container */ NON_MAIN_FRAGMENT }; ParameterList<Param> mParams; public BaseFragment() { mParams = new ParameterList<Param>(null); } public BaseFragment(Param... params) { mParams = new ParameterList<Param>(params); } /** * Add a runnable to a queue to be run one single * occurrence the next time a distinct event occurs. * This task will NOT survive a configuration change * or past the onDetach method. * Use this, for example, to call a method in a * fragment before that fragment has been created. * @param event : the {@link FragmentEvent} to trigger the runnable. * @param task : the Runnable to run */ public void queueTask(FragmentEvent event, Runnable task) { mTaskQueue.addTask(event, task); } /** * Get the task queue * @return the {@link LifecycleTaskQueue} object */ public LifecycleTaskQueue getTaskQueue() { return mTaskQueue; } /** * Enum representing the events we mark in fragments as points which * queued tasks can run. * We've removed onCreateView and onDestroyView, because the former usually * doesn't call the super and thus we have no way of knowing in BaseFragment * if that method call has occurred unless we wanted to make it final, * and create an alternative implementation. That seems unnecessary, * given the multitude of other points at which a task could be run. */ public enum FragmentEvent { OnAttach, OnCreate, // OnCreateView, OnActivityCreated, OnStart, OnResume, OnPause, OnStop, // OnDestroyView, OnDestroy, OnDetach }; /** * @return true if between onAttach and onDetach, and there is a non null activity */ public boolean isAttached() { return isAttached && getActivity() != null; } /** * @return true if between onCreate and onDestroy */ public boolean isCreated() { return isCreated; } // /** // * @return true if between onViewCreated and onViewDestroyed // */ // public boolean isViewCreated() { // super not usually called, so we can't do this one // return isViewCreated; // } /** * @return true if after onActivityCreated and the activity register as created */ public boolean isActivityCreated() { return isActivityCreated && mActivity.isCreated(); } /** * @return true if between onStart and onStop */ public boolean isStarted() { return isStarted; } /** * @return true if NOT between onResume and onPause */ public boolean isPaused() { return !isResumed; } @Override public void onAttach(Activity activity) { super.onAttach(activity); mActivity = (FragmentBaseActivity) activity; isAttached = true; mTaskQueue.runEvent(FragmentEvent.OnAttach); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); isCreated = true; mActivity = (FragmentBaseActivity) getActivity(); setHasOptionsMenu(true); if (savedInstanceState != null) { mTransactionID = savedInstanceState.getInt(STATE_TRANSACTION_ID, -1); } mTaskQueue.runEvent(FragmentEvent.OnCreate); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle icicle) { View v = super.onCreateView(inflater, container, icicle); // isViewCreated = true; return v; } @Override public void onActivityCreated(Bundle inState) { super.onActivityCreated(inState); isActivityCreated = true; if (inState != null) { // } mTaskQueue.runEvent(FragmentEvent.OnActivityCreated); } @Override public void onStart() { super.onStart(); isStarted = true; mTaskQueue.runEvent(FragmentEvent.OnStart); } @Override public void onResume() { super.onResume(); isResumed = true; mActivity.getSupportActionBar().setDisplayHomeAsUpEnabled(this != mActivity.getMainFragment()); String title = getTitle(); if (title == null) title = mActivity.mApp.getAppName(); mActivity.getSupportActionBar().setTitle(title); mTaskQueue.runEvent(FragmentEvent.OnResume); } @Override public void onSaveInstanceState(Bundle outState) { outState.putInt(STATE_TRANSACTION_ID, mTransactionID); // M.log(this.getClass().getSimpleName(), "onSaveInstanceState transID: " + mTransactionID); } @Override public void onPause() { super.onPause(); isResumed = false; mTaskQueue.runEvent(FragmentEvent.OnPause); } @Override public void onStop() { super.onStop(); isStarted = false; mTaskQueue.runEvent(FragmentEvent.OnStop); } @Override public void onDestroyView() { super.onDestroyView(); // isViewCreated = false; } @Override public void onDestroy() { super.onDestroy(); isCreated = false; mTaskQueue.runEvent(FragmentEvent.OnDestroy); } @Override public void onDetach() { super.onDetach(); isAttached = false; mTaskQueue.runEvent(FragmentEvent.OnDetach); mTaskQueue.empty(); } /** * called when the back button is pressed. * @return true to capture the button press */ public abstract boolean onBackPressed(); @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { if (!isAttached() || this.getActivity() == null || isRemoving()) return; menu.clear(); mMenuItems.clear(); onCreateOptionsMenu(mMenuItems); Action a; for (int i = 0; i < mMenuItems.size(); i++) { a = mMenuItems.get(i); addMenuItem(menu, a); } } /** * This function is called every time the Action Bar is invalidated. * Add the actions you would like in the Action Bar to items * @param items the arraylist to add new Actions to */ protected abstract void onCreateOptionsMenu(ArrayList<Action> items); /** adds a single menu item to the action bar */ private void addMenuItem(Menu menu, final Action action) { MenuItem mi = menu.add(Menu.NONE, action.id, Menu.NONE, action.text); Drawable d = action.getDrawable(mActivity); if (d != null) { d.setBounds(0, 0, Math.round(32*App.DENSITY), Math.round(32*App.DENSITY)); mi.setIcon(d); } mi.setShowAsAction((action.over ? MenuItem.SHOW_AS_ACTION_NEVER : (action.priority ? MenuItem.SHOW_AS_ACTION_ALWAYS : MenuItem.SHOW_AS_ACTION_IF_ROOM)) | ((!action.over && action.wt) ? MenuItem.SHOW_AS_ACTION_WITH_TEXT : 0) | (action.customControl != null ? MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW : 0)); mi.setEnabled(!action.disabled); // if (action.actionProvider != null) // mi.setActionProvider(action.actionProvider); if (action.customControl != null) { mi.setActionView(action.customControl); mi.setOnActionExpandListener(new OnActionExpandListener() { @Override public boolean onMenuItemActionCollapse(MenuItem item) { onOptionsItemAction(action.tag, ActionItemEvent.COLLAPSED); return true; // Return true to collapse action view } @Override public boolean onMenuItemActionExpand(MenuItem item) { onOptionsItemAction(action.tag, ActionItemEvent.EXPANDED); return true; // Return true to expand action view } }); } } /** * Create a Share Action Provider based on the given intent * @param i : the intent to launch * @param listener : an option listener for when a share option is chosen * @return */ public ShareActionProvider createShareActionProvider(Intent i, OnShareTargetSelectedListener listener) { ShareActionProvider actionProvider = new ShareActionProvider(mActivity); actionProvider.setShareHistoryFileName(null); // removes history button // ShareActionProvider.DEFAULT_SHARE_HISTORY_FILE_NAME); actionProvider.setShareIntent(i); actionProvider.setOnShareTargetSelectedListener(listener); return actionProvider; } /** * @return true if this fragment is the current active main fragment */ public boolean isCurrentFragment() { return (mActivity.getCurFragment() == this); } @Override public boolean onOptionsItemSelected(MenuItem item) { if (getActivity() == null) return false; int id = item.getItemId(); if (id == android.R.id.home) { if (this != mActivity.getMainFragment() && !this.isPaused()) mActivity.onBackPressed(); return true; } for (int i = 0; i < mMenuItems.size(); i++) { if (id == mMenuItems.get(i).id) { onOptionsItemSelected(mMenuItems.get(i).tag); return true; } } return super.onOptionsItemSelected(item); } public enum ActionItemEvent { EXPANDED, COLLAPSED; } /** * This method is called when an action from the action bar * or its overflow menu is selected. * @param action : This is the enum tag associated with the action. * It is easiest to cast action to your enum type and then make a switch case block using it. */ protected abstract void onOptionsItemSelected(Enum<?> action); /** * This method is called when something other than a simple select * is done on an action from the action bar * @param action : This is the enum tag associated with the action. * @param whatHappened : describes the event * It is easiest to cast action to your enum type and then make a switch case block using it. */ protected void onOptionsItemAction(Enum<?> action, ActionItemEvent whatHappened) { // } /** * This method returns the title of the Fragment, which will be seen in the Action Bar. * Its default implementation returns null, which serves the same as using the app's title. * Override it to provide a different title. * @return The fragment title */ public String getTitle() { return null; } /** Override this method to add animations to fragment transcations. * @param fa : Which animation we need to define. * @param f : The other fragment involved in this animation. * @return A resource identifying the animation to play. */ protected abstract int getAnimation(FragmentAnimation fa, BaseFragment f); /** * Gets the default animation used for standard fragment sliding left and right * @param fa : Which animation we need to define. * @return A resource identifying the animation to play. */ protected int getDefaultAnimationSlideFromRight(FragmentAnimation fa) { switch (fa) { case ENTER_FORWARD: return R.anim.fragment_slide_left_enter; case EXIT_FORWARD: return R.anim.fragment_slide_left_exit; case ENTER_BACKWARD: return R.anim.fragment_slide_right_enter; case EXIT_BACKWARD: return R.anim.fragment_slide_right_exit; default: return 0; } } /** * Gets the default animation used for standard fragment sliding up and down * @param fa : Which animation we need to define. * @return A resource identifying the animation to play. */ protected int getDefaultAnimationSlideFromBottom(FragmentAnimation fa) { switch (fa) { case ENTER_FORWARD: return R.anim.fragment_slide_up_enter; case EXIT_FORWARD: return R.anim.fragment_slide_up_exit; case ENTER_BACKWARD: return R.anim.fragment_slide_down_enter; case EXIT_BACKWARD: return R.anim.fragment_slide_down_exit; default: return 0; } } /** * Gets the default animation used for standard fragment sliding left and right * @param fa : Which animation we need to define. * @return A resource identifying the animation to play. */ protected int getDefaultAnimationSlideFromLeft(FragmentAnimation fa) { switch (fa) { case ENTER_FORWARD: return R.anim.fragment_slide_right_enter; case EXIT_FORWARD: return R.anim.fragment_slide_right_exit; case ENTER_BACKWARD: return R.anim.fragment_slide_left_enter; case EXIT_BACKWARD: return R.anim.fragment_slide_left_exit; default: return 0; } } /** * Gets the default animation used for standard fragment sliding up and down * @param fa : Which animation we need to define. * @return A resource identifying the animation to play. */ protected int getDefaultAnimationSlideFromTop(FragmentAnimation fa) { switch (fa) { case ENTER_FORWARD: return R.anim.fragment_slide_down_enter; case EXIT_FORWARD: return R.anim.fragment_slide_down_exit; case ENTER_BACKWARD: return R.anim.fragment_slide_up_enter; case EXIT_BACKWARD: return R.anim.fragment_slide_up_exit; default: return 0; } } /** * Sets the transaction ID that showed this fragment. * @param id : the ID returned by FragmentTransaction.commit(); */ protected void setTransactionID(int id) { mTransactionID = id; // M.log(this.getClass().getSimpleName(), "setTransactionID " + id); } /** * Get the transaction ID that showed this fragment. * @return The ID. */ protected int getTransactionID() { return mTransactionID; } /** * Override this to retain custom objects across instances rather than the whole fragment, * as the API allows * @param customRetain : the map to put objects in */ public void onRetainCustomObjects(Map<String, Object> customRetain) { // } /** * Called when a dialog has returned * @param id : the id the dialog was created with * @param button : the button, DialogInterface.BUTTON_x values */ protected void onDialogResult(int id, Result button) { // } /** * Called when a dialog needs a custom view during creation * @param id : the id the dialog was created with */ protected View onDialogCreateCustomView(int id) { return null; } }