您的位置:首页 > 移动开发 > Android开发

Android Support V7 包中 ActionBar的使用

2015-12-14 15:19 585 查看



Action Bar取代了传统的tittle bar和menu,在程序运行中一直置于顶部,对于Android平板设备来说屏幕更大它的标题使用Action Bar来设计可以展示更多丰富的内容,方便操控。





<1> ActionBar的图标,可显示软件图标,也可用其他图标代替。当软件不在最高级页面时,图标左侧会显示一个左箭头,用户可以通过这个箭头向上导航;

<2> 如果你的应用要在不同的View中显示数据,这部分允许用户来切换视图。一般的作法是用一个下拉菜单或者是Tab选项卡。如果只有一个界面,那这里可以显示应用程序的标题或者是更长一点的商标信息;

<3> 两个action按钮,这里放重要的按钮功能,为用户进行某项操作提供直接的访问;

<4> overflow按钮,放不下的按钮会被置于“更多...”菜单项中,“更多...”菜单项是以下拉形式实现的。

1、添加ActionBar

ActionBar的添加非常简单,只需要在AndroidManifest.xml中指定Application或Activity的theme是Theme.Holo或其子类就可以了,在Android 3.0及更高的版本中,Activity中都默认包含有ActionBar组件。

2、取消ActionBar

  如果需要隐藏Action Bar可以在你的Activity的属性中设置主题风格为NoTitleBar在你的manifest文件中

<activity android:theme="@android:style/Theme.NoTitleBar">


还有一种做法,在运行时调用hide()方法也可以隐藏ActionBar,调用show()方法来显示ActionBar()。

ActionBar actionBar = getActionBar();
actionBar.hide();


当你隐藏ActionBar时,系统会将Activity的整个内容充满整个空间。

3.通过Action Bar图标进行导航

启用ActionBar图标导航的功能,可以允许用户根据当前应用的位置来在不同界面之间切换。比如,A界面展示了一个列表,点击某一项之后进入了B界面,这时B界面就应该启用ActionBar图标导航功能,这样就可以回到A界面。

我们可以通过调用setDisplayHomeAsUpEnabled()方法来启用ActionBar图标导航功能,比如:

setTitle("Yanis");
setContentView(R.layout.activity_main);
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);


现在运行一下程序,结果如下图所示:



可以看到,在ActionBar图标的左侧出现了一个向左的箭头,通常情况下这都表示返回的意思,因此最简单的实现就是在它的点击事件里面加入finish()方法就可以了,如下所示:

switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
...
}


当点击ActionBar图标的时候,系统同样会调用onOptionsItemSelected()方法,并且此时的itemId是android.R.id.home,所以finish()方法也就是加在这里的了。

4.Overflow按钮不显示的情况

虽然现在我们已经掌握了不少ActionBar的用法,但是当你真正去使用它的时候还是可能会遇到各种各样的问题,比如很多人都会碰到overflow按钮不显示的情况。明明是同样的一份代码,overflow按钮在有些手机上会显示,而在有些手机上偏偏就不显示,如下图:



可以看到,ActionBar最右边的overflow按钮不见,按一下Menu键,隐藏在overflow中的Action按钮就会从底部出来。

有人总结了一下,overflow按钮的显示情况和手机的硬件情况是有关系的,如果手机没有物理Menu键的话,overflow按钮就可以显示,如果有物理Menu键的话,overflow按钮就不会显示出来。比如我们启动一个有Menu键的模拟器,然后将代码运行到该模拟器上

实际上,在ViewConfiguration这个类中有一个叫做sHasPermanentMenuKey的静态变量,系统就是根据这个变量的值来判断手机有没有物理Menu键的。当然这是一个内部变量,我们无法直接访问它,但是可以通过反射的方式修改它的值,让它永远为false就可以了,代码如下所示:

@Override
public void onStart() {
......
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();
}
}


这里我们在onCreate()方法的最后调用了setOverflowShowingAlways()方法,而这个方法的内部就是使用反射的方式将sHasPermanentMenuKey的值设置成false,现在重新运行一下代码,结果如下图所示:



5.让Overflow中的选项显示图标

如果你点击一下overflow按钮去查看隐藏的Action按钮,你会发现这部分Action按钮都是只显示文字不显示图标的,如下图所示:



这是官方的默认效果,Google认为隐藏在overflow中的Action按钮都应该只显示文字。当然,如果你认为这样不够美观,希望在overflow中的Action按钮也可以显示图标,我们仍然可以想办法来改变这一默认行为。
其实,overflow中的Action按钮应不应该显示图标,是由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);
}


可以看到,这里我们重写了一个onMenuOpened()方法,当overflow被展开的时候就会回调这个方法,接着在这个方法的内部通过返回反射的方法将MenuBuilder的setOptionalIconsVisible变量设置为true就可以了。

[title3]
6. 自定义背景[/title3]

如果想要修改ActionBar的背景,我们可以通过创建一个自定义主题并重写actionBarStyle属性来实现。这个属性可以指向另外一个样式,然后我们在这个样式中重写background这个属性就可以指定一个drawable资源或颜色,从而实现自定义背景的功能。
编辑styles.xml文件,在里面加入一个自定义的主题,如下所示:

<resources>

<style name="CustomActionBarTheme" parent="@android:style/Theme.Holo.Light">
<item name="android:actionBarStyle">@style/MyActionBar</item>
</style>

<style name="MyActionBar" parent="@android:style/Widget.Holo.Light.ActionBar">
<item name="android:background">#f4842d</item>
</style>

</resources>

可以看到,这里我们定义了一个CustomActionBarTheme主题,并让它继承自Theme.Holo.Light。然后在其内部重写了actionBarStyle这个属性,然后将这个属性指向了MyActionBar这个样式,我们在这个样式中又重写了background属性,并给它指定了一个背景色。

现在整个ActionBar的颜色是属于偏暗系的,而ActionBar中文字的颜色又偏偏是黑色的,所以看起来并不舒服,那么接下来我们就学习一下如果自定义文字颜色,将文字颜色改成白色。
修改styles.xml文件,如下所示:

<resources>

......

<style name="MyActionBar" parent="@android:style/Widget.Holo.Light.ActionBar">
......
<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>

</resources>


可以看到,这里在MyActionBar样式里面重写了titleTextStyle属性,并将它指向了另一个自定义样式MyActionBarTitleText,接着我们在这个样式中指定textColor的颜色是#fff,也就是白色。

[title3]
7. 强制隐藏或显示Actionbar上图标[/title3]

隐藏图标:
if (android.os.Build.VERSION.SDK_INT >=  11) {
ActionBar actionBar = this.getActionBar();
if(actionBar!=null)
actionBar.setDisplayShowHomeEnabled(false);
}

显示图标:

if (android.os.Build.VERSION.SDK_INT >=  11) {
ActionBar actionBar = this.getActionBar();
if(actionBar!=null)
actionBar.setDisplayShowHomeEnabled(true);
}



<style name="UserHomeAppTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">
<item name="actionBarStyle">@style/ActionBarStyle</item>
<!-- ActionBar高度 -->
<item name="actionBarSize">50dp</item>
<!-- 去除ActionBar底部阴影效果 -->
<item name="android:windowContentOverlay">@null</item>
</style>

<style name="ActionBarStyle" parent="@style/Widget.AppCompat.Light.ActionBar.Solid">
<item name="titleTextStyle">@style/TitleTextStyle</item>
<!-- ActionBar背景 -->
<item name="background">@drawable/ic_actionbar_bg</item>
</style>
<!-- ActionBar字体 -->
<style name="TitleTextStyle" parent="@style/TextAppearance.AppCompat.Widget.ActionBar.Title">
<item name="android:textSize">18sp</item>
</style>



1.
导入Support V7的包.更新SDK 18以后,会发现在 \android-sdk\extras\android\support\v7目录下有三个子文件夹,分别是:appcompat\gridlayout\mediarouter,工作中比较常用的是appcompat,所以今天也只看了这个目录下的android-support-v7-appcompat.jar.把这个文件导入到工程中.

  2.在manifest文件中,为你使用了ActionBar的actitity添加theme属性,这个theme必须是 @style/Theme.AppCompat ,@style/Theme.AppCompat.Light.,@style/Theme.AppCompat.Light.DarkActionBar,三种中的一种,我偷懒了,直接在application节点中加了theme.

  3.在res/menu目录下,写一个xml文件。官方推荐每一个item项都要有icon和title图标,因为系统默认显示的是图标,而且当屏幕空间不够的时候,未显示的菜单就会隐藏到列表中,而列表中只能显示title字段的值。

  html代码

  android:id="@+id/action_search"

  android:icon="@drawable/left"

  android:title="search"/>

  android:id="@+id/action_compose"

  android:icon="@drawable/right"

  android:title="compose"/>

复制代码
    4.实现Activity,让它继承ActionBarActivity.在onCreateOptionsMenu()方法中,获取到每一个MenuItem,之后为每一个MenuItem调用MenuItemCompat.setShowAsAction(MenuItem
item, int actionEnum)方法,就可以将菜单项变为ActionBar中的子项了.

  actionEnum的值有以下几种:

  MenuItemCompat.SHOW_AS_ACTION_ALWAYS (始终显示)

  MenuItemCompat.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW (隐藏列表中显示)

  MenuItemCompat.SHOW_AS_ACTION_IF_ROOM (屏幕有空间就显示,没空间就隐藏)

  MenuItemCompat.SHOW_AS_ACTION_NEVER (永不显示)

  MenuItemCompat.SHOW_AS_ACTION_WITH_TEXT (既显示图标又显示文字)

  最后 在方法中要 return true

  java代码

@Override

  public boolean onCreateOptionsMenu(Menu menu) {

  MenuInflater menuInflater = getMenuInflater();

  menuInflater.inflate(R.menu.main, menu);

  MenuItem menuItem = menu.findItem(R.id.action_search);

  MenuItem findItem = menu.findItem(R.id.action_compose);

  MenuItemCompat.setShowAsAction(menuItem,

MenuItemCompat.SHOW_AS_ACTION_ALWAYS);

  MenuItemCompat.setShowAsAction(findItem,

MenuItemCompat.SHOW_AS_ACTION_WITH_TEXT);

  return true;

  }

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: