1、帮助用户知道你现在处于哪个页面
2、为用户提供统一的导航界面
在2.x上使用ActionBar的步骤
1、导入android-support-v7库,这个库其实在你的sdk里面就有(前提是你已经下载下来了),如我的路径:D:\android-sdk-windows\extras\android\support\v7\appcompat
2、创建项目,让我们的库依赖andorid-support-v7,并让需要使用ActionBar的Activity依赖ActionBarActivity,并进行如下配置:
<activity android:theme="@style/Theme.AppCompat.Light" ... >
就这么简单,你的项目就已经引入了ActionBar了,如果你想隐藏ActionBar,如下操作即可
ActionBar actionBar = getSupportActionBar(); actionBar.hide();
这里要提醒一下:由于ActionBar在隐藏的时候会重现绘制Activity的界面,从而填充ActionBar的空白,所以当你频繁的隐藏和显示ActionBar时,会导致Activity的界面频繁重绘,为了避免这种情况发生,你可以再actionBarStyle中将 windowActionBarOverlay这个属性设置为true,也就是说ActionBar会在Activity的上面,隐藏和显示不会影响Activity
我上面引入的ActionBar没有引入任何内容,默认里面就是一个设置项,现在我们就像里面加入自己的item吧
创建res/menu/main_activity_actions.xml文件并加入如下内容,
<menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/action_copy" android:icon="@drawable/copy" android:title="复制"/> <item android:id="@+id/action_cut" android:icon="@drawable/cut" android:title="剪切"/> <item android:id="@+id/action_discard" android:icon="@drawable/discard" android:title="删除"/> <item android:id="@+id/action_edit" android:icon="@drawable/edit" android:title="编辑"/> <item android:id="@+id/action_email" android:icon="@drawable/email" android:title="邮箱"/> </menu>
然后重写下面的方法:
@Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); //返回true才会显示overflow按钮 return true; }
通过以上步骤,我们就已经向ActionBar中加入了5个Item,运行一下看看效果吧,如下图
ActionBar是出来了,但是和我们上面说的ActionBar貌似有些区别,这些item都进入了overflow了,另外就是我明明设置了icon属性,却没有看见icon
对于这两个问题,我们一一解决吧
item默认都是进入Overflow的,如果想有些重要的Item 进入ActionItem 里面,那么需要配置一个属性showAsAction
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:yourapp="http://schemas.android.com/apk/res-auto" > <item android:id="@+id/action_copy" android:icon="@drawable/copy" android:title="复制" yourapp:showAsAction="always" /> ... </menu>
注意这里的showAsActoin命名空间是自定义的,不是"android",因为这个属性在2.x系统中没有,是andorid-support-v7定义的,你运行一下,会发现复制已经到了ActionItem的位置了
第二个问题就是设置了icon为什么没有显示?其实在Actionbar中,处于ActionItem位置的item默认是显示icon而不显示title的,我们可以通过在showAsActoin中配置"always|withText",让Tiele显示出来(但是也不一定会显示,只是尽量显示),而处于Overflow的item 默认是显示title而不显示icon的,这个可以通过反射机制来改变,方案如下:
public void setOverflowIconVisiable(Menu menu) { try { Class clazz=Class.forName("com.android.internal.view.menu.MenuBuilder"); Field field=clazz.getDeclaredField("mOptionalIconsVisible"); if(field!=null) { field.setAccessible(true); field.set(menu , true); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } }然后再onMenuOpened方法中调用
@Override public boolean onMenuOpened(int featureId, Menu menu) { if(featureId == Window.FEATURE_ACTION_BAR && menu != null) { setOverflowIconVisiable(menu); } return super.onMenuOpened(featureId, menu); }
运行效果如下图,可以看到icon已经显示了
目前这些ActionItem和Overflowsitems都是没有响应事件的,现在为他们添加吧,如果以前使用过菜单的同学会觉得和菜单是一样的
@Override public boolean onOptionsItemSelected(MenuItem item) { switch(item.getItemId()) { case R.id.action_copy: Toast.makeText(this, item.getTitle(), 1000).show(); return true; case R.id.action_cut: Toast.makeText(this, item.getTitle(), 1000).show(); return true; case R.id.action_delete: Toast.makeText(this, item.getTitle(), 1000).show(); return true; case R.id.action_edit: Toast.makeText(this, item.getTitle(), 1000).show(); return true; case R.id.action_email: Toast.makeText(this, item.getTitle(), 1000).show(); return true; } return super.onOptionsItemSelected(item); }