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
