/* * Copyright (C) 2010 Cyril Mottier (http://www.cyrilmottier.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package greendroid.app; import com.cyrilmottier.android.greendroid.R; import greendroid.util.Config; import greendroid.widget.GDActionBar; import greendroid.widget.ActionBarHost; import greendroid.widget.ActionBarItem; import greendroid.widget.GDActionBar.OnActionBarListener; import greendroid.widget.GDActionBar.Type; import android.app.Activity; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup.LayoutParams; import android.widget.FrameLayout; /** * <p> * An {@link GDActivity} is a regular Activity that always hosts an * {@link GDActionBar}. It is extremely simple to use as you have nothing * particular to do. Indeed, the ActionBar is automatically added to your own * layout when using the {@link #getContentView()} method. You can also use one * of the setActionBarContentView utility methods. As a result, a basic * {@link GDActivity} will often be initialized using the following snippet of * code: * </p> * * <pre> * protected void onCreate(Bundle savedInstanceState) { * super.onCreate(savedInstanceState); * * setActionBarContentView(R.layout.main); * } * </pre> * <p> * An ActionBar is a widget that may contains actions items and a title. You can * also set the title putting an extra string with the key * {@link GD_ACTION_BAR_TITLE} in your Intent: * </p> * * <pre> * Intent intent = new Intent(this, MyGDActivity.class); * intent.putExtra(ActionBarActivity.GD_ACTION_BAR_TITLE, "Next screen title"); * startActivity(intent); * </pre> * <p> * Note: An {@link GDActivity} automatically handle the type of the ActionBar * (Dashboard or Normal) depending on the value returned by the * getHomeActivityClass of your {@link GDApplication}. However you can force the * type of the action bar in your constructor. * </p> * * <pre> * public MyGDActivity() { * super(ActionBar.Type.Dashboard); * } * </pre> * <p> * All Activities that inherits from an {@link GDActivity} are notified when an * action button is tapped in the onHandleActionBarItemClick(ActionBarItem, int) * method. By default this method does nothing but return false. * </p> * * @see {@link GDApplication#getHomeActivityClass()} * @see {@link ActionBarActivity#GD_ACTION_BAR_TITLE} * @see {@link GDActivity#setActionBarContentView(int)} * @see {@link GDActivity#setActionBarContentView(View)} * @see {@link GDActivity#setActionBarContentView(View, LayoutParams)} * @author Cyril Mottier */ public class GDActivity extends Activity implements ActionBarActivity { private static final String LOG_TAG = GDActivity.class.getSimpleName(); private boolean mDefaultConstructorUsed = false; private Type mActionBarType; private ActionBarHost mActionBarHost; public GDActivity() { this(Type.Normal); mDefaultConstructorUsed = true; } public GDActivity(GDActionBar.Type actionBarType) { super(); mActionBarType = actionBarType; } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { ensureLayout(); super.onRestoreInstanceState(savedInstanceState); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (mDefaultConstructorUsed) { // HACK cyril: This should have been done is the default // constructor. Unfortunately, the getApplication() method returns // null there. Hence, this has to be done here. if (getClass().equals(getGDApplication().getHomeActivityClass())) { mActionBarType = Type.Dashboard; } } } @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); ensureLayout(); } public GDActionBar.Type getActionBarType() { return mActionBarType; } public int createLayout() { switch (mActionBarType) { case Dashboard: return R.layout.gd_content_dashboard; case Empty: return R.layout.gd_content_empty; case Normal: default: return R.layout.gd_content_normal; } } protected void ensureLayout() { if (!verifyLayout()) { setContentView(createLayout()); } } protected boolean verifyLayout() { return mActionBarHost != null; } public GDApplication getGDApplication() { return (GDApplication) getApplication(); } @Override public void onContentChanged() { super.onContentChanged(); onPreContentChanged(); onPostContentChanged(); } public void onPreContentChanged() { mActionBarHost = (ActionBarHost) findViewById(R.id.gd_action_bar_host); if (mActionBarHost == null) { throw new RuntimeException( "Your content must have an ActionBarHost whose id attribute is R.id.gd_action_bar_host"); } mActionBarHost.getActionBar().setOnActionBarListener(mActionBarListener); } public void onPostContentChanged() { boolean titleSet = false; final Intent intent = getIntent(); if (intent != null) { String title = intent.getStringExtra(ActionBarActivity.GD_ACTION_BAR_TITLE); if (title != null) { titleSet = true; setTitle(title); } } if (!titleSet) { // No title has been set via the Intent. Let's look in the // ActivityInfo try { final ActivityInfo activityInfo = getPackageManager().getActivityInfo(getComponentName(), 0); if (activityInfo.labelRes != 0) { setTitle(activityInfo.labelRes); } } catch (NameNotFoundException e) { // Do nothing } } final int visibility = intent.getIntExtra(ActionBarActivity.GD_ACTION_BAR_VISIBILITY, View.VISIBLE); getGDActionBar().setVisibility(visibility); } @Override public void setTitle(CharSequence title) { getGDActionBar().setTitle(title); } @Override public void setTitle(int titleId) { setTitle(getString(titleId)); } public GDActionBar getGDActionBar() { ensureLayout(); return mActionBarHost.getActionBar(); } public ActionBarItem addActionBarItem(ActionBarItem item) { return getGDActionBar().addItem(item); } public ActionBarItem addActionBarItem(ActionBarItem item, int itemId) { return getGDActionBar().addItem(item, itemId); } public ActionBarItem addActionBarItem(ActionBarItem.Type actionBarItemType) { return getGDActionBar().addItem(actionBarItemType); } public ActionBarItem addActionBarItem(ActionBarItem.Type actionBarItemType, int itemId) { return getGDActionBar().addItem(actionBarItemType, itemId); } public FrameLayout getContentView() { ensureLayout(); return mActionBarHost.getContentView(); } public void setActionBarContentView(int resID) { LayoutInflater.from(this).inflate(resID, getContentView()); } public void setActionBarContentView(View view, LayoutParams params) { getContentView().addView(view, params); } public void setActionBarContentView(View view) { getContentView().addView(view); } public boolean onHandleActionBarItemClick(ActionBarItem item, int position) { return false; } private OnActionBarListener mActionBarListener = new OnActionBarListener() { public void onActionBarItemClicked(int position) { if (position == OnActionBarListener.HOME_ITEM) { final GDApplication app = getGDApplication(); switch (mActionBarType) { case Normal: final Class<?> klass = app.getHomeActivityClass(); if (klass != null && !klass.equals(GDActivity.this.getClass())) { if (Config.GD_INFO_LOGS_ENABLED) { Log.i(LOG_TAG, "Going back to the home activity"); } Intent homeIntent = new Intent(GDActivity.this, klass); homeIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(homeIntent); } break; case Dashboard: final Intent appIntent = app.getMainApplicationIntent(); if (appIntent != null) { if (Config.GD_INFO_LOGS_ENABLED) { Log.i(LOG_TAG, "Launching the main application Intent"); } startActivity(appIntent); } break; } } else { if (!onHandleActionBarItemClick(getGDActionBar().getItem(position), position)) { if (Config.GD_WARNING_LOGS_ENABLED) { Log.w(LOG_TAG, "Click on item at position " + position + " dropped down to the floor"); } } } } }; }