本篇文章主要内容来自于Android Doc,我翻译之后又做了些加工,英文好的朋友也可以直接去读原文。
http://developer.android.com/guide/topics/ui/actionbar.html
Action Bar是一种新増的导航栏功能,在Android 3.0之后加入到系统的API当中,它标识了用户当前操作界面的位置,并提供了额外的用户动作、界面导航等功能。使用ActionBar的好处是,它可以给提供一种全局统一的UI界面,使得用户在使用任何一款软件时都懂得该如何操作,并且ActionBar还可以自动适应各种不同大小的屏幕。下面是一张使用ActionBar的界面截图:
其中,[1]是ActionBar的图标,[2]是两个action按钮,[3]是overflow按钮。
由于Action Bar是在3.0以后的版本中加入的,如果想在2.x的版本里使用ActionBar的话则需要引入Support Library,不过3.0之前版本的市场占有率已经非常小了,这里简单起见我们就不再考虑去做向下兼容,而是只考虑4.0以上版本的用法。
添加和移除Action Bar
ActionBar的添加非常简单,只需要在AndroidManifest.xml中指定Application或Activity的theme是Theme.Holo或其子类就可以了,而使用Eclipse创建的项目自动就会将Application的theme指定成Theme.Holo,所以ActionBar默认都是显示出来的。新建一个空项目并运行,效果如下图所示:
而如果想要移除ActionBar的话通常有两种方式,一是将theme指定成Theme.Holo.NoActionBar,表示使用一个不包含ActionBar的主题,二是在Activity中调用以下方法:
ActionBar actionBar = getActionBar(); actionBar.hide();
现在重新运行一下程序,就可以看到ActionBar不再显示了,如下图所示:
修改Action Bar的图标和标题
<activity android:name="com.example.actionbartest.MainActivity" android:logo="@drawable/weather" > </activity>
<activity android:name="com.example.actionbartest.MainActivity" android:label="天气" android:logo="@drawable/weather" > </activity>
添加Action按钮
<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/action_compose" android:icon="@drawable/ic_action_compose" android:showAsAction="always" android:title="@string/action_compose"/> <item android:id="@+id/action_delete" android:icon="@drawable/ic_action_delete" android:showAsAction="always" android:title="@string/action_delete"/> <item android:id="@+id/action_settings" android:icon="@drawable/ic_launcher" android:showAsAction="never" android:title="@string/action_settings"/> </menu>
@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.main, menu); return super.onCreateOptionsMenu(menu); }
- 当ActionBar中的剩余空间不足的时候,如果Action按钮指定的showAsAction属性是ifRoom的话,该Action按钮就会出现在overflow当中,此时就只有title能够显示了。
- 如果Action按钮在ActionBar中显示,用户可能通过长按该Action按钮的方式来查看到title的内容。
响应Action按钮的点击事件
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_compose: Toast.makeText(this, "Compose", Toast.LENGTH_SHORT).show(); return true; case R.id.action_delete: Toast.makeText(this, "Delete", Toast.LENGTH_SHORT).show(); return true; case R.id.action_settings: Toast.makeText(this, "Settings", Toast.LENGTH_SHORT).show(); return true; default: return super.onOptionsItemSelected(item); } }
通过Action Bar图标进行导航
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setTitle("天气"); setContentView(R.layout.activity_main); ActionBar actionBar = getActionBar(); actionBar.setDisplayHomeAsUpEnabled(true); }
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: finish(); return true; …… } }
<activity android:name="com.example.actionbartest.MainActivity" android:logo="@drawable/weather" > <meta-data android:name="android.support.PARENT_ACTIVITY" android:value="com.example.actionbartest.LaunchActivity" /> </activity>
可以看到,这里通过meta-data标签指定了MainActivity的父Activity是LaunchActivity,在Android 4.1版本之后,也可以直接使用android:parentActivityName这个属性来进行指定,如下所示:
<activity android:name="com.example.actionbartest.MainActivity" android:logo="@drawable/weather" android:parentActivityName="com.example.actionbartest.LaunchActivity" > </activity>
第三步则需要对android.R.id.home这个事件进行一些特殊处理,如下所示:
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: Intent upIntent = NavUtils.getParentActivityIntent(this); if (NavUtils.shouldUpRecreateTask(this, upIntent)) { TaskStackBuilder.create(this) .addNextIntentWithParentStack(upIntent) .startActivities(); } else { upIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); NavUtils.navigateUpTo(this, upIntent); } return true; ...... } }
添加Action View
<menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/action_search" android:icon="@drawable/ic_action_search" android:actionViewClass="android.widget.SearchView" android:showAsAction="ifRoom|collapseActionView" android:title="@string/action_search" /> ...... </menu>
@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.main, menu); MenuItem searchItem = menu.findItem(R.id.action_search); SearchView searchView = (SearchView) searchItem.getActionView(); // 配置SearchView的属性 ...... return super.onCreateOptionsMenu(menu); }
@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.main, menu); MenuItem searchItem = menu.findItem(R.id.action_search); searchItem.setOnActionExpandListener(new OnActionExpandListener() { @Override public boolean onMenuItemActionExpand(MenuItem item) { Log.d("TAG", "on expand"); return true; } @Override public boolean onMenuItemActionCollapse(MenuItem item) { Log.d("TAG", "on collapse"); return true; } }); return super.onCreateOptionsMenu(menu); }
Overflow按钮不显示的情况
@Override protected void onCreate(Bundle savedInstanceState) { ...... setOverflowShowingAlways(); } private void setOverflowShowingAlways() { try { ViewConfiguration config = ViewConfiguration.get(this); Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey"); menuKeyField.setAccessible(true); menuKeyField.setBoolean(config, false); } catch (Exception e) { e.printStackTrace(); } }
让Overflow中的选项显示图标
@Override public boolean onMenuOpened(int featureId, Menu menu) { if (featureId == Window.FEATURE_ACTION_BAR && menu != null) { if (menu.getClass().getSimpleName().equals("MenuBuilder")) { try { Method m = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE); m.setAccessible(true); m.invoke(menu, true); } catch (Exception e) { } } } return super.onMenuOpened(featureId, menu); }