package com.actionbarsherlock.internal.widget;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.support.v4.app.ActionBar;
import android.support.v4.view.Menu;
import android.support.v4.view.Window;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.Spinner;
import android.widget.SpinnerAdapter;
import android.widget.TextView;
import com.actionbarsherlock.internal.view.menu.ActionMenuItem;
import com.actionbarsherlock.internal.view.menu.ActionMenuPresenter;
import com.actionbarsherlock.internal.view.menu.ActionMenuView;
import com.actionbarsherlock.internal.view.menu.MenuBuilder;
import com.actionbarsherlock.internal.view.menu.MenuPresenter;
import mobisocial.musubi.R;
public final class ActionBarView extends RelativeLayout {
/** Default display options if none are defined in the theme. */
private static final int DEFAULT_DISPLAY_OPTIONS = ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_HOME;
/** Default navigation mode if one is not defined in the theme. */
private static final int DEFAULT_NAVIGATION_MODE = ActionBar.NAVIGATION_MODE_STANDARD;
private final Context mContext;
private final View mHomeAsUpView;
private final ViewGroup mHomeLayout;
private final ActionMenuItem mLogoNavItem;
private final CharSequence mTitle;
private final TextView mTitleLayout;
private final CharSequence mSubtitle;
private final TextView mSubtitleLayout;
/** Indeterminate progress bar. */
private final ProgressBar mIndeterminateProgress;
private boolean mAllowsIndeterminateProgress = false;
/** List view. */
private final Spinner mSpinner;
private SpinnerAdapter mSpinnerAdapter;
private final AdapterView.OnItemSelectedListener mNavItemSelectedListener;
private ActionBar.OnNavigationListener mCallback;
/** Custom view parent. */
private final FrameLayout mCustomView;
private View mCustomNavView;
private ImageView mIconView;
private Drawable mLogo;
private Drawable mIcon;
/** Container for action item view. */
private final FrameLayout mActionsView;
private MenuBuilder mOptionsMenu;
private ActionMenuView mMenuView;
private ActionMenuPresenter mActionMenuPresenter;
/** Container for all tab items. */
private final LinearLayout mTabsView;
private final ViewGroup mTabViewContainer;
/**
* Display state flags.
*
* @see #getDisplayOptions()
* @see #getDisplayOptionValue(int)
* @see #setDisplayOptions(int)
* @see #setDisplayOptions(int, int)
* @see #setDisplayOption(int, boolean)
* @see #reloadDisplay()
*/
private int mDisplayOptions;
/**
* Current navigation mode
*
* @see #getNavigationMode()
* @see #setNavigationMode(int)
*/
private int mNavigationMode = -1;
private boolean mIsConstructing;
public ActionBarView(Context context) {
this(context, null);
}
public ActionBarView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ActionBarView(final Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mContext = context;
mIsConstructing = true;
LayoutInflater.from(context).inflate(R.layout.abs__action_bar, this, true);
mNavItemSelectedListener = new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
if (mCallback != null) {
mCallback.onNavigationItemSelected(arg2, arg3);
}
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
//No op
}
};
setBackgroundResource(0);
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SherlockTheme, defStyle, 0);
final ApplicationInfo appInfo = context.getApplicationInfo();
final PackageManager pm = context.getPackageManager();
//// TITLE ////
mTitleLayout = (TextView)findViewById(R.id.abs__action_bar_title);
//Try to load title style from the theme
final int titleTextStyle = a.getResourceId(R.styleable.SherlockTheme_abTitleTextStyle, 0);
if (titleTextStyle != 0) {
mTitleLayout.setTextAppearance(context, titleTextStyle);
}
//Try to load title from the theme
mTitle = a.getString(R.styleable.SherlockTheme_abTitle);
if (mTitle != null) {
setTitle(mTitle);
}
//// SUBTITLE ////
mSubtitleLayout = (TextView)findViewById(R.id.abs__action_bar_subtitle);
//Try to load subtitle style from the theme
final int subtitleTextStyle = a.getResourceId(R.styleable.SherlockTheme_abSubtitleTextStyle, 0);
if (subtitleTextStyle != 0) {
mSubtitleLayout.setTextAppearance(context, subtitleTextStyle);
}
//Try to load subtitle from theme
mSubtitle = a.getString(R.styleable.SherlockTheme_abSubtitle);
if (mSubtitle != null) {
setSubtitle(mSubtitle);
}
/// HOME ////
mHomeLayout = (ViewGroup)findViewById(R.id.abs__home_wrapper);
final int homeLayoutResource = a.getResourceId(R.styleable.SherlockTheme_abHomeLayout, R.layout.abs__action_bar_home);
LayoutInflater.from(context).inflate(homeLayoutResource, mHomeLayout, true);
//Try to load the logo from the theme
mLogo = a.getDrawable(R.styleable.SherlockTheme_abLogo);
/*
if ((mLogo == null) && (context instanceof Activity)) {
//LOGO LOADING DOES NOT WORK
//SEE: http://stackoverflow.com/questions/6105504/load-activity-and-or-application-logo-programmatically-from-manifest
//SEE: https://groups.google.com/forum/#!topic/android-developers/UFR4l0ZwJWc
}
*/
//Try to load the icon from the theme
mIcon = a.getDrawable(R.styleable.SherlockTheme_abIcon);
if ((mIcon == null) && (context instanceof Activity)) {
mIcon = appInfo.loadIcon(pm);
}
mHomeAsUpView = findViewById(R.id.abs__up);
mIconView = (ImageView)findViewById(R.id.abs__home);
//// NAVIGATION ////
mSpinner = (Spinner)findViewById(R.id.abs__nav_list);
mSpinner.setOnItemSelectedListener(mNavItemSelectedListener);
mTabsView = (LinearLayout)findViewById(R.id.abs__nav_tabs);
mTabViewContainer = (ViewGroup)findViewById(R.id.abs__nav_tabs_layout);
//// CUSTOM VIEW ////
mCustomView = (FrameLayout)findViewById(R.id.abs__custom);
//Try to load a custom view from the theme. This will NOT automatically
//trigger the visibility of the custom layout, however.
final int customViewResourceId = a.getResourceId(R.styleable.SherlockTheme_abCustomNavigationLayout, 0);
if (customViewResourceId != 0) {
mCustomNavView = LayoutInflater.from(context).inflate(customViewResourceId, mCustomView, true);
mNavigationMode = ActionBar.NAVIGATION_MODE_STANDARD;
setDisplayOptions(mDisplayOptions | ActionBar.DISPLAY_SHOW_CUSTOM);
}
mActionsView = (FrameLayout)findViewById(R.id.abs__actions);
mIndeterminateProgress = (ProgressBar)findViewById(R.id.abs__iprogress);
//Try to get the display options defined in the theme, or fall back to
//displaying the title and home icon
setDisplayOptions(a.getInteger(R.styleable.SherlockTheme_abDisplayOptions, DEFAULT_DISPLAY_OPTIONS));
//Try to get the navigation defined in the theme, or, fall back to
//use standard navigation by default
setNavigationMode(a.getInteger(R.styleable.SherlockTheme_abNavigationMode, DEFAULT_NAVIGATION_MODE));
//Reduce, Reuse, Recycle!
a.recycle();
mIsConstructing = false;
mLogoNavItem = new ActionMenuItem(context, 0, android.R.id.home, 0, 0, mTitle);
mHomeLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (context instanceof Activity) {
((Activity)context).onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, mLogoNavItem);
}
}
});
mHomeLayout.setClickable(true);
mHomeLayout.setFocusable(true);
reloadDisplay();
}
// ------------------------------------------------------------------------
// HELPER METHODS
// ------------------------------------------------------------------------
/**
* Helper to get a boolean value for a specific flag.
*
* @param flag Target flag.
* @return Value.
*/
private boolean getDisplayOptionValue(int flag) {
return (mDisplayOptions & flag) == flag;
}
/**
* Reload the current action bar display state.
*/
private void reloadDisplay() {
if (mIsConstructing) {
return; //Do not run if we are in the constructor
}
final boolean isStandard = mNavigationMode == ActionBar.NAVIGATION_MODE_STANDARD;
final boolean isList = mNavigationMode == ActionBar.NAVIGATION_MODE_LIST;
final boolean isTab = mNavigationMode == ActionBar.NAVIGATION_MODE_TABS;
final boolean isTabUnderAb = isTab && getContext().getString(R.string.abs__tab_under_ab_tag).equals(mTabsView.getTag());
final boolean hasSubtitle = (mSubtitleLayout.getText() != null) && !mSubtitleLayout.getText().equals("");
final boolean displayHome = getDisplayOptionValue(ActionBar.DISPLAY_SHOW_HOME);
final boolean displayHomeAsUp = getDisplayOptionValue(ActionBar.DISPLAY_HOME_AS_UP);
final boolean displayTitle = getDisplayOptionValue(ActionBar.DISPLAY_SHOW_TITLE);
final boolean displayCustom = getDisplayOptionValue(ActionBar.DISPLAY_SHOW_CUSTOM);
final boolean displayLogo = getDisplayOptionValue(ActionBar.DISPLAY_USE_LOGO) && (mLogo != null);
mHomeLayout.setVisibility(displayHome ? View.VISIBLE : View.GONE);
if (displayHome) {
if (mHomeAsUpView != null) {
mHomeAsUpView.setVisibility(displayHomeAsUp ? View.VISIBLE : View.GONE);
}
if (mIconView != null) {
mIconView.setImageDrawable(displayLogo ? mLogo : mIcon);
}
}
//Only show list if we are in list navigation and there are list items
mSpinner.setVisibility(isList ? View.VISIBLE : View.GONE);
// Show tabs if in tabs navigation mode.
mTabsView.setVisibility(isTab ? View.VISIBLE : View.GONE);
if (mTabViewContainer != null) {
mTabViewContainer.setVisibility(isTab ? View.VISIBLE : View.GONE);
}
//Show title view if we are not in list navigation, not showing custom
//view, and the show title flag is true
mTitleLayout.setVisibility((isStandard || isTabUnderAb) && !displayCustom && displayTitle ? View.VISIBLE : View.GONE);
//Show subtitle view if we are not in list navigation, not showing
//custom view, show title flag is true, and a subtitle is set
mSubtitleLayout.setVisibility((isStandard || isTabUnderAb) && !displayCustom && displayTitle && hasSubtitle ? View.VISIBLE : View.GONE);
//Show custom view if we are not in list navigation and showing custom
//flag is set
mCustomView.setVisibility(isStandard && displayCustom ? View.VISIBLE : View.GONE);
}
public void initIndeterminateProgress() {
mAllowsIndeterminateProgress = true;
}
public void setMenu(Menu menu, MenuPresenter.Callback cb) {
if (menu == mOptionsMenu) return;
if (mOptionsMenu != null) {
mOptionsMenu.removeMenuPresenter(mActionMenuPresenter);
}
MenuBuilder builder = (MenuBuilder) menu;
mOptionsMenu = builder;
if (mMenuView != null) {
final ViewGroup oldParent = (ViewGroup) mMenuView.getParent();
if (oldParent != null) {
oldParent.removeView(mMenuView);
}
}
if (mActionMenuPresenter == null) {
mActionMenuPresenter = new ActionMenuPresenter(mContext);
mActionMenuPresenter.setCallback(cb);
mActionMenuPresenter.setId(R.id.abs__action_menu_presenter);
}
ActionMenuView menuView;
final LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.FILL_PARENT);
configPresenters(builder);
menuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this);
final ViewGroup oldParent = (ViewGroup) menuView.getParent();
if (oldParent != null && oldParent != this) {
oldParent.removeView(menuView);
}
mActionsView.addView(menuView, layoutParams);
mMenuView = menuView;
}
private void configPresenters(MenuBuilder builder) {
if (builder != null) {
builder.addMenuPresenter(mActionMenuPresenter);
} else {
mActionMenuPresenter.initForMenu(mContext, null);
mActionMenuPresenter.updateMenuView(true);
}
}
// ------------------------------------------------------------------------
// ACTION BAR API
// ------------------------------------------------------------------------
public void addTab(ActionBar.Tab tab) {
final int tabCount = getTabCount();
addTab(tab, tabCount, tabCount == 0);
}
public void addTab(ActionBar.Tab tab, boolean setSelected) {
addTab(tab, getTabCount(), setSelected);
}
public void addTab(ActionBar.Tab tab, int position) {
addTab(tab, position, getTabCount() == 0);
}
public void addTab(ActionBar.Tab tab, int position, boolean setSelected) {
mTabsView.addView(((TabImpl)tab).mView, position);
if (setSelected) {
tab.select();
}
}
public View getCustomView() {
return mCustomNavView;
}
public int getDisplayOptions() {
return mDisplayOptions;
}
public SpinnerAdapter getDropdownAdapter() {
return this.mSpinnerAdapter;
}
public int getDropdownSelectedPosition() {
return this.mSpinner.getSelectedItemPosition();
}
public int getNavigationMode() {
return mNavigationMode;
}
public ActionBar.Tab getSelectedTab() {
final int count = mTabsView.getChildCount();
for (int i = 0; i < count; i++) {
TabImpl tab = (TabImpl)mTabsView.getChildAt(i).getTag();
if (tab.mView.isSelected()) {
return tab;
}
}
return null;
}
public CharSequence getSubtitle() {
if ((mNavigationMode == ActionBar.NAVIGATION_MODE_STANDARD) && !mSubtitleLayout.getText().equals("")) {
return mSubtitleLayout.getText();
} else {
return null;
}
}
public ActionBar.Tab getTabAt(int index) {
View view = mTabsView.getChildAt(index);
return (view != null) ? (TabImpl)view.getTag() : null;
}
public int getTabCount() {
return mTabsView.getChildCount();
}
public CharSequence getTitle() {
if ((mNavigationMode == ActionBar.NAVIGATION_MODE_STANDARD) && !mTitleLayout.getText().equals("")) {
return mTitleLayout.getText();
} else {
return null;
}
}
public TabImpl newTab() {
return new TabImpl(this);
}
public void removeAllTabs() {
TabImpl selected = (TabImpl)getSelectedTab();
if (selected != null) {
selected.unselect();
}
mTabsView.removeAllViews();
}
public void removeTab(ActionBar.Tab tab) {
final int count = mTabsView.getChildCount();
for (int i = 0; i < count; i++) {
TabImpl existingTab = (TabImpl)mTabsView.getChildAt(i).getTag();
if (existingTab.equals(tab)) {
removeTabAt(i);
break;
}
}
}
public void removeTabAt(int position) {
TabImpl tab = (TabImpl)getTabAt(position);
if (tab != null) {
tab.unselect();
mTabsView.removeViewAt(position);
if (position > 0) {
//Select previous tab
((TabImpl)mTabsView.getChildAt(position - 1).getTag()).select();
} else if (mTabsView.getChildCount() > 0) {
//Select first tab
((TabImpl)mTabsView.getChildAt(0).getTag()).select();
}
}
}
public void setCallback(ActionBar.OnNavigationListener callback) {
mCallback = callback;
}
public void setCustomNavigationView(View view) {
mCustomNavView = view;
mCustomView.removeAllViews();
mCustomView.addView(view);
}
public void setDisplayOptions(int options) {
mDisplayOptions = options;
reloadDisplay();
}
public void setDropdownAdapter(SpinnerAdapter spinnerAdapter) {
mSpinnerAdapter = spinnerAdapter;
if (mSpinner != null) {
mSpinner.setAdapter(mSpinnerAdapter);
}
}
public void setDropdownSelectedPosition(int position) {
mSpinner.setSelection(position);
}
public void setProgressBarIndeterminateVisibility(boolean visible) {
if (mAllowsIndeterminateProgress) {
mIndeterminateProgress.setVisibility(visible ? View.VISIBLE : View.GONE);
}
}
public void setNavigationMode(int mode) {
if ((mode != ActionBar.NAVIGATION_MODE_STANDARD) && (mode != ActionBar.NAVIGATION_MODE_LIST)
&& (mode != ActionBar.NAVIGATION_MODE_TABS)) {
throw new IllegalArgumentException("Unknown navigation mode value " + Integer.toString(mode));
}
if (mode != mNavigationMode) {
mNavigationMode = mode;
reloadDisplay();
}
}
public void selectTab(ActionBar.Tab tab) {
final int count = mTabsView.getChildCount();
for (int i = 0; i < count; i++) {
TabImpl existingTab = (TabImpl)mTabsView.getChildAt(i).getTag();
if (existingTab.equals(tab)) {
existingTab.select();
break;
}
}
}
public void setSubtitle(CharSequence subtitle) {
mSubtitleLayout.setText((subtitle == null) ? "" : subtitle);
reloadDisplay();
}
public void setSubtitle(int resId) {
mSubtitleLayout.setText(resId);
reloadDisplay();
}
public void setTitle(CharSequence title) {
mTitleLayout.setText((title == null) ? "" : title);
}
public void setTitle(int resId) {
mTitleLayout.setText(resId);
}
// ------------------------------------------------------------------------
// HELPER INTERFACES AND HELPER CLASSES
// ------------------------------------------------------------------------
private static class TabImpl extends ActionBar.Tab {
private static final View.OnClickListener clickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
((TabImpl)v.getTag()).select();
}
};
final ActionBarView mActionBar;
final View mView;
final ImageView mIconView;
final TextView mTextView;
final FrameLayout mCustomView;
ActionBar.TabListener mListener;
Object mTag;
TabImpl(ActionBarView actionBar) {
mActionBar = actionBar;
mView = LayoutInflater.from(mActionBar.getContext()).inflate(R.layout.abs__action_bar_tab_layout, actionBar.mTabsView, false);
mView.setTag(this);
mView.setOnClickListener(clickListener);
mIconView = (ImageView)mView.findViewById(R.id.abs__tab_icon);
mTextView = (TextView)mView.findViewById(R.id.abs__tab);
mCustomView = (FrameLayout)mView.findViewById(R.id.abs__tab_custom);
}
/**
* Update display to reflect current property state.
*/
void reloadDisplay() {
boolean hasCustom = mCustomView.getChildCount() > 0;
mIconView.setVisibility(hasCustom ? View.GONE : View.VISIBLE);
mTextView.setVisibility(hasCustom ? View.GONE : View.VISIBLE);
mCustomView.setVisibility(hasCustom ? View.VISIBLE : View.GONE);
}
@Override
public View getCustomView() {
return mCustomView.getChildAt(0);
}
@Override
public Drawable getIcon() {
return mIconView.getDrawable();
}
@Override
public int getPosition() {
final int count = mActionBar.mTabsView.getChildCount();
for (int i = 0; i < count; i++) {
if (mActionBar.mTabsView.getChildAt(i).getTag().equals(this)) {
return i;
}
}
return -1;
}
@Override
public ActionBar.TabListener getTabListener() {
return mListener;
}
@Override
public Object getTag() {
return mTag;
}
@Override
public CharSequence getText() {
return mTextView.getText();
}
@Override
public TabImpl setCustomView(int layoutResId) {
mCustomView.removeAllViews();
LayoutInflater.from(mActionBar.getContext()).inflate(layoutResId, mCustomView, true);
reloadDisplay();
return this;
}
@Override
public TabImpl setCustomView(View view) {
mCustomView.removeAllViews();
if (view != null) {
mCustomView.addView(view);
}
reloadDisplay();
return this;
}
@Override
public TabImpl setIcon(Drawable icon) {
mIconView.setImageDrawable(icon);
return this;
}
@Override
public TabImpl setIcon(int resId) {
mIconView.setImageResource(resId);
return this;
}
@Override
public TabImpl setTabListener(ActionBar.TabListener listener) {
mListener = listener;
return this;
}
@Override
public TabImpl setTag(Object obj) {
mTag = obj;
return this;
}
@Override
public TabImpl setText(int resId) {
mTextView.setText(resId);
return this;
}
@Override
public TabImpl setText(CharSequence text) {
mTextView.setText(text);
return this;
}
@Override
public void select() {
if (mView.isSelected()) {
if (mListener != null) {
mListener.onTabReselected(this, null);
}
return;
}
TabImpl current = (TabImpl)mActionBar.getSelectedTab();
if (current != null) {
current.unselect();
}
mView.setSelected(true);
if (mListener != null) {
mListener.onTabSelected(this, null);
}
}
/**
* Unselect this tab. Only valid if the tab has been added to the
* action bar and was previously selected.
*/
void unselect() {
if (mView.isSelected()) {
mView.setSelected(false);
if (mListener != null) {
mListener.onTabUnselected(this, null);
}
}
}
}
}