/*******************************************************************************
* Copyright 2012-present Pixate, Inc.
*
* 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.pixate.freestyle.styling.virtualAdapters;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.view.ViewGroup;
import com.pixate.freestyle.styling.PXRuleSet;
import com.pixate.freestyle.styling.adapters.PXTabViewStyleAdapter;
import com.pixate.freestyle.styling.cache.PXStyleInfo;
import com.pixate.freestyle.styling.stylers.PXStylerContext;
import com.pixate.freestyle.util.PXDrawableUtil;
import com.pixate.freestyle.util.PXLog;
/**
* Virtual adapter for {@link ActionBar} {@link Tab} icons.
*
* <pre>
* <code>
* - icon
* </code>
* </pre>
*
* For example, styling the nth tab can be done like that:
*
* <pre>
* action-bar action-bar-tab:nth-child(n) icon {
* background-image: url(tab1.svg);
* }
*
* action-bar action-bar-tab:nth-child(n + 1) icon {
* background-image: url(tab2.svg);
* }
*
* action-bar action-bar-tab:nth-child(n + 2) icon {
* background-image: url(tab3.svg);
* }
* </pre>
*
* TODO - add an example with states
*
* @author Shalom Gibly
*/
public class PXVirtualActionBarTabIconAdapter extends PXVirtualChildAdapter {
private static String ELEMENT_NAME = "icon";
private static PXVirtualActionBarTabIconAdapter instance;
/**
* Returns a singleton instance of this class.
*
* @return An instance of {@link PXVirtualActionBarTabIconAdapter}
*/
public static PXVirtualActionBarTabIconAdapter getInstance() {
synchronized (PXVirtualActionBarTabIconAdapter.class) {
if (instance == null) {
instance = new PXVirtualActionBarTabIconAdapter();
}
}
return instance;
}
@Override
public List<String> getSupportedPseudoClasses(Object styleable) {
return new ArrayList<String>(PXDrawableUtil.getSupportedStates().keySet());
}
/*
* (non-Javadoc)
* @see
* com.pixate.freestyle.styling.adapters.PXStyleAdapter#getDefaultPseudoClass
* (java.lang.Object)
*/
@Override
public String getDefaultPseudoClass(Object styleable) {
return PXStyleInfo.DEFAULT_STYLE;
}
/*
* (non-Javadoc)
* @see
* com.pixate.freestyle.styling.adapters.PXViewStyleAdapter#getElementName
* (java.lang.Object)
*/
@Override
public String getElementName(Object object) {
return ELEMENT_NAME;
}
@Override
public boolean updateStyle(List<PXRuleSet> ruleSets, List<PXStylerContext> contexts) {
if (!super.updateStyle(ruleSets, contexts)) {
return false;
}
// Extract the ActionBar's TabView we are styling.
View tabView = (View) contexts.get(0).getStyleable();
// Use the 'setIcon' on the TabView's assigned tab. To get to this tab,
// we need reflection.
try {
Method getTabMethod = tabView.getClass().getMethod("getTab", (Class<?>[]) null);
getTabMethod.setAccessible(true);
Tab tab = (Tab) getTabMethod.invoke(tabView, (Object[]) null);
if (tab != null) {
// Grab the existing icon. In case it's a StatesListDrawable
// we'll append to it.
Map<int[], Drawable> existingStates = PXDrawableUtil.getExistingStates(tab
.getIcon());
if (existingStates == null || existingStates.isEmpty()) {
Drawable drawable = PXDrawableUtil.createNewDrawable(
PXTabViewStyleAdapter.getInstance(), ruleSets, contexts);
if (drawable != null) {
tab.setIcon(drawable);
}
} else {
tab.setIcon(PXDrawableUtil.createDrawable(PXTabViewStyleAdapter.getInstance(),
existingStates, ruleSets, contexts));
}
// Adding an icon is actually adding an ImageView child to the
// TabView. We have to set the selection state for this
// ImageView, otherwise it will not display any existing
// selection icon in case the tab is selected.
// To make sure we get the child, no matter what is the order,
// we traverse all direct children and set their selection
// state.
ViewGroup tabsGroup = ((ViewGroup) tabView);
for (int i = 0; i < tabsGroup.getChildCount(); i++) {
tabsGroup.getChildAt(i).setSelected(tabView.isSelected());
}
}
} catch (Exception e) {
if (PXLog.isLogging()) {
PXLog.w(getClass().getSimpleName(), e, "Error setting the ActionBar's Tab icon");
}
}
return true;
}
}