ActionBar实际上是用来替换导航菜单的一个选项,主要的作用是:
ok,接下来我们查看源码:
AndroidManifest.xml文件中我们看到设置了application的android:theme="@style/AppTheme",我们去看看style.xml文件(为了快速简单的分析,我们仅针对Android 4.0以上版本的分析,所以这里检查的是values-v13):
<resources>
<style name="ActionBarTitle" parent="android:style/TextAppearance.Holo.Widget.ActionBar.Title">
<!-- 颜色值在colors文件中有配置 -->
<item name="android:textColor">@color/actionbar_title_color</item>
</style>
</resources>
接下来我们看看MainActivity代码,总体上看Activity代码较为简单,主要处理了optionmenu:
public class MainActivity extends ActionBarActivity {
private boolean mAlternateTitle = false;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
findViewById(R.id.toggle_title).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 设置标题文字
if (mAlternateTitle) {
setTitle(R.string.app_name);
} else {
setTitle(R.string.alternate_title);
}
mAlternateTitle = !mAlternateTitle;
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.main, menu);
// Calling super after populating the menu is necessary here to ensure that the
// action bar helpers have a chance to handle this event.
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// 响应按钮点击
switch (item.getItemId()) {
// case android.R.id.home:
// Toast.makeText(this, "Tapped home", Toast.LENGTH_SHORT).show();
// break;
case R.id.menu_refresh:
Toast.makeText(this, "Fake refreshing...", Toast.LENGTH_SHORT).show();
getActionBarHelper().setRefreshActionItemState(true);
getWindow().getDecorView().postDelayed(
new Runnable() {
@Override
public void run() {
getActionBarHelper().setRefreshActionItemState(false);
}
}, 1000);
break;
case R.id.menu_search:
Toast.makeText(this, "Tapped search", Toast.LENGTH_SHORT).show();
break;
// case R.id.menu_share:
// Toast.makeText(this, "Tapped share", Toast.LENGTH_SHORT).show();
// break;
}
return super.onOptionsItemSelected(item);
}
}
public abstract 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);
}
}
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) {
// 如果Build的SDK版本>=14,也就是我们正在分析的。
return new ActionBarHelperICS(activity);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
// 如果Build的SDK版本在[11,14)之间
return new ActionBarHelperHoneycomb(activity);
} else {
// 其余SDK版本
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 <em>menu</em> 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;
}
}
public class ActionBarHelperICS extends ActionBarHelperHoneycomb {
protected ActionBarHelperICS(Activity activity) {
super(activity);
}
@Override
protected Context getActionBarThemedContext() {
return mActivity.getActionBar().getThemedContext();
}
}
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;
}
}
public class SimpleMenu implements Menu {
private Context mContext;
private Resources mResources;
private ArrayList<SimpleMenuItem> mItems;
public SimpleMenu(Context context) {
mContext = context;
mResources = context.getResources();
mItems = new ArrayList<SimpleMenuItem>();
}
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<? extends MenuItem> 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");
}
}
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;
}
}
参考资料:http://blog.csdn.net/aomandeshangxiao/article/details/7674904