diff --git a/.classpath b/.classpath index 1e34f60..4b421f7 100644 --- a/.classpath +++ b/.classpath @@ -5,7 +5,6 @@ - diff --git a/.project b/.project index 872fd55..1ce07ec 100644 --- a/.project +++ b/.project @@ -25,9 +25,15 @@ + + net.rim.ajde.internal.verifier + + + com.android.ide.eclipse.adt.AndroidNature org.eclipse.jdt.core.javanature + net.rim.ajde.BlackBerryAndroidNature diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 4f6c1d3..3447d3a 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -7,21 +7,24 @@ - + + android:label="@string/app_name" + android:theme="@style/AppTheme" > - + android:name="RoutesListActivity" + android:label="@string/app_name" > + - + @@ -30,7 +33,7 @@ - + @@ -39,9 +42,10 @@ - + android:name="AddRouteActivity" + android:label="@string/add_route" + android:theme="@android:style/Theme.Dialog" > + @@ -50,9 +54,9 @@ - + android:name="ViewDeparturesActivity" + android:label="@string/departures" > + @@ -61,14 +65,14 @@ + android:name="ViewMapActivity" + android:label="@string/system_map" > + android:label="BartRunner data provider" /> \ No newline at end of file diff --git a/libs/android-support-v4.jar b/libs/android-support-v4.jar deleted file mode 100644 index 99e063b..0000000 Binary files a/libs/android-support-v4.jar and /dev/null differ diff --git a/lint.xml b/lint.xml new file mode 100644 index 0000000..ee0eead --- /dev/null +++ b/lint.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/res/drawable-hdpi/actionbar_shadow.9.png b/res/drawable-hdpi/actionbar_shadow.9.png new file mode 100644 index 0000000..3c80a3f Binary files /dev/null and b/res/drawable-hdpi/actionbar_shadow.9.png differ diff --git a/res/drawable-hdpi/map_icon.png b/res/drawable-hdpi/map_icon.png new file mode 100644 index 0000000..e590707 Binary files /dev/null and b/res/drawable-hdpi/map_icon.png differ diff --git a/res/drawable-hdpi/new_icon.png b/res/drawable-hdpi/new_icon.png new file mode 100644 index 0000000..ad8ada6 Binary files /dev/null and b/res/drawable-hdpi/new_icon.png differ diff --git a/res/drawable-hdpi/web_icon.png b/res/drawable-hdpi/web_icon.png new file mode 100644 index 0000000..e154afd Binary files /dev/null and b/res/drawable-hdpi/web_icon.png differ diff --git a/res/drawable-mdpi/actionbar_shadow.9.png b/res/drawable-mdpi/actionbar_shadow.9.png new file mode 100644 index 0000000..cae1778 Binary files /dev/null and b/res/drawable-mdpi/actionbar_shadow.9.png differ diff --git a/res/drawable-mdpi/map_icon.png b/res/drawable-mdpi/map_icon.png new file mode 100644 index 0000000..21de201 Binary files /dev/null and b/res/drawable-mdpi/map_icon.png differ diff --git a/res/drawable-mdpi/new_icon.png b/res/drawable-mdpi/new_icon.png new file mode 100644 index 0000000..4d5d484 Binary files /dev/null and b/res/drawable-mdpi/new_icon.png differ diff --git a/res/drawable-mdpi/web_icon.png b/res/drawable-mdpi/web_icon.png new file mode 100644 index 0000000..41b56ec Binary files /dev/null and b/res/drawable-mdpi/web_icon.png differ diff --git a/res/drawable/actionbar_compat_item.xml b/res/drawable/actionbar_compat_item.xml new file mode 100644 index 0000000..4b3960c --- /dev/null +++ b/res/drawable/actionbar_compat_item.xml @@ -0,0 +1,23 @@ + + + + + + + diff --git a/res/drawable/actionbar_compat_item_focused.xml b/res/drawable/actionbar_compat_item_focused.xml new file mode 100644 index 0000000..04811d3 --- /dev/null +++ b/res/drawable/actionbar_compat_item_focused.xml @@ -0,0 +1,19 @@ + + + + + diff --git a/res/drawable/actionbar_compat_item_pressed.xml b/res/drawable/actionbar_compat_item_pressed.xml new file mode 100644 index 0000000..72ff4b4 --- /dev/null +++ b/res/drawable/actionbar_compat_item_pressed.xml @@ -0,0 +1,19 @@ + + + + + diff --git a/res/layout-v11/actionbar_indeterminate_progress.xml b/res/layout-v11/actionbar_indeterminate_progress.xml new file mode 100644 index 0000000..c05750e --- /dev/null +++ b/res/layout-v11/actionbar_indeterminate_progress.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/res/layout/actionbar_compat.xml b/res/layout/actionbar_compat.xml new file mode 100644 index 0000000..ae6c44b --- /dev/null +++ b/res/layout/actionbar_compat.xml @@ -0,0 +1,21 @@ + + + diff --git a/res/layout/add_favorite.xml b/res/layout/add_favorite.xml index 8eec91f..3b82187 100644 --- a/res/layout/add_favorite.xml +++ b/res/layout/add_favorite.xml @@ -2,10 +2,6 @@ - + + + + + + + + + + + \ No newline at end of file diff --git a/res/layout/main.xml b/res/layout/main.xml index 91e7e0e..4e07c8f 100644 --- a/res/layout/main.xml +++ b/res/layout/main.xml @@ -4,16 +4,6 @@ android:layout_height="fill_parent" android:orientation="vertical" > - - - - - \ No newline at end of file diff --git a/res/menu/route_menu.xml b/res/menu/route_menu.xml index d40585e..466cf0e 100644 --- a/res/menu/route_menu.xml +++ b/res/menu/route_menu.xml @@ -1,7 +1,17 @@ - - - - + + + + + + + + \ No newline at end of file diff --git a/res/menu/routes_list_menu.xml b/res/menu/routes_list_menu.xml index 5b5be09..cedd391 100644 --- a/res/menu/routes_list_menu.xml +++ b/res/menu/routes_list_menu.xml @@ -1,7 +1,17 @@ - - - - + + + + + + + + \ No newline at end of file diff --git a/res/menu/system_map_menu.xml b/res/menu/system_map_menu.xml new file mode 100644 index 0000000..c52f182 --- /dev/null +++ b/res/menu/system_map_menu.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/res/values-v11/styles.xml b/res/values-v11/styles.xml new file mode 100644 index 0000000..0d65e77 --- /dev/null +++ b/res/values-v11/styles.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/res/values-v13/styles.xml b/res/values-v13/styles.xml new file mode 100644 index 0000000..8a042b4 --- /dev/null +++ b/res/values-v13/styles.xml @@ -0,0 +1,23 @@ + + + + + + + diff --git a/res/values/attrs.xml b/res/values/attrs.xml new file mode 100644 index 0000000..c59822c --- /dev/null +++ b/res/values/attrs.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + diff --git a/res/values/colors.xml b/res/values/colors.xml index 4faa818..ec349a6 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -1,4 +1,5 @@ #FF000000 - + #EEEEEE + \ No newline at end of file diff --git a/res/values/dimens.xml b/res/values/dimens.xml new file mode 100644 index 0000000..67c8436 --- /dev/null +++ b/res/values/dimens.xml @@ -0,0 +1,21 @@ + + + + 48dp + 48dp + 56dp + diff --git a/res/values/ids.xml b/res/values/ids.xml new file mode 100644 index 0000000..e0a4745 --- /dev/null +++ b/res/values/ids.xml @@ -0,0 +1,23 @@ + + + + + + + + + diff --git a/res/values/strings.xml b/res/values/strings.xml index bcda25f..2ada87c 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -2,8 +2,7 @@ BART Runner Favorite Routes - Press the menu button and select \"Add route\" to - add a route + No favorite routes have been added yet Add a route Origin Destination @@ -29,4 +28,6 @@ again later. Also add return route View system map + System map + Departures diff --git a/res/values/styles.xml b/res/values/styles.xml index 65aa43f..886faa6 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -1,78 +1,129 @@ - - - + - + + + + @style/ActionBarCompatTitle + @style/ActionBarCompatItem + @style/ActionBarCompatHomeItem + @style/ActionBarCompatProgressIndicator + - + - + + + center + @drawable/actionbar_compat_item + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/com/dougkeen/bart/RoutesListActivity.java b/src/com/dougkeen/bart/RoutesListActivity.java index d599736..c720791 100644 --- a/src/com/dougkeen/bart/RoutesListActivity.java +++ b/src/com/dougkeen/bart/RoutesListActivity.java @@ -6,7 +6,6 @@ import java.util.TimeZone; import android.app.AlertDialog; import android.app.AlertDialog.Builder; import android.app.Dialog; -import android.app.ListActivity; import android.content.ContentUris; import android.content.ContentValues; import android.content.DialogInterface; @@ -27,13 +26,14 @@ import android.widget.SimpleCursorAdapter; import android.widget.SimpleCursorAdapter.ViewBinder; import android.widget.TextView; +import com.dougkeen.bart.actionbarcompat.ActionBarListActivity; import com.dougkeen.bart.data.CursorUtils; import com.dougkeen.bart.data.RoutesColumns; import com.dougkeen.bart.model.Constants; import com.dougkeen.bart.model.Station; import com.dougkeen.bart.networktasks.GetRouteFareTask; -public class RoutesListActivity extends ListActivity { +public class RoutesListActivity extends ActionBarListActivity { private static final TimeZone PACIFIC_TIME = TimeZone .getTimeZone("America/Los_Angeles"); @@ -50,6 +50,7 @@ public class RoutesListActivity extends ListActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); + setTitle(R.string.favorite_routes); mQuery = managedQuery(Constants.FAVORITE_CONTENT_URI, new String[] { RoutesColumns._ID.string, RoutesColumns.FROM_STATION.string, @@ -138,8 +139,6 @@ public class RoutesListActivity extends ListActivity { @Override protected void onResume() { super.onResume(); - ((TextView) findViewById(R.id.listTitle)) - .setText(R.string.favorite_routes); ((TextView) findViewById(android.R.id.empty)) .setText(R.string.empty_favorites_list_message); refreshFares(); diff --git a/src/com/dougkeen/bart/ViewDeparturesActivity.java b/src/com/dougkeen/bart/ViewDeparturesActivity.java index 2e5e40e..30ca3c9 100644 --- a/src/com/dougkeen/bart/ViewDeparturesActivity.java +++ b/src/com/dougkeen/bart/ViewDeparturesActivity.java @@ -4,7 +4,6 @@ import java.util.List; import org.apache.commons.lang3.math.NumberUtils; -import android.app.ListActivity; import android.content.ContentValues; import android.content.Context; import android.content.Intent; @@ -24,6 +23,7 @@ import android.view.View; import android.widget.TextView; import android.widget.Toast; +import com.dougkeen.bart.actionbarcompat.ActionBarListActivity; import com.dougkeen.bart.data.RoutesColumns; import com.dougkeen.bart.model.Constants; import com.dougkeen.bart.model.Departure; @@ -35,7 +35,7 @@ import com.dougkeen.bart.model.StationPair; import com.dougkeen.bart.networktasks.GetRealTimeDeparturesTask; import com.dougkeen.bart.networktasks.GetScheduleInformationTask; -public class ViewDeparturesActivity extends ListActivity { +public class ViewDeparturesActivity extends ActionBarListActivity { private static final int UNCERTAINTY_THRESHOLD = 17; @@ -50,7 +50,7 @@ public class ViewDeparturesActivity extends ListActivity { private ScheduleInformation mLatestScheduleInfo; - private TextView mListTitleView; + private TextView mEmptyView; private AsyncTask mGetDeparturesTask; private AsyncTask mGetScheduleInformationTask; @@ -71,7 +71,7 @@ public class ViewDeparturesActivity extends ListActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.main); + setContentView(R.layout.departures); final Intent intent = getIntent(); @@ -96,13 +96,11 @@ public class ViewDeparturesActivity extends ListActivity { mAverageTripLength = cursor.getInt(2); mAverageTripSampleCount = cursor.getInt(3); - String header = "Departures:\n" + mOrigin.name + " to " - + mDestination.name; + ((TextView) findViewById(R.id.listTitle)).setText(mOrigin.name + " to " + + mDestination.name); - mListTitleView = (TextView) findViewById(R.id.listTitle); - mListTitleView.setText(header); - ((TextView) findViewById(android.R.id.empty)) - .setText(R.string.departure_wait_message); + mEmptyView = (TextView) findViewById(android.R.id.empty); + mEmptyView.setText(R.string.departure_wait_message); mDeparturesAdapter = new DepartureArrayAdapter(this, R.layout.departure_listing); @@ -200,8 +198,7 @@ public class ViewDeparturesActivity extends ListActivity { Log.w(Constants.TAG, e.getMessage(), e); Toast.makeText(ViewDeparturesActivity.this, R.string.could_not_connect, Toast.LENGTH_LONG).show(); - ((TextView) findViewById(android.R.id.empty)) - .setText(R.string.could_not_connect); + mEmptyView.setText(R.string.could_not_connect); // Try again in 60s scheduleDepartureFetch(60000); } @@ -236,8 +233,7 @@ public class ViewDeparturesActivity extends ListActivity { Log.w(Constants.TAG, e.getMessage(), e); Toast.makeText(ViewDeparturesActivity.this, R.string.could_not_connect, Toast.LENGTH_LONG).show(); - ((TextView) findViewById(android.R.id.empty)) - .setText(R.string.could_not_connect); + mEmptyView.setText(R.string.could_not_connect); // Try again in 60s scheduleScheduleInfoFetch(60000); } @@ -262,7 +258,7 @@ public class ViewDeparturesActivity extends ListActivity { return; } if (result.getDepartures().isEmpty()) { - final TextView textView = (TextView) findViewById(android.R.id.empty); + final TextView textView = mEmptyView; textView.setText(R.string.no_data_message); Linkify.addLinks(textView, Linkify.WEB_URLS); return; @@ -486,7 +482,7 @@ public class ViewDeparturesActivity extends ListActivity { private void scheduleDepartureFetch(int millisUntilExecute) { if (!mDepartureFetchIsPending) { - mListTitleView.postDelayed(new Runnable() { + postDelayed(new Runnable() { public void run() { fetchLatestDepartures(); } @@ -499,7 +495,7 @@ public class ViewDeparturesActivity extends ListActivity { private void scheduleScheduleInfoFetch(int millisUntilExecute) { if (!mScheduleFetchIsPending) { - mListTitleView.postDelayed(new Runnable() { + postDelayed(new Runnable() { public void run() { fetchLatestSchedule(); } @@ -523,12 +519,16 @@ public class ViewDeparturesActivity extends ListActivity { } mLastAutoUpdate = now; if (hasWindowFocus()) { - mListTitleView.postDelayed(AUTO_UPDATE_RUNNABLE, 1000); + postDelayed(AUTO_UPDATE_RUNNABLE, 1000); } else { mIsAutoUpdating = false; } } + private boolean postDelayed(Runnable runnable, long delayMillis) { + return mEmptyView.postDelayed(runnable, delayMillis); + } + @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); diff --git a/src/com/dougkeen/bart/ViewMapActivity.java b/src/com/dougkeen/bart/ViewMapActivity.java index f2b5b9f..00c3485 100644 --- a/src/com/dougkeen/bart/ViewMapActivity.java +++ b/src/com/dougkeen/bart/ViewMapActivity.java @@ -1,10 +1,13 @@ package com.dougkeen.bart; -import android.app.Activity; import android.os.Bundle; +import android.view.Menu; +import android.view.MenuInflater; import android.webkit.WebView; -public class ViewMapActivity extends Activity { +import com.dougkeen.bart.actionbarcompat.ActionBarActivity; + +public class ViewMapActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { @@ -18,4 +21,12 @@ public class ViewMapActivity extends Activity { webview.loadUrl("file:///android_res/drawable/map.png"); } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.system_map_menu, menu); + return true; + } + } diff --git a/src/com/dougkeen/bart/actionbarcompat/ActionBarActivity.java b/src/com/dougkeen/bart/actionbarcompat/ActionBarActivity.java new file mode 100644 index 0000000..02ea24e --- /dev/null +++ b/src/com/dougkeen/bart/actionbarcompat/ActionBarActivity.java @@ -0,0 +1,63 @@ +package com.dougkeen.bart.actionbarcompat; + +import android.app.Activity; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuInflater; + +/** + * Damn, I wish Java had mixins + */ +public class ActionBarActivity extends Activity { + final ActionBarHelper mActionBarHelper = ActionBarHelper + .createInstance(this); + + /** + * Returns the {@link ActionBarHelper} for this activity. + */ + protected ActionBarHelper getActionBarHelper() { + return mActionBarHelper; + } + + /** {@inheritDoc} */ + @Override + public MenuInflater getMenuInflater() { + return mActionBarHelper.getMenuInflater(super.getMenuInflater()); + } + + /** {@inheritDoc} */ + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mActionBarHelper.onCreate(savedInstanceState); + } + + /** {@inheritDoc} */ + @Override + protected void onPostCreate(Bundle savedInstanceState) { + super.onPostCreate(savedInstanceState); + mActionBarHelper.onPostCreate(savedInstanceState); + } + + /** + * Base action bar-aware implementation for + * {@link Activity#onCreateOptionsMenu(android.view.Menu)}. + * + * Note: marking menu items as invisible/visible is not currently supported. + */ + @Override + public boolean onCreateOptionsMenu(Menu menu) { + boolean retValue = false; + retValue |= mActionBarHelper.onCreateOptionsMenu(menu); + retValue |= super.onCreateOptionsMenu(menu); + return retValue; + } + + /** {@inheritDoc} */ + @Override + protected void onTitleChanged(CharSequence title, int color) { + mActionBarHelper.onTitleChanged(title, color); + super.onTitleChanged(title, color); + } + +} diff --git a/src/com/dougkeen/bart/actionbarcompat/ActionBarHelper.java b/src/com/dougkeen/bart/actionbarcompat/ActionBarHelper.java new file mode 100644 index 0000000..73de5d9 --- /dev/null +++ b/src/com/dougkeen/bart/actionbarcompat/ActionBarHelper.java @@ -0,0 +1,97 @@ +/* + * Copyright 2011 The Android Open Source Project + * + * 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 com.dougkeen.bart.actionbarcompat; + +import android.app.Activity; +import android.os.Build; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuInflater; + +/** + * An abstract class that handles some common action bar-related functionality in the app. This + * class provides functionality useful for both phones and tablets, and does not require any Android + * 3.0-specific features, although it uses them if available. + * + * Two implementations of this class are {@link ActionBarHelperBase} for a pre-Honeycomb version of + * the action bar, and {@link ActionBarHelperHoneycomb}, which uses the built-in ActionBar features + * in Android 3.0 and later. + */ +public abstract class ActionBarHelper { + protected Activity mActivity; + + /** + * Factory method for creating {@link ActionBarHelper} objects for a + * given activity. Depending on which device the app is running, either a basic helper or + * Honeycomb-specific helper will be returned. + */ + public static ActionBarHelper createInstance(Activity activity) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + return new ActionBarHelperICS(activity); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + return new ActionBarHelperHoneycomb(activity); + } else { + return new ActionBarHelperBase(activity); + } + } + + protected ActionBarHelper(Activity activity) { + mActivity = activity; + } + + /** + * Action bar helper code to be run in {@link Activity#onCreate(android.os.Bundle)}. + */ + public void onCreate(Bundle savedInstanceState) { + } + + /** + * Action bar helper code to be run in {@link Activity#onPostCreate(android.os.Bundle)}. + */ + public void onPostCreate(Bundle savedInstanceState) { + } + + /** + * Action bar helper code to be run in {@link Activity#onCreateOptionsMenu(android.view.Menu)}. + * + * NOTE: Setting the visibility of menu items in menu is not currently supported. + */ + public boolean onCreateOptionsMenu(Menu menu) { + return true; + } + + /** + * Action bar helper code to be run in {@link Activity#onTitleChanged(CharSequence, int)}. + */ + protected void onTitleChanged(CharSequence title, int color) { + } + + /** + * Sets the indeterminate loading state of the item with ID {@link R.id.menu_refresh}. + * (where the item ID was menu_refresh). + */ + public abstract void setRefreshActionItemState(boolean refreshing); + + /** + * Returns a {@link MenuInflater} for use when inflating menus. The implementation of this + * method in {@link ActionBarHelperBase} returns a wrapped menu inflater that can read + * action bar metadata from a menu resource pre-Honeycomb. + */ + public MenuInflater getMenuInflater(MenuInflater superMenuInflater) { + return superMenuInflater; + } +} diff --git a/src/com/dougkeen/bart/actionbarcompat/ActionBarHelperBase.java b/src/com/dougkeen/bart/actionbarcompat/ActionBarHelperBase.java new file mode 100644 index 0000000..66812c9 --- /dev/null +++ b/src/com/dougkeen/bart/actionbarcompat/ActionBarHelperBase.java @@ -0,0 +1,319 @@ +/* + * Copyright 2011 The Android Open Source Project + * + * 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 com.dougkeen.bart.actionbarcompat; + +import java.io.IOException; +import java.util.HashSet; +import java.util.Set; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import android.app.Activity; +import android.content.Context; +import android.content.res.XmlResourceParser; +import android.os.Bundle; +import android.view.InflateException; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.dougkeen.bart.R; + +/** + * A class that implements the action bar pattern for pre-Honeycomb devices. + */ +public class ActionBarHelperBase extends ActionBarHelper { + private static final String MENU_RES_NAMESPACE = "http://schemas.android.com/apk/res/android"; + private static final String MENU_ATTR_ID = "id"; + private static final String MENU_ATTR_SHOW_AS_ACTION = "showAsAction"; + + protected Set mActionItemIds = new HashSet(); + + protected ActionBarHelperBase(Activity activity) { + super(activity); + } + + /** {@inheritDoc} */ + @Override + public void onCreate(Bundle savedInstanceState) { + mActivity.requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); + } + + /** {@inheritDoc} */ + @Override + public void onPostCreate(Bundle savedInstanceState) { + mActivity.getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, + R.layout.actionbar_compat); + setupActionBar(); + + SimpleMenu menu = new SimpleMenu(mActivity); + mActivity.onCreatePanelMenu(Window.FEATURE_OPTIONS_PANEL, menu); + mActivity.onPrepareOptionsMenu(menu); + for (int i = 0; i < menu.size(); i++) { + MenuItem item = menu.getItem(i); + if (mActionItemIds.contains(item.getItemId())) { + addActionItemCompatFromMenuItem(item); + } + } + } + + /** + * Sets up the compatibility action bar with the given title. + */ + private void setupActionBar() { + final ViewGroup actionBarCompat = getActionBarCompat(); + if (actionBarCompat == null) { + return; + } + + LinearLayout.LayoutParams springLayoutParams = new LinearLayout.LayoutParams( + 0, ViewGroup.LayoutParams.FILL_PARENT); + springLayoutParams.weight = 1; + + // Add Home button + SimpleMenu tempMenu = new SimpleMenu(mActivity); + SimpleMenuItem homeItem = new SimpleMenuItem(tempMenu, + android.R.id.home, 0, mActivity.getString(R.string.app_name)); + homeItem.setIcon(R.drawable.icon); + addActionItemCompatFromMenuItem(homeItem); + + // Add title text + TextView titleText = new TextView(mActivity, null, + R.attr.actionbarCompatTitleStyle); + titleText.setLayoutParams(springLayoutParams); + titleText.setText(mActivity.getTitle()); + actionBarCompat.addView(titleText); + } + + /** {@inheritDoc} */ + @Override + public void setRefreshActionItemState(boolean refreshing) { + View refreshButton = mActivity + .findViewById(R.id.actionbar_compat_item_refresh); + View refreshIndicator = mActivity + .findViewById(R.id.actionbar_compat_item_refresh_progress); + + if (refreshButton != null) { + refreshButton.setVisibility(refreshing ? View.GONE : View.VISIBLE); + } + if (refreshIndicator != null) { + refreshIndicator.setVisibility(refreshing ? View.VISIBLE + : View.GONE); + } + } + + /** + * Action bar helper code to be run in + * {@link Activity#onCreateOptionsMenu(android.view.Menu)}. + * + * NOTE: This code will mark on-screen menu items as invisible. + */ + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Hides on-screen action items from the options menu. + for (Integer id : mActionItemIds) { + menu.findItem(id).setVisible(false); + } + return true; + } + + /** {@inheritDoc} */ + @Override + protected void onTitleChanged(CharSequence title, int color) { + TextView titleView = (TextView) mActivity + .findViewById(R.id.actionbar_compat_title); + if (titleView != null) { + titleView.setText(title); + } + } + + /** + * Returns a {@link android.view.MenuInflater} that can read action bar + * metadata on pre-Honeycomb devices. + */ + public MenuInflater getMenuInflater(MenuInflater superMenuInflater) { + return new WrappedMenuInflater(mActivity, superMenuInflater); + } + + /** + * Returns the {@link android.view.ViewGroup} for the action bar on phones + * (compatibility action bar). Can return null, and will return null on + * Honeycomb. + */ + private ViewGroup getActionBarCompat() { + return (ViewGroup) mActivity.findViewById(R.id.actionbar_compat); + } + + /** + * Adds an action button to the compatibility action bar, using menu + * information from a {@link android.view.MenuItem}. If the menu item ID is + * menu_refresh, the menu item's state can be changed to show a + * loading spinner using + * {@link com.example.android.actionbarcompat.ActionBarHelperBase#setRefreshActionItemState(boolean)} + * . + */ + private View addActionItemCompatFromMenuItem(final MenuItem item) { + final int itemId = item.getItemId(); + + final ViewGroup actionBar = getActionBarCompat(); + if (actionBar == null) { + return null; + } + + // Create the button + ImageButton actionButton = new ImageButton( + mActivity, + null, + itemId == android.R.id.home ? R.attr.actionbarCompatItemHomeStyle + : R.attr.actionbarCompatItemStyle); + actionButton + .setLayoutParams(new ViewGroup.LayoutParams( + (int) mActivity + .getResources() + .getDimension( + itemId == android.R.id.home ? R.dimen.actionbar_compat_button_home_width + : R.dimen.actionbar_compat_button_width), + ViewGroup.LayoutParams.FILL_PARENT)); + if (itemId == R.id.menu_refresh) { + actionButton.setId(R.id.actionbar_compat_item_refresh); + } + actionButton.setImageDrawable(item.getIcon()); + actionButton.setScaleType(ImageView.ScaleType.CENTER); + actionButton.setContentDescription(item.getTitle()); + actionButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + mActivity + .onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, item); + } + }); + + actionBar.addView(actionButton); + + if (item.getItemId() == R.id.menu_refresh) { + // Refresh buttons should be stateful, and allow for indeterminate + // progress indicators, + // so add those. + ProgressBar indicator = new ProgressBar(mActivity, null, + R.attr.actionbarCompatProgressIndicatorStyle); + + final int buttonWidth = mActivity.getResources() + .getDimensionPixelSize( + R.dimen.actionbar_compat_button_width); + final int buttonHeight = mActivity.getResources() + .getDimensionPixelSize(R.dimen.actionbar_compat_height); + final int progressIndicatorWidth = buttonWidth / 2; + + LinearLayout.LayoutParams indicatorLayoutParams = new LinearLayout.LayoutParams( + progressIndicatorWidth, progressIndicatorWidth); + indicatorLayoutParams.setMargins( + (buttonWidth - progressIndicatorWidth) / 2, + (buttonHeight - progressIndicatorWidth) / 2, + (buttonWidth - progressIndicatorWidth) / 2, 0); + indicator.setLayoutParams(indicatorLayoutParams); + indicator.setVisibility(View.GONE); + indicator.setId(R.id.actionbar_compat_item_refresh_progress); + actionBar.addView(indicator); + } + + return actionButton; + } + + /** + * A {@link android.view.MenuInflater} that reads action bar metadata. + */ + private class WrappedMenuInflater extends MenuInflater { + MenuInflater mInflater; + + public WrappedMenuInflater(Context context, MenuInflater inflater) { + super(context); + mInflater = inflater; + } + + @Override + public void inflate(int menuRes, Menu menu) { + loadActionBarMetadata(menuRes); + mInflater.inflate(menuRes, menu); + } + + /** + * Loads action bar metadata from a menu resource, storing a list of + * menu item IDs that should be shown on-screen (i.e. those with + * showAsAction set to always or ifRoom). + * + * @param menuResId + */ + private void loadActionBarMetadata(int menuResId) { + XmlResourceParser parser = null; + try { + parser = mActivity.getResources().getXml(menuResId); + + int eventType = parser.getEventType(); + int itemId; + int showAsAction; + + boolean eof = false; + while (!eof) { + switch (eventType) { + case XmlPullParser.START_TAG: + if (!parser.getName().equals("item")) { + break; + } + + itemId = parser.getAttributeResourceValue( + MENU_RES_NAMESPACE, MENU_ATTR_ID, 0); + if (itemId == 0) { + break; + } + + showAsAction = parser.getAttributeIntValue( + MENU_RES_NAMESPACE, MENU_ATTR_SHOW_AS_ACTION, + -1); + if ((showAsAction & MenuItem.SHOW_AS_ACTION_ALWAYS) > 0 + || (showAsAction & MenuItem.SHOW_AS_ACTION_IF_ROOM) > 0) { + mActionItemIds.add(itemId); + } + break; + + case XmlPullParser.END_DOCUMENT: + eof = true; + break; + } + + eventType = parser.next(); + } + } catch (XmlPullParserException e) { + throw new InflateException("Error inflating menu XML", e); + } catch (IOException e) { + throw new InflateException("Error inflating menu XML", e); + } finally { + if (parser != null) { + parser.close(); + } + } + } + + } +} diff --git a/src/com/dougkeen/bart/actionbarcompat/ActionBarHelperHoneycomb.java b/src/com/dougkeen/bart/actionbarcompat/ActionBarHelperHoneycomb.java new file mode 100644 index 0000000..2643f3f --- /dev/null +++ b/src/com/dougkeen/bart/actionbarcompat/ActionBarHelperHoneycomb.java @@ -0,0 +1,80 @@ +/* + * Copyright 2011 The Android Open Source Project + * + * 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 com.dougkeen.bart.actionbarcompat; + +import android.app.Activity; +import android.content.Context; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; + +import com.dougkeen.bart.R; + +/** + * An extension of {@link ActionBarHelper} that provides Android 3.0-specific functionality for + * Honeycomb tablets. It thus requires API level 11. + */ +public class ActionBarHelperHoneycomb extends ActionBarHelper { + private Menu mOptionsMenu; + private View mRefreshIndeterminateProgressView = null; + + protected ActionBarHelperHoneycomb(Activity activity) { + super(activity); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + mOptionsMenu = menu; + return super.onCreateOptionsMenu(menu); + } + + @Override + public void setRefreshActionItemState(boolean refreshing) { + // On Honeycomb, we can set the state of the refresh button by giving it a custom + // action view. + if (mOptionsMenu == null) { + return; + } + + final MenuItem refreshItem = mOptionsMenu.findItem(R.id.menu_refresh); + if (refreshItem != null) { + if (refreshing) { + if (mRefreshIndeterminateProgressView == null) { + LayoutInflater inflater = (LayoutInflater) + getActionBarThemedContext().getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + mRefreshIndeterminateProgressView = inflater.inflate( + R.layout.actionbar_indeterminate_progress, null); + } + + refreshItem.setActionView(mRefreshIndeterminateProgressView); + } else { + refreshItem.setActionView(null); + } + } + } + + /** + * Returns a {@link Context} suitable for inflating layouts for the action bar. The + * implementation for this method in {@link ActionBarHelperICS} asks the action bar for a + * themed context. + */ + protected Context getActionBarThemedContext() { + return mActivity; + } +} diff --git a/src/com/dougkeen/bart/actionbarcompat/ActionBarHelperICS.java b/src/com/dougkeen/bart/actionbarcompat/ActionBarHelperICS.java new file mode 100644 index 0000000..64abb53 --- /dev/null +++ b/src/com/dougkeen/bart/actionbarcompat/ActionBarHelperICS.java @@ -0,0 +1,37 @@ +/* + * Copyright 2011 The Android Open Source Project + * + * 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 com.dougkeen.bart.actionbarcompat; + +import android.app.Activity; +import android.content.Context; +import android.view.Menu; +import android.view.MenuItem; + +/** + * An extension of {@link com.example.android.actionbarcompat.ActionBarHelper} that provides Android + * 4.0-specific functionality for IceCreamSandwich devices. It thus requires API level 14. + */ +public class ActionBarHelperICS extends ActionBarHelperHoneycomb { + protected ActionBarHelperICS(Activity activity) { + super(activity); + } + + @Override + protected Context getActionBarThemedContext() { + return mActivity.getActionBar().getThemedContext(); + } +} diff --git a/src/com/dougkeen/bart/actionbarcompat/ActionBarListActivity.java b/src/com/dougkeen/bart/actionbarcompat/ActionBarListActivity.java new file mode 100644 index 0000000..256efad --- /dev/null +++ b/src/com/dougkeen/bart/actionbarcompat/ActionBarListActivity.java @@ -0,0 +1,84 @@ +/* + * Copyright 2011 The Android Open Source Project + * + * 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 com.dougkeen.bart.actionbarcompat; + +import android.app.Activity; +import android.app.ListActivity; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuInflater; + +/** + * A base activity that defers common functionality across app activities to an {@link + * ActionBarHelper}. + * + * NOTE: dynamically marking menu items as invisible/visible is not currently supported. + * + * NOTE: this may used with the Android Compatibility Package by extending + * android.support.v4.app.FragmentActivity instead of {@link Activity}. + */ +public abstract class ActionBarListActivity extends ListActivity { + final ActionBarHelper mActionBarHelper = ActionBarHelper.createInstance(this); + + /** + * Returns the {@link ActionBarHelper} for this activity. + */ + protected ActionBarHelper getActionBarHelper() { + return mActionBarHelper; + } + + /**{@inheritDoc}*/ + @Override + public MenuInflater getMenuInflater() { + return mActionBarHelper.getMenuInflater(super.getMenuInflater()); + } + + /**{@inheritDoc}*/ + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mActionBarHelper.onCreate(savedInstanceState); + } + + /**{@inheritDoc}*/ + @Override + protected void onPostCreate(Bundle savedInstanceState) { + super.onPostCreate(savedInstanceState); + mActionBarHelper.onPostCreate(savedInstanceState); + } + + /** + * Base action bar-aware implementation for + * {@link Activity#onCreateOptionsMenu(android.view.Menu)}. + * + * Note: marking menu items as invisible/visible is not currently supported. + */ + @Override + public boolean onCreateOptionsMenu(Menu menu) { + boolean retValue = false; + retValue |= mActionBarHelper.onCreateOptionsMenu(menu); + retValue |= super.onCreateOptionsMenu(menu); + return retValue; + } + + /**{@inheritDoc}*/ + @Override + protected void onTitleChanged(CharSequence title, int color) { + mActionBarHelper.onTitleChanged(title, color); + super.onTitleChanged(title, color); + } +} diff --git a/src/com/dougkeen/bart/actionbarcompat/SimpleMenu.java b/src/com/dougkeen/bart/actionbarcompat/SimpleMenu.java new file mode 100644 index 0000000..d2dc936 --- /dev/null +++ b/src/com/dougkeen/bart/actionbarcompat/SimpleMenu.java @@ -0,0 +1,203 @@ +/* + * Copyright 2011 The Android Open Source Project + * + * 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 com.dougkeen.bart.actionbarcompat; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.res.Resources; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuItem; +import android.view.SubMenu; + +import java.util.ArrayList; + +/** + * A really dumb implementation of the {@link android.view.Menu} interface, that's only + * useful for our actionbar-compat purposes. See + * com.android.internal.view.menu.MenuBuilder in AOSP for a more complete + * implementation. + */ +public class SimpleMenu implements Menu { + + private Context mContext; + private Resources mResources; + + private ArrayList mItems; + + public SimpleMenu(Context context) { + mContext = context; + mResources = context.getResources(); + mItems = new ArrayList(); + } + + public Context getContext() { + return mContext; + } + + public Resources getResources() { + return mResources; + } + + public MenuItem add(CharSequence title) { + return addInternal(0, 0, title); + } + + public MenuItem add(int titleRes) { + return addInternal(0, 0, mResources.getString(titleRes)); + } + + public MenuItem add(int groupId, int itemId, int order, CharSequence title) { + return addInternal(itemId, order, title); + } + + public MenuItem add(int groupId, int itemId, int order, int titleRes) { + return addInternal(itemId, order, mResources.getString(titleRes)); + } + + /** + * Adds an item to the menu. The other add methods funnel to this. + */ + private MenuItem addInternal(int itemId, int order, CharSequence title) { + final SimpleMenuItem item = new SimpleMenuItem(this, itemId, order, title); + mItems.add(findInsertIndex(mItems, order), item); + return item; + } + + private static int findInsertIndex(ArrayList items, int order) { + for (int i = items.size() - 1; i >= 0; i--) { + MenuItem item = items.get(i); + if (item.getOrder() <= order) { + return i + 1; + } + } + + return 0; + } + + public int findItemIndex(int id) { + final int size = size(); + + for (int i = 0; i < size; i++) { + SimpleMenuItem item = mItems.get(i); + if (item.getItemId() == id) { + return i; + } + } + + return -1; + } + + public void removeItem(int itemId) { + removeItemAtInt(findItemIndex(itemId)); + } + + private void removeItemAtInt(int index) { + if ((index < 0) || (index >= mItems.size())) { + return; + } + mItems.remove(index); + } + + public void clear() { + mItems.clear(); + } + + public MenuItem findItem(int id) { + final int size = size(); + for (int i = 0; i < size; i++) { + SimpleMenuItem item = mItems.get(i); + if (item.getItemId() == id) { + return item; + } + } + + return null; + } + + public int size() { + return mItems.size(); + } + + public MenuItem getItem(int index) { + return mItems.get(index); + } + + // Unsupported operations. + + public SubMenu addSubMenu(CharSequence charSequence) { + throw new UnsupportedOperationException("This operation is not supported for SimpleMenu"); + } + + public SubMenu addSubMenu(int titleRes) { + throw new UnsupportedOperationException("This operation is not supported for SimpleMenu"); + } + + public SubMenu addSubMenu(int groupId, int itemId, int order, CharSequence title) { + throw new UnsupportedOperationException("This operation is not supported for SimpleMenu"); + } + + public SubMenu addSubMenu(int groupId, int itemId, int order, int titleRes) { + throw new UnsupportedOperationException("This operation is not supported for SimpleMenu"); + } + + public int addIntentOptions(int i, int i1, int i2, ComponentName componentName, + Intent[] intents, Intent intent, int i3, MenuItem[] menuItems) { + throw new UnsupportedOperationException("This operation is not supported for SimpleMenu"); + } + + public void removeGroup(int i) { + throw new UnsupportedOperationException("This operation is not supported for SimpleMenu"); + } + + public void setGroupCheckable(int i, boolean b, boolean b1) { + throw new UnsupportedOperationException("This operation is not supported for SimpleMenu"); + } + + public void setGroupVisible(int i, boolean b) { + throw new UnsupportedOperationException("This operation is not supported for SimpleMenu"); + } + + public void setGroupEnabled(int i, boolean b) { + throw new UnsupportedOperationException("This operation is not supported for SimpleMenu"); + } + + public boolean hasVisibleItems() { + throw new UnsupportedOperationException("This operation is not supported for SimpleMenu"); + } + + public void close() { + throw new UnsupportedOperationException("This operation is not supported for SimpleMenu"); + } + + public boolean performShortcut(int i, KeyEvent keyEvent, int i1) { + throw new UnsupportedOperationException("This operation is not supported for SimpleMenu"); + } + + public boolean isShortcutKey(int i, KeyEvent keyEvent) { + throw new UnsupportedOperationException("This operation is not supported for SimpleMenu"); + } + + public boolean performIdentifierAction(int i, int i1) { + throw new UnsupportedOperationException("This operation is not supported for SimpleMenu"); + } + + public void setQwertyMode(boolean b) { + throw new UnsupportedOperationException("This operation is not supported for SimpleMenu"); + } +} diff --git a/src/com/dougkeen/bart/actionbarcompat/SimpleMenuItem.java b/src/com/dougkeen/bart/actionbarcompat/SimpleMenuItem.java new file mode 100644 index 0000000..54722e2 --- /dev/null +++ b/src/com/dougkeen/bart/actionbarcompat/SimpleMenuItem.java @@ -0,0 +1,263 @@ +/* + * Copyright 2011 The Android Open Source Project + * + * 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 com.dougkeen.bart.actionbarcompat; + +import android.content.Intent; +import android.graphics.drawable.Drawable; +import android.view.ActionProvider; +import android.view.ContextMenu; +import android.view.MenuItem; +import android.view.SubMenu; +import android.view.View; + +/** + * A really dumb implementation of the {@link android.view.MenuItem} + * interface, that's only useful for our actionbar-compat purposes. See + * com.android.internal.view.menu.MenuItemImpl in AOSP for a more + * complete implementation. + */ +public class SimpleMenuItem implements MenuItem { + + private SimpleMenu mMenu; + + private final int mId; + private final int mOrder; + private CharSequence mTitle; + private CharSequence mTitleCondensed; + private Drawable mIconDrawable; + private int mIconResId = 0; + private boolean mEnabled = true; + + public SimpleMenuItem(SimpleMenu menu, int id, int order, CharSequence title) { + mMenu = menu; + mId = id; + mOrder = order; + mTitle = title; + } + + public int getItemId() { + return mId; + } + + public int getOrder() { + return mOrder; + } + + public MenuItem setTitle(CharSequence title) { + mTitle = title; + return this; + } + + public MenuItem setTitle(int titleRes) { + return setTitle(mMenu.getContext().getString(titleRes)); + } + + public CharSequence getTitle() { + return mTitle; + } + + public MenuItem setTitleCondensed(CharSequence title) { + mTitleCondensed = title; + return this; + } + + public CharSequence getTitleCondensed() { + return mTitleCondensed != null ? mTitleCondensed : mTitle; + } + + public MenuItem setIcon(Drawable icon) { + mIconResId = 0; + mIconDrawable = icon; + return this; + } + + public MenuItem setIcon(int iconResId) { + mIconDrawable = null; + mIconResId = iconResId; + return this; + } + + public Drawable getIcon() { + if (mIconDrawable != null) { + return mIconDrawable; + } + + if (mIconResId != 0) { + return mMenu.getResources().getDrawable(mIconResId); + } + + return null; + } + + public MenuItem setEnabled(boolean enabled) { + mEnabled = enabled; + return this; + } + + public boolean isEnabled() { + return mEnabled; + } + + // No-op operations. We use no-ops to allow inflation from menu XML. + + public int getGroupId() { + // Noop + return 0; + } + + public View getActionView() { + // Noop + return null; + } + + public MenuItem setActionProvider(ActionProvider actionProvider) { + // Noop + return this; + } + + public ActionProvider getActionProvider() { + // Noop + return null; + } + + public boolean expandActionView() { + // Noop + return false; + } + + public boolean collapseActionView() { + // Noop + return false; + } + + public boolean isActionViewExpanded() { + // Noop + return false; + } + + @Override + public MenuItem setOnActionExpandListener( + OnActionExpandListener onActionExpandListener) { + // Noop + return this; + } + + public MenuItem setIntent(Intent intent) { + // Noop + return this; + } + + public Intent getIntent() { + // Noop + return null; + } + + public MenuItem setShortcut(char c, char c1) { + // Noop + return this; + } + + public MenuItem setNumericShortcut(char c) { + // Noop + return this; + } + + public char getNumericShortcut() { + // Noop + return 0; + } + + public MenuItem setAlphabeticShortcut(char c) { + // Noop + return this; + } + + public char getAlphabeticShortcut() { + // Noop + return 0; + } + + public MenuItem setCheckable(boolean b) { + // Noop + return this; + } + + public boolean isCheckable() { + // Noop + return false; + } + + public MenuItem setChecked(boolean b) { + // Noop + return this; + } + + public boolean isChecked() { + // Noop + return false; + } + + public MenuItem setVisible(boolean b) { + // Noop + return this; + } + + public boolean isVisible() { + // Noop + return true; + } + + public boolean hasSubMenu() { + // Noop + return false; + } + + public SubMenu getSubMenu() { + // Noop + return null; + } + + public MenuItem setOnMenuItemClickListener( + OnMenuItemClickListener onMenuItemClickListener) { + // Noop + return this; + } + + public ContextMenu.ContextMenuInfo getMenuInfo() { + // Noop + return null; + } + + public void setShowAsAction(int i) { + // Noop + } + + public MenuItem setShowAsActionFlags(int i) { + // Noop + return null; + } + + public MenuItem setActionView(View view) { + // Noop + return this; + } + + public MenuItem setActionView(int i) { + // Noop + return this; + } +}