ActionBarSherlock 3.x – Fix for theme icons
ActionBarSherlock has a nasty bug if you use theme icons.
For example:
styles.xml
<resources xmlns:android= "http://schemas.android.com/apk/res/android"> <style name="Theme.Test" parent="Theme.Sherlock.Light"> <item name="abIconSettings"> @drawable/ic_action_settings_holo_light</item> </style> </resources>
attrs.xml
<resources> <declare-styleable name="Theme"> <attr name="abIconSettings" format="reference" /> </declare-styleable> </resources>
menu.xml
<menu xmlns:android= "http://schemas.android.com/apk/res/android"> <item android:id="@+id/menu_settings" android:title="@string/menu_settings" android:orderInCategory="100" android:showAsAction="always" android:icon="?attr/abIconSettings" /> </menu>
If you use the attribute abIconSettings you will see the icon on Android 3.x and above, but on Android 1.6 + 2.x you only see the text instead of the icon.
SimonVT has made a fix for ABS 4.x to display the theme icons correctly on Android 2.x !
I’ve ported this fix to the 3.5.1 release of the ActionBarSherlock.
Open abs_attrs.xml in res/values folder and add this lines:
<!-- Base attributes that are available to all groups. --> <declare-styleable name="SherlockMenuGroup"> <!-- The ID of the group. --> <attr name="android:id" /> <!-- The category applied to all items within this group. (This will be or'ed with the orderInCategory attribute.) --> <attr name="android:menuCategory" /> <!-- The order within the category applied to all items within this group. (This will be or'ed with the category attribute.) --> <attr name="android:orderInCategory" /> <!-- Whether the items are capable of displaying a check mark. --> <attr name="android:checkableBehavior" /> <!-- Whether the items are shown/visible. --> <attr name="android:visible" /> <!-- Whether the items are enabled. --> <attr name="android:enabled" /> </declare-styleable> <!-- Base attributes that are available to all Item objects. --> <declare-styleable name="SherlockMenuItem"> <!-- The ID of the item. --> <attr name="android:id" /> <!-- The category applied to the item. (This will be or'ed with the orderInCategory attribute.) --> <attr name="android:menuCategory" /> <!-- The order within the category applied to the item. (This will be or'ed with the category attribute.) --> <attr name="android:orderInCategory" /> <!-- The title associated with the item. --> <attr name="android:title" /> <!-- The condensed title associated with the item. This is used in situations where the normal title may be too long to be displayed. --> <attr name="android:titleCondensed" /> <!-- The icon associated with this item. This icon will not always be shown, so the title should be sufficient in describing this item. --> <attr name="android:icon" /> <!-- The alphabetic shortcut key. This is the shortcut when using a keyboard with alphabetic keys. --> <attr name="android:alphabeticShortcut" /> <!-- The numeric shortcut key. This is the shortcut when using a numeric (e.g., 12-key) keyboard. --> <attr name="android:numericShortcut" /> <!-- Whether the item is capable of displaying a check mark. --> <attr name="android:checkable" /> <!-- Whether the item is checked. Note that you must first have enabled checking with the checkable attribute or else the check mark will not appear. --> <attr name="android:checked" /> <!-- Whether the item is shown/visible. --> <attr name="android:visible" /> <!-- Whether the item is enabled. --> <attr name="android:enabled" /> <!-- Name of a method on the Context used to inflate the menu that will be called when the item is clicked. --> <attr name="android:onClick" /> <!-- How this item should display in the Action Bar, if present. --> <attr name="android:showAsAction" /> <!-- An optional layout to be used as an action view. See {@link android.view.MenuItem#setActionView(android.view.View)} for more info. --> <attr name="android:actionLayout" /> <!-- The name of an optional View class to instantiate and use as an action view. See {@link android.view.MenuItem#setActionView(android.view.View)} for more info. --> <attr name="android:actionViewClass" /> </declare-styleable>
Open MenuInflaterImpl.java in src/com.actionbarsherlock.internal.view.menu and replace the method readGroup() with this lines:
/** * Called when the parser is pointing to a group tag. */ public void readGroup(AttributeSet attrs) { TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.SherlockMenuGroup); groupId = a.getResourceId(R.styleable.SherlockMenuGroup_android_id, defaultGroupId); groupCategory = a.getInt(R.styleable.SherlockMenuGroup_android_menuCategory, defaultItemCategory); groupOrder = a.getInt(R.styleable.SherlockMenuGroup_android_orderInCategory, defaultItemOrder); groupCheckable = a.getInt(R.styleable.SherlockMenuGroup_android_checkableBehavior, defaultItemCheckable); groupVisible = a.getBoolean(R.styleable.SherlockMenuGroup_android_visible, defaultItemVisible); groupEnabled = a.getBoolean(R.styleable.SherlockMenuGroup_android_enabled, defaultItemEnabled); a.recycle(); }
The last step is to replace the method readItem() with this lines:
/** * Called when the parser is pointing to an item tag. */ public void readItem(AttributeSet attrs) { TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.SherlockMenuItem); // Inherit attributes from the group as default value itemId = a.getResourceId(R.styleable.SherlockMenuItem_android_id, defaultItemId); final int category = a.getInt(R.styleable.SherlockMenuItem_android_menuCategory, groupCategory); final int order = a.getInt(R.styleable.SherlockMenuItem_android_orderInCategory, groupOrder); itemCategoryOrder = (category & Menu.CATEGORY_MASK) | (order & Menu.USER_MASK); itemTitle = a.getString(R.styleable.SherlockMenuItem_android_title); itemTitleCondensed = a.getString(R.styleable.SherlockMenuItem_android_titleCondensed); itemIconResId = a.getResourceId(R.styleable.SherlockMenuItem_android_icon, 0); itemAlphabeticShortcut = getShortcut(a.getString(R.styleable.SherlockMenuItem_android_alphabeticShortcut)); itemNumericShortcut = getShortcut(a.getString(R.styleable.SherlockMenuItem_android_numericShortcut)); if (a.hasValue(R.styleable.SherlockMenuItem_android_checkable)) { itemCheckable = a.getBoolean(R.styleable.SherlockMenuItem_android_checkable, false) ? 1 : 0; } else { // Item does not have attribute, use the group's (group can have one more state // for checkable that represents the exclusive checkable) itemCheckable = groupCheckable; } itemChecked = a.getBoolean(R.styleable.SherlockMenuItem_android_checked, defaultItemChecked); itemVisible = a.getBoolean(R.styleable.SherlockMenuItem_android_visible, groupVisible); itemEnabled = a.getBoolean(R.styleable.SherlockMenuItem_android_enabled, groupEnabled); itemShowAsAction = a.getInt(R.styleable.SherlockMenuItem_android_showAsAction, -1); itemListenerMethodName = a.getString(R.styleable.SherlockMenuItem_android_onClick); itemActionViewLayout = a.getResourceId(R.styleable.SherlockMenuItem_android_actionLayout, 0); itemActionViewClassName = a.getString(R.styleable.SherlockMenuItem_android_actionViewClass); a.recycle(); itemAdded = false; }
All credits goes to SimonVT who added this fix for ABS 4.x!
Here is the original Google Groups thread:
https://groups.google.com/forum/?fromgroups&hl=de#!topic/actionbarsherlock/hL4w26bIXyg%5B1-25%5D