package org.ohmage.ui; import android.content.ContentResolver; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.view.Menu; import android.view.View; import android.view.animation.AnimationUtils; import android.widget.FrameLayout; import android.widget.LinearLayout; import org.ohmage.AccountHelper; import org.ohmage.OhmageApplication; import org.ohmage.R; import org.ohmage.UserPreferencesHelper; import org.ohmage.controls.ActionBarControl; import org.ohmage.logprobe.Analytics; import org.ohmage.logprobe.Log; import org.ohmage.logprobe.LogProbe.Status; /** * A base activity for all screens. It handles showing the action bar and setting the title correctly as * the manifest specifies. This activity also has the {@link #setLoadingVisibility(boolean)} function * which makes it easy to show a loading spinner while you wait for data from a loader or somewhere else. * * @author Cameron Ketcham * */ public abstract class BaseActivity extends FragmentActivity { private static final String TAG = "BaseActivity"; private ActionBarControl mActionBar; private FrameLayout mContainer; private View mActionBarShadow; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); UserPreferencesHelper preferencesHelper = new UserPreferencesHelper(this); if (preferencesHelper.isUserDisabled()) { ((OhmageApplication) getApplication()).resetAll(); } if (!AccountHelper.accountExists()) { Log.v(TAG, "no credentials saved, so launch Login"); startActivity(AccountHelper.getLoginIntent(this)); finish(); return; } } @Override protected void onResume() { super.onResume(); Analytics.activity(this, Status.ON); } @Override protected void onPause() { super.onPause(); Analytics.activity(this, Status.OFF); } @Override public boolean onPrepareOptionsMenu(Menu menu) { Analytics.widget(this, "Menu Button"); return super.onPrepareOptionsMenu(menu); } @Override public void onContentChanged() { super.onContentChanged(); getActionBarControl().setTitle(getTitle()); } @Override public void setContentView(final int layoutResID) { View rootView = initLayout(); getLayoutInflater().inflate(layoutResID, getContainer(), true); super.setContentView(rootView); } @Override public void setContentView(View view) { View rootView = initLayout(); mContainer.addView(view); super.setContentView(rootView); } /** * Sets the content view but doesn't add anything to the container */ public void setContentView() { super.setContentView(initLayout()); } /** * We should automatically add the action bar to the view. This function inflates the base activity layout * which contains the action bar. It also sets the {@link #mActionBar} and {@link #mContainer} fields * @return the root view */ private View initLayout() { LinearLayout baseLayout = (LinearLayout) getLayoutInflater().inflate(R.layout.base_activity, null); mActionBar = (ActionBarControl) baseLayout.findViewById(R.id.action_bar); mActionBarShadow = baseLayout.findViewById(R.id.action_bar_shadow); mContainer = (FrameLayout) baseLayout.findViewById(R.id.root_container); return baseLayout; } @Override public View findViewById(int id) { // There is no reason for people to be searching through the whole hierarchy // since they have access to getActionBarControl() return mContainer.findViewById(id); } public ActionBarControl getActionBarControl() { return mActionBar; } protected FrameLayout getContainer() { return mContainer; } /** * Sets whether the progress spinner overlay is covering the content area (e.g. if the view is still loading). * You're encouraged to call setLoadingVisiblity(true) in your onCreate() and then setLoadingVisibility(false) when * your content is ready. * * @param isLoading true if the progress spinner overlay should cover the content, false to show the content underneath. */ protected void setLoadingVisibility(boolean isLoading) { View pv = super.findViewById(R.id.info_loading_bar); boolean wasVisible = pv.getVisibility() == View.VISIBLE; // do the appropriate animation if the view is disappearing // do nothing if it's not transitioning or if it's being displayed if (wasVisible && !isLoading) { pv.startAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_out)); } else pv.clearAnimation(); // and finally set the actual visibility of the thing pv.setVisibility(isLoading?View.VISIBLE:View.GONE); } protected void setActionBarShadowVisibility(boolean visible) { mActionBarShadow.setVisibility(visible?View.VISIBLE:View.GONE); } /** * Converts an intent into a {@link Bundle} suitable for use as fragment arguments. */ public static Bundle intentToFragmentArguments(Intent intent) { Bundle arguments = new Bundle(); if (intent == null) { return arguments; } final Uri data = intent.getData(); if (data != null) { arguments.putParcelable("_uri", data); } final Bundle extras = intent.getExtras(); if (extras != null) { arguments.putAll(intent.getExtras()); } return arguments; } @Override public ContentResolver getContentResolver() { // The Ohmage Application has code which makes it possible to switch content resolvers during testing. // We need to make sure to get the right one here. return OhmageApplication.getContext().getContentResolver(); } }