一:把ActionBar放在底部:在manifest里注册activity时加入 android:uiOptions="splitActionBarWhenNarrow" 就行,如下图。
<activity
android:name="com.example.actionbar.MainActivity"
android:label="@string/app_name"
android:uiOptions="splitActionBarWhenNarrow" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
二:由于ActionBar主要放在是menu构成,当menu比较多时,横竖屏显示的menu数量不一致(在不同屏幕的手机上显示的也不一样),这样容易影响体验。这是因为当menu较多而屏幕不够宽时,android会把一部分的menu显隐交给menu键(android上的实体键)控制,点击menu键隐藏的menu就会显示,当没有menu键时就会把所有的menu全部显示出来,所以解决这个问题的思路是让程序认为没有menu键 让其无论在什么时候显示的数量都一样。但这是一个内部变量,我们无法直接访问他,
但是可以通过反射的方式修改它的值,让它永远为false就可以了。
代码如下(在onCreate()里调用):
- 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 当menu较多时 会把其他的menu放在最后按钮中 点击按钮剩余的menu就会显示。但显示的只有文字 ,这是Google官方默认效果,如果还要显示按钮 那么 那么。。 其实按钮显示与否
是由MenuBuilder这个类的setOptionalIconsVisible方法来决定的,如果我们在overflow被展开的时候给这个方法传入true,那么里面的每一个Action按钮对应的图标就都会显示出来了。调用的方法当然仍然是用反射了 代码如下:
- @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);
- }
当然这里只是使overflow可以显示图片,具体要显示什么图片还得依靠代码来设置
MenuItem save1 = menu.add(0, 0, 0, "save2");
save1.setIcon(R.drawable.abc_ab_bottom_transparent_light_holo);
如图:
四:ActionProvider
和Action View有点类似,Action Provider也可以将一个Action按钮替换成一个自定义的布局。但不同的是,Action Provider能够完全控制事件的所有行为,并且还可以在点击的时候显示子菜单。
为了实现这一功能,需要再item标签中指定一个actionViewClass属性,在里面填入完整的ActionProvider类名,可以自己定义,也可以引用系统的provider,比如shareActionProvider。
由于每个Action Provider都可以自由地控制事件响应,所以它们不需要在onOptionsItemSelected()方法中再去监听点击事件,而是应该在onPerformDefaultAction()方法中去执行相应的逻辑。
部分代码如下:
- <item
- android:id="@+id/action_share"
- android:actionProviderClass="android.widget.ShareActionProvider"
- android:showAsAction="ifRoom"
- android:title="@string/action_share" />
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- MenuInflater inflater = getMenuInflater();
- inflater.inflate(R.menu.main, menu);
- MenuItem shareItem = menu.findItem(R.id.action_share);
- ShareActionProvider provider = (ShareActionProvider) shareItem.getActionProvider();
- provider.setShareIntent(getDefaultIntent());
- ......
- return super.onCreateOptionsMenu(menu);
- }
自定义provider 写一个provider继承ActionProvider 重写里面的方法 如图:
这个监听可以放在调用这个provider的Activity的onOptionsItemSelected 通过判断id就可以去响应点击事件。
五:
自定义ActionBar去控制APP导航行为
ActionBar提供了两种自定义行为,分别是导航Tabs和下拉列表。(每次只能用一种)
①,导航TABS 使用
setNavigationMode方法 指定ActionBar.NAVIGATION_MODE_TABS 如图:
Tab的转换是由TabListener来操控的,当tab被选择、未选择、重新选择时,允许你创建Fragment事务作为回应。
② 下拉列表
像上面一样 先指定ActionBar的navigation 为
ActionBar.NAVIGATION_MODE_LIST,这其实就是一个Adapter+点击事件。
六:自定义ActionBar
actionBar.setDisplayShowCustomEnabled(true);
actionBar.setCustomView(R.layout.my_custom_navigation);//layout里就是自定义的ActionBar 但是 如果activity的icon和title没有隐藏的话 他们会在 自定的view的前面显示。 而且ActionBar的点击事件 要
actionBar.setCustomView(R.layout.my_custom_navigation);//layout里就是自定义的ActionBar 但是 如果activity的icon和title没有隐藏的话 他们会在 自定的view的前面显示。 而且ActionBar的点击事件 要
才能被捕捉到 然后在ActionBar的layout里添加
android:onClick="onClick" 其他部分就和普通的点击没有区别了。
七:要点
①,menu中使用“withText ”属性不一定有文字显示 因为 The "withText" value is a hint to the action bar that the text title should appear. The action bar will show the title when possible, but
might not if an icon is available and the action bar is constrained for space.
②,应为每一个menu设置title属性