Android ActionBar自定义

Apple给开发者发了通知:2015年2月1日起,向App Store提交的新app必须支持64位处理器,必须基于iOS8 SDK开发。当然开发者唯一要做的,就是按照Xcode6或更新的版本进行开发,并按照默认配置进行编译。(参考Apple Developer

提这件事的目的是因为这让我想到了Android的碎片化。Android 4.0发布已经过了3年,到现在还在做兼容2.3系统app的还有多少呢?Android开源的特性本应该造就一批热血的极客面对优秀的系统优化和更新的API兴奋不已,但有多少Android开发者只是完成工作,解决bug,费力兼容老版本系统?

Android 5.0已经发布了,5.0又需要多久才能达到60以上的占比?开发者又需要过多久才能把最低版本设置为Android 4.4来支持ART和64位?至少,如果你是个人开发者,希望支持新API和新的系统。
前面是一些废话,今天聊一下ActionBar自定义那点事。Action Bar是在Android 3.0伴随Holo主题引入的,当然Android 3.0夭折以后的Android 4.0才算是Google第一次努力进行设备间的体验同步,Action Bar也是那个时候才开始被开发者广泛使用的吧。

Action Bar默认是Holo样式,并且在开发者网站也没有过多的自定义样式说明(Styling the Action Bar),甚至有些xml属性是ant都不会提示的,所以网上也有很多自定义Action Bar的博客,这里对我用到的一些做出整理和说明。

Kick off!

如果你不知道《那天》是啥,就先看下我之前的一篇文章,这个app的Action Bar基本是按照Material Design的规范设计的,细节尺寸上还是有一些出入,不过不影响整体的样式,下面这张图片是截图:

看起来还不错的吧?首先说明下左边那个Drawer的indicator用的是DrawerArrowDrawable开源项目,感谢作者。不过这个Drawable的使用不影响下文的内容。

先看AppTheme的定义,AppTheme是ant自动生成的一个主题样式,默认Application中的所有Activity都使用这个样式。AppTheme也是Google推荐自定义样式的入口。

<style name="AppTheme" parent="AppBaseTheme">
 <item name="android:actionBarStyle">@style/AppActionBar</item>
 <item name="@android:attr/actionBarSize">@dimen/actionbar_height</item>
 <item name="android:actionOverflowButtonStyle">@style/OverFlow</item>
 <item name="android:homeAsUpIndicator">@null</item>
 <item name="android:selectableItemBackground">@drawable/actionbar_selector</item>
</style>
  • 第一个android:actionBarStyle是对Action Bar的style进行定义,value是一个style资源,后面贴出来细说
  • 第二个@android:attr/actionBarSize是对Action Bar的高度进行定义,”@android:attr/“是为了指向android包定义的attr资源的actionBarSize项。这样引用应该是这个属性没有暴漏在android这个命名空间中吧,有待求证。
  • 第三个android:actionOverflowButtonStyle定义OverFlow按钮的样式,也就是上图最右边三个点的样式。Holo默认是三个方块的,我将其修改成了Material Design中的三个圆点,该样式也在后面贴出。
  • 第四个android:homeAsUpIndicator设置为@null是为了禁用左侧的up按钮,因为需要的效果是使用Home按钮作为Drawer的Indicator,如果不禁用up按钮的话,在Home左侧会出现一个神奇的space。
  • 第五个android:selectableItemBackground设置ActionBar中可点击项的背景,用来更改item按下的效果,上图中右侧的Overflow按钮的背景就是按下的效果。
    虽然只有五个item配置,但是这些配置项都是一般的Android教程不会提到的,但是在实际项目中又很实用。下面分别是AppActionBar和OverFlow的样式:

    <style name=”AppActionBar” parent=”android:Widget.Holo.ActionBar”>
    <item name=”android:titleTextStyle”>@style/GlobalActionBarText</item>
    <item name=”android:icon”>@android:color/transparent</item>
    <item name=”android:background”>@color/global_highlight</item>
    </style>

    这个样式比较简单了,针对Action Bar,配置了三个属性:

  • 第一个android:titleTextStyle,是为了定义标题的文字样式,比较简单,在后面贴出。

  • 第二个android:icon,设置为透明,是因为需要在代码中设置DrawerArrowDrawable。
  • 第三个android:background,当然就是背景颜色了。
    下面是OverFlow样式:
    <style name="OverFlow" parent="@android:style/Widget.Holo.ActionButton.Overflow">
    <item name="android:src">@drawable/ab_overflow_icon</item>
    <item name="android:minWidth">32dp</item>
    </style>
    首先需要注意的是父样式的写法:@android:style/Widget.Holo.ActionButton.Overflow 其次,也是写的时候遇到点小麻烦的地方,就是按钮的宽度,Holo默认的宽度应该是48dp,如果想让其缩小,首先要把素材缩小,随后设置minWidth为你想要的宽度。 下面是GlobalActionBarText样式,也就是修改标题的样式,很简单,就不做详述了。
    <style name="GlobalActionBarText">
    <item name="android:textSize">@dimen/textsize_title</item>
    <item name="android:textStyle">bold</item>
    <item name="android:textColor">@color/text_actionbar</item>
    </style>

Sth. in Code

只在xml中设置属性显然是不够的,下面这个方法,就是在Activity中做的一些操作:

private void initialActionBar() {
ActionBar actionBar = getActionBar();

final Resources resources = getResources();
drawerArrowDrawable = new DrawerArrowDrawable(resources);
drawerArrowDrawable.setStrokeColor(getResources().getColor(R.color.text_actionbar));
actionBar.setIcon(drawerArrowDrawable);

actionBar.setHomeButtonEnabled(true);
actionBar.setDisplayHomeAsUpEnabled(true);

int padding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 20, this.getResources().getDisplayMetrics());
ImageView view = (ImageView) findViewById(android.R.id.home);
view.setPadding(padding * 2, padding, (int) (padding * 1.5), padding);

}

其中的几行代码是对DrawerArrowDrawable的配置,可以忽略。需要注意的是后面对home按钮的padding进行调整的部分,包括如何取到home的view,以及大概的尺寸。

总结

虽然定义的内容不多,但是可以看到即便是这么几项, 需要做的说明也是不少。在baidu上搜到的靠前的资料,甚至还有在layout中自己写ActionBar的。希望这篇文章能给看到的同僚带来帮助,如果你有其他想法,也很欢迎交流。

最后,项目最低支持Android 4.0,API level14。