Actionbar
请尊重他人的劳动成果,转载请注明出处: 详解Android中的ActionBar的使用
http://blog.csdn.net/fengyuzhengfan/article/details/40216389
ActionBar 是 Android 3.0(API level 11) 引入的一个新控件,它代表了应用程序标题栏,如果要开发兼容的程序,可以使用 v7 包下的ActionBar 。我们在应用中看见的 ActionBar 一般是下图的样子,比如有道词典及微信:

1.App icon: 应用的图标,左侧图标说明可以触摸返回,相当于触摸 back 返回键
2.ViewControl: 下拉列表导航
3.Action button: 相当于普通的 Button 可以监听点击事件
4.Action overflow: 三个点,相当于手机上的 menu 键,可以显示隐藏的 action button 。
使用 ActionBar 一个最大好处是应用可以根据设备显示空间动态调整,如果显示空间不够,应用把多出的 Action Button 添加到 Action overflow 区域。
如何在应用中添加 ActionBar
1 、在应用中添加 ActionBar ,一般我们要继承 ActionBarActivity:
public classMainActivity extends ActionBarActivity{ //……. }
也可以直接继承 Activity ,但是为了向后兼容,最好继承ActionBarActivity( 注意这个类是兼容包 v7 中定义的 )
2 、在 res/menu/ 目录中创建 ActionBar 的 Item ,如下:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.jph.ab.MainActivity">
<item
android:id="@+id/refresh"
android:orderInCategory="100"
android:title="/刷新"
android:icon="@drawable/ic_navigation_refresh"
app:showAsAction="always"/>
<item
android:id="@+id/cancle"
android:orderInCategory="100"
android:title="取消"
android:icon="@drawable/ic_navigation_cancel"
app:showAsAction="always"/>
<item
android:id="@+id/setting"
android:orderInCategory="100"
android:title="设置"
android:icon="@drawable/ic_action_settings"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/cancle2"
android:orderInCategory="100"
android:title="删除"
android:icon="@drawable/ic_cab_done_holo"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/play"
android:orderInCategory="100"
android:title="播放"
android:icon="@drawable/ic_media_play"
app:showAsAction="never"/>
</menu>
Menu 标签中 Item 标签的主要属性:
|
属性名 |
解释 |
|
android:orderInCategory |
表示每个 item 的优先级,值越大优先级越低, actionbar 地方不够就会放到 overflow 中。 |
|
android:title |
item 的标题。 |
|
android:icon |
item 显示的图标。 |
|
app:showAsAction |
item 显示的方式。 |
其 showAsAction 属性接受如下一些值:
|
ifRoom |
会显示在 Item 中,但是如果已经有 4 个或者 4 个以上的 Item 时会隐藏在溢出列表中。当然个数并不仅仅局限于 4 个,依据屏幕的宽窄而定 |
|
never |
永远不会显示。只会在溢出列表中显示,而且只显示标题,所以在定义 item 的时候,最好把标题都带上。 |
|
always |
无论是否溢出,总会显示。 |
|
withText |
withText 值示意 Action bar 要显示文本标题。 Action bar 会尽可能的显示这个标题,但是,如果图标有效并且受到 Action bar 空间的限制,文本标题有可能显示不全。 |
|
collapseActionView |
声明了这个操作视窗应该被折叠到一个按钮中,当用户选择这个按钮时,这个操作视窗展开。否则,这个操作视窗在默认的情况下是不可见的。一般要配合 ifRoom一起使用才会有效果。 |
提示: 为了兼容低版本,这里没有使用 android:showAsAction 而是使用的 v7 兼容包中的 app:showAsAction 。使用app:showAsAction 需要将 xmlns:app =http://schemas.android.com/apk/res-auto 命名空间导进来。
3 、重写 ActionBarActivity 中的方式:
@Override
public booleanonCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to theaction bar if it is present.
getMenuInflater().inflate(R.menu.simple, menu);//获取menu目录下simple.xml的菜单文件
return true;
}
这时 ActionBar 的 Item 在应用中就能够显示了,如果要让触摸Item 添加功能,必须重写进行第 4 步
4 、监听触摸 Item 事件
@Override
public booleanonOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case R.id.refresh:
Utils.showToast(this, "您点击了刷新菜单", Toast.LENGTH_SHORT);
return true;
case R.id.cancle:
Utils.showToast(this, "您点击了取消菜单", Toast.LENGTH_SHORT);
return true;
case R.id.cancle2:
Utils.showToast(this, "您点击了删除菜单", Toast.LENGTH_SHORT);
return true;
case R.id.setting:
Utils.showToast(this, "您点击了设置菜单", Toast.LENGTH_SHORT);
return true;
case R.id.play:
Utils.showToast(this, "您点击了播放菜单", Toast.LENGTH_SHORT);
return true;
}
return super.onOptionsItemSelected(item);
}
程序运行效果图:

为 ActionBar 配置返回键
在 AndroidManifest.xml 中为需要返回到上一级的 activity 配置android:parentActivityName = ".MainActivity" 属性。其中parentActivityName 表示当前 activity 要返回到 activity 。
<activity android:name=".SpinnerActionBar"
android:parentActivityName=".MainActivity"
android:label="ActionBar实现下拉导航"></activity>
程序运行效果图:

显示溢出区按钮
如果手机有 menu 键 ActionBar 可能不会显示三个点的溢出按钮,触摸菜单键才会显示 ActionBar overflow 区域,这样用户体验不一致,为了能够让有菜单键的设备,也能够显示溢出按钮,则需要加入以下代码:
/**
* 即使有物理菜单键也显示ActionBar的flowMenu
*/
public static void showOverflowMenu(Context context) {
try {
ViewConfiguration config = ViewConfiguration.get(context);
//使用java反射技术,获取getDeclaredField类的私有属性sHasPermanentMenuKey
Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
if(menuKeyField != null){
menuKeyField.setAccessible(true); //将属性设为可访问的
menuKeyField.setBoolean(config, false); //为属性赋值为false
}
} catch (Exception e) {
e.printStackTrace();
}
}
然后,在 onCreate 中调用这个函数,这样有菜单键的设备就能显示溢出按钮了。
ActionBar 实现下拉导航
具体步骤:
l 首先需要一个 SpinnerAdapter 设置下拉 item 的内容和显示的layout
l 实现 ActionBar.OnNavigationListener 这个接口,接口中有点击item 的事件
l 设置 navigationmode 例如
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
l 用 setListNavigationCallbacks() 方法来实现下拉选项,例如
actionBar.setListNavigationCallbacks(mSpinnerAdapter,mNavigationCallback);
程序代码:
package com.jph.ab.activity;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBar.OnNavigationListener;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.Toast;
import com.jph.ab.utils.Utils;
/**
* ActionBar实现下拉导航
* @author jph
* Date:2014.10.13
*/
public class SpinnerActionBar extends ActionBarActivity {
private ActionBar actionbar;
/**菜单名称***/
private String[] menuItems;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Utils.showOverflowMenu(this);//如果手机有menu键也显示flowMenu
actionbar=getSupportActionBar();//获取v7兼容包中的ActionBar
actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
menuItems=getResources().getStringArray(R.array.menus);//获取string_array.xml中的menus数组
ArrayAdapter<String> adapter=new ArrayAdapter<String>(this,
R.layout.spinner,R.id.tvMenu,menuItems );
actionbar.setListNavigationCallbacks(adapter, new OnNavigationListener() {
@Override
public boolean onNavigationItemSelected(int itemPosition, long itemId) {
// TODO Auto-generated method stub
Utils.showToast(SpinnerActionBar.this,"您选择了:"+ menuItems[itemPosition],Toast.LENGTH_SHORT);
return true;
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.simple, menu);//获取menu目录下simple.xml的菜单文件
return true;
}
@Override
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.refresh:
Utils.showToast(this, "您点击了刷新菜单", Toast.LENGTH_SHORT);
return true;
case R.id.cancle:
Utils.showToast(this, "您点击了取消菜单", Toast.LENGTH_SHORT);
return true;
case R.id.cancle2:
Utils.showToast(this, "您点击了删除菜单", Toast.LENGTH_SHORT);
return true;
case R.id.setting:
Utils.showToast(this, "您点击了设置菜单", Toast.LENGTH_SHORT);
return true;
case R.id.play:
Utils.showToast(this, "您点击了播放菜单", Toast.LENGTH_SHORT);
return true;
}
return super.onOptionsItemSelected(item);
}
}
程序运行效果图:

ActionBar 实现 Tab 导航
package com.jph.ab.activity;
import java.util.ArrayList;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBar.Tab;
import android.support.v7.app.ActionBar.TabListener;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.jph.ab.fragment.BaseFragment;
import com.jph.ab.fragment.BaseFragmentPagerAdapter;
import com.jph.ab.utils.Utils;
/**
* ActionBar实现Tab导航
* 程序亮点:ActionBar Tab+ViewPager+Fragment
* @author jph
* Date:2014.10.13
*/
public class TabActionBar extends ActionBarActivity {
private ActionBar actionbar;
private ViewPager vpContent;
/**ViewPager包含的Fragment集合**/
private ArrayList<Fragment> fragments;
/**ActionBar上的Tab集合**/
private ArrayList<Tab> tabs;
/**当前页**/
protected int currentPage;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.tab_actionbar);
Utils.showOverflowMenu(this);//如果手机有menu键也显示flowMenu
initViewPager();//初始化ViewPager要在初始化initTab之前,否则会出错
initTab();
}
/**
* 初始化Tab
*/
private void initTab() {
// TODO Auto-generated method stub
tabs=new ArrayList<Tab>();
actionbar=getSupportActionBar();//获取v7兼容包中的ActionBar
actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
Tab tabMyContacts=actionbar.newTab();//创建一个tab实例
Tab tabMyFavorite=actionbar.newTab();
tabMyContacts.setTag(0);//为Tab设置Tag,用于标识Tab的位置
tabMyContacts.setText("全部联系人");
tabMyFavorite.setTag(1);
tabMyFavorite.setText("常用联系人");
tabMyContacts.setTabListener(tabListener);//为Tab设置监听(这一步是必须的,不然系统会不报错)
tabMyFavorite.setTabListener(tabListener);
tabs.add(tabMyContacts);
tabs.add(tabMyFavorite);
actionbar.addTab(tabMyContacts);//将Tab添加ActionBar上
actionbar.addTab(tabMyFavorite);
}
/**
* 初始化ViewPager
*/
private void initViewPager() {
// TODO Auto-generated method stub
vpContent=(ViewPager)findViewById(R.id.vpContent);
//初始化ViewPager显示的页面集合
fragments = new ArrayList<Fragment>();
BaseFragment fragment1=BaseFragment.newInstance(BaseFragment.LOAD_FRAGMENT_1);
BaseFragment fragment2=BaseFragment.newInstance(BaseFragment.LOAD_FRAGMENT_2);
fragments.add(fragment1);
fragments.add(fragment2);
//设置ViewPager adapter
BaseFragmentPagerAdapter adapter=new BaseFragmentPagerAdapter(getSupportFragmentManager(), fragments);
vpContent.setAdapter(adapter);
vpContent.setCurrentItem(0);//默认显示第一个页面
//监听ViewPager事件
vpContent.setOnPageChangeListener(new OnPageChangeListener(){
@Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
currentPage = position;
actionbar.selectTab(tabs.get(position));//当滑动页面结束让ActionBar选择指定的Tab
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.simple, menu);//获取menu目录下simple.xml的菜单文件
return true;
}
@Override
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