ActionBar是Android3.0的重要更新之一。归纳起来,ActionBar提供了如下功能
1.显示选项菜单的菜单项(将菜单显示为Action Item)
2.使用程序图标作为返回home主屏或向上的导航操作。
3.提供交互式View作为Action View。
4.提供基于Tab的导航方式,可用于切换多个Fragment。
5.提供基于下拉的导航方式。
启用ActionBar
最新的And容地版本已经默认启用了ActionBar,因此只需要在AndroidManifest.xml文件的sdk配置中指定该应用的目标版本高于11,默认就会启用ActionBar。如果希望关闭ActionBar,则可设置应用主题为xxx.NoActionBar。在实际项目中,通常推荐使用代码来控制ActionBar的显示和隐藏。
ActionBar actionBar;
actionBar = getActionBar();
actionBar.show();
actionBar.hide();
修改默认的ActionBar标题
默认情况下,系统会使用应用程序默认的icon来作为ActionBar的图标。我们可以在AndroidManifest中对其进行修改。
使用ActionBar显示选项菜单
目前,Android不再强制要求手机提供menu键,提供ActionBar作为解决方案,ActionBar可以将选项菜单显示成Action Item。从Android3.0开始,MenuItem新增如下方法
setShowAsAction(int actionEnum):该方法设置是否将该菜单项显示在ActionBar上作为Action Item
该方法支持如下参数:
SHOW_AS_ACTION_ALWAYS: 总是将MenuItem显示在ActionBar上面
SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW:将ActionView折叠成普通菜单项。
SHOW_AS_ACTION_IF_ROOM:当ActionBar位置足够时才显示MenuItem
SHOW_AS_ACTION_NEVER:不将该MenuItem显示在ActionBar上面
SHOW_AS_ACTION_WITH_TEXT:将该MenuItem显示在ActionBar上,并显示菜单项的文本。
实际项目中推荐使用xml资源文件来定义菜单,因此Android允许在xml菜单资源文件中为<item .../>指定如下属性
android:showAsAction:其作用类似于setShowAsAction,所以也支持类似上面的属性值。
定义menu资源文件
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.example.actionbartest.MainActivity" >
<item
android:id="@+id/football"
android:icon="@drawable/football"
android:title="@string/strFootball"
android:showAsAction="ifRoom|withText"
/>
<item
android:id="@+id/basketball"
android:icon="@drawable/basketball"
android:title="@string/strBasketball"
android:showAsAction="ifRoom|withText"
/>
<item
android:id="@+id/volleyball"
android:icon="@drawable/volleyball"
android:title="@string/strVolleyball"
android:showAsAction="ifRoom|withText"
/>
<item
android:id="@+id/badmintonball"
android:icon="@drawable/badminton"
android:title="@string/strBadminton"
android:showAsAction="ifRoom|withText"
/>
</menu>
可以看出来,ActionBar上的按钮默认情况下只显示图标,不显示文字,title的内容默认只在overflow中显示,那为什么在ActionBar中显示的图标定义title呢?
1.在空间不足的情况下,overflow中要显示的是title
2.如果按钮在ActionBar中,通过长按该按钮会提示该按钮的title
Overflow
同一份代码,在某些手机上会显示overflow,有些手机就不会显示overflow。这是什么原因呢?由于现在android设备不强制要求menu键,在有menu键的手机上就不会显示overflow,点击menu键就会显示那些原本在overflow中的选项,而没有menu键的手机都是会显示overflow的。我们可以通过设置来改变这种情况。
public void setOverflowShowingAlways(){
try {
ViewConfiguration config = ViewConfiguration.get(this);
Field menukeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
menukeyField.setAccessible(true);
menukeyField.setBoolean(config, false);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
在onCreate函数中加入setOverFlowShowingAlways就可以屏蔽物理menu键(如果有的话),总是显示overflow。sHasPermanentMenuKey是一个ViewConfig类的一个静态变量,系统就是通过这个变量来判断设备是否存在menu键。
通过ActionBar进行图标导航
通过图片可以看出,ActionBar图标有一个向左的箭头,默认情况是没有这个箭头的,这就是图标导航,简单来说,其作用就是返回上一个Activity。我们可以通过调用setDisplayHomeAsUpEnable()来启用图标导航
public class MainActivity extends Activity implements ActionBar.TabListener{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar actionBar;
actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
}
图标导航的id为android.R.id.home。
响应ActionBar的点击事件
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
switch (id) {
case R.id.football:
Toast.makeText(this, "football", Toast.LENGTH_SHORT).show();
break;
case R.id.badmintonball:
Toast.makeText(this, "badminton", Toast.LENGTH_SHORT).show();
break;
case R.id.basketball:
Toast.makeText(this, "basketball", Toast.LENGTH_SHORT).show();
break;
case R.id.volleyball:
Toast.makeText(this, "volleyball", Toast.LENGTH_SHORT).show();
break;
case android.R.id.home:
Toast.makeText(this, "home", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
添加ActionView
ActionView是在ActionBar中替换按钮的控件.它允许用户在不切换界面的情况下实现一些功能。以控件searchView为例,介绍一下。
可以看到搜索图标了。
添加Tabs导航
在onCreate中加入
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionBar.addTab(actionBar.newTab().setText("第一页").setTabListener(this));
actionBar.addTab(actionBar.newTab().setText("第二页").setTabListener(this));
actionBar.addTab(actionBar.newTab().setText("第三页").setTabListener(this));
这只是实现了Tab页,我们可以通过自定义ActionBar的style来定制符合需求的ActionBar
<style name="MyActionBarTheme" parent="android:Theme.Holo.Light">
<item name="android:actionBarStyle">@style/MyActionBar</item>
<item name="android:actionBarTabTextStyle">@style/MyActionBarTabText</item>
<item name="android:actionBarTabStyle">@style/MyActionBarTabs</item>
</style>
<style name="MyActionBar" parent="@android:style/Widget.Holo.Light.ActionBar">
<item name="android:background">#f4842d</item>
<item name="android:backgroundStacked">#d27026</item>
<item name="android:titleTextStyle">@style/MyActionBarTitleText</item>
</style>
<style name="MyActionBarTitleText" parent="@android:style/TextAppearance.Holo.Widget.ActionBar.Title">
<item name="android:textColor">#fff</item>
</style>
<style name="MyActionBarTabText" parent="@android:style/Widget.Holo.ActionBar.TabText">
<item name="android:textColor">#fff</item>
</style>
<style name="MyActionBarTabs" parent="@android:style/Widget.Holo.ActionBar.TabView">
<item name="android:background">@drawable/tab_indicator</item>
</style>
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:state_selected="false"
android:state_pressed="false"
android:drawable="@drawable/unpressed"
/>
<item
android:state_selected="true"
android:state_pressed="false"
android:drawable="@drawable/pressed"
/>
<item
android:state_selected="false"
android:state_pressed="true"
android:drawable="@drawable/selected"
/>
<item
android:state_selected="true"
android:state_pressed="true"
android:drawable="@drawable/pressed"
/>
</selector>