Android AppCompat v21 Theme

本文作为读书笔记的总结性内容,起因是29日看到某社交网站谷歌的Matias Duarte分享一个链接,点进去发现是blogspot更新了,于是借此机会做一个总结,所以本文内容目前是基于19月28日信息,11月3日后根据更详细的信息进行进一步修正。

—-正文的分割线—–

本文描述基于Android 5.0 Lollipop的主题以及围绕新Material Design设计规范在交互与界面上的实现问题,并且是基于Support v7 AppCompat v21类库,其最主要的目的是将新特性与交互方式兼容到4.x版本。
本文的参考主要来源于:

Android 开发者网站 Android Developer

Android 开发者博客 Android Developer blogspot

引用原文与细节将在引用位置提供链接或在结尾进行详细说明。

首先在官方Maintaining Compatibility的描述为使用Support v7 r21类库可以实现一些Material design style。其主要包含:

  1. 提供一个类似于5.0的Material design风格的界面。通过Theme.AppCompat主题实现。
  2. 调色板应用,Color Palette。体现在主题是可以根据给定的色彩统一渲染控件,达到界面显示效果统一。
  3. 提供RecyclerView,由于其内部实现了LayoutManager,所以可以实现更多变的布局与动画。
  4. 提供CardView,主要提供类似于Android 5.0的Z轴阴影效果,也表明卡片元素在新的设计规范中的重要性。
  5. Palette,在代码中的效果就是通过Palette工具可是提取主题色用于界面动态渲染(这属于界面Material动画的关键,其后进行详细说明)。

Widget渲染

界面控件渲染截止到14年10月29日支持EditText、Spinner、CheckBox、RadioButton、SwitchCompat、CheckedTextView,通过实际测试可知依旧有许多控件未完全兼容,甚至包括Dialog依旧使用系统默认风格。同时Google Design网站关于设计的细节依旧没有明确的说明,其自家应用也是每个都一个样,文档也一直处于预览版状态,希望伴随着11月3日Android 5.0 的发布,相关文档与设计规范能够跟进。

对Android 5.0新特性的支持

对于Android 5.0非常令人兴奋的功能,也没有进行完整的兼容,如Touch feedback,scene transitions animation。控件方面,Floating Action Button也没有提供。根据开发者关系小组博客上的反馈信息,这些已经列上了日程,希望在Android 5.0正式发布后会进行支持。

接下来从代码角度说明对Material主题样式的兼容。首先和兼容Actionbar一样,依赖AppCompat v21项目并使所有Activity继承ActionBarActivity,使用Theme.AppCompat.xx一系列主题,即可在视觉上达到与Android 5.0相似的效果。

《AppCompat v21 - Material Design for Pre-Lollipop Devices!》中对此有比较详细的描述,关于使用中的问题可以前往Android 开发者关系小组成员的博客进行咨询。
文章《Implementing material design in your Android app》则对主题的定制,和基于Material Design的界面设计和动画效果进行了讲解。
而昨天发布的《Material Design on Android Checklist》则使用实例的方式讲解了Google Design中的一些要点规范以及如何实现。

对于Android 5.0非常重要的ActionBar在新规范中使用了support v7 Toolbar进行替代。其目的是将ActionBar的布局位置转移到开发者自己定制的Layout中,可以达到在Activity中将ActionBar作为一个部分进行控制,在界面上实现与ActionBar联动的交互操作和整个Activity范围的动画效果。

此时的ActionBar的实现方式为 layout.xml:

1
2
3
4
5
6
<android.support.v7.widget.ToolBar
      android:id="@+id/toolbar"
      android:layout_height="wrap_content"
      android:layout_width="match_parent"
      android:minHeight="?attr/actionBarSize"
      android:background="?attr/colorPrimary"/>

通过可以使用theme单独对其进行定制,同样在全局theme中可使用actionBarStyle属性。values/theme.xml

1
2
3
4
5
6
7
8
<style name="Theme.MyTheme" parent="Theme.AppCompat.Light">
<!-- Set AppCompat’s actionBarStyle -->
<item name="actionBarStyle">@style/MyActionBarStyle</item>
<!-- Set AppCompat’s color theming attrs -->
<item name="colorPrimary">@color/my_awesome_red</item>
<item name="colorPrimaryDark">@color/my_awesome_darker_red</item>
<!-- The rest of your attributes -->
</style>

MainActivity.java

1
2
3
4
5
6
7
8
@Override 
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
   
    ToolBar toolbar = (Toolbar)findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
}

代码中在setContentView之后使用setSupportActionBar将Toolbar设置为ActionBar,之后即可像普通的ActionBar那样使用,当然获得ActionBar依旧使用getSupportActionBar的方式。API同样遵循ActionBar的规范。根据官方的说明实现类似于平板和网页版的multiple toolnars,也就轻而易举了。当然Toolbar比较合适的用法是单独的layout文件,并通过inlcude标签引入到具体界面上,当然Toolbar也可以直接使用。

关于此时ToolBar的定制,可以使用之前定制ActionBar的方法,如果直接写在ToolBar便签中则需要support库的namespace,即重新定义自动引用auto-resource,如前缀为app,则使用app:theme=”@style/ThemeOverlay.AppCompat.Dark.ActionBar”同样popupMenu使用ThemeOverlay.AppCompat.Light。直接使用android命名空间是无效的。同样在主Theme样式文件中自定义继承的主题也需要AppCompat类型,而不是系统默认的主题类型。同时需要注意的是AppCompat同样依赖于Support v4,并且要保持版本为最新。

关于主题调色板应用

在继承Theme.AppCompat.xx等一些列主题后对全局控件样式,即对色彩的修改也集中于此。之前的主题如Holo大部分使用9-path类型填充,但是将反馈效果放在图片中实现,而现在的色彩可以根据Theme的配置自行进行绘制,这样就保持了界面样式的统一性,同时对自定义样式的总体搭配减少了很多麻烦。

在继承Theme.AppCompat主题之后最为醒目的是新样式的ActionBar,目前谷歌提倡大胆用色,色彩要鲜明等。关于选色可参考Google Design文档中色彩的章节。

在主题设置中有以下几个属性需要关注(注意前缀):

  1. name=”colorPrimary”
  2. name=”colorPrimaryDark”
  3. name=”android:textColorPrimary”
  4. name=”colorAccent”
  5. name=”colorControlNormal
  6. name=”colorControlActivated”
  7. name=”colorControlHighlight”
  8. name=”colorSwitchThumbNormal”
  9. name=”android:windowBackground”
  10. name=”android:navigationBarColor” API V21

如上图:

colorPrimary:可以理解为你的APP的主题色或者主色调,默认情况下体现为ActionBar的背景色。

colorPrimaryDark:为系统状态栏背景色,这个颜色比primary要深一些,则个方法在4.4.2以及一下版本没有意义,但是状态栏也就是status bar的颜色在4.4可以通过类似于hack的方式在代码中实现,当然也包括colorNavigationBarColor的颜色。同样的colorPrimary可以在toolbar中通过设置背景色来实现。

textColorPrimary:实际上为Actionbar中的文本颜色。

colorAccent:为控件的选中颜色,即checked或selected状态的颜色。

colorControlNormal:为控件预设的颜色,相当与之前定义xml Drawable中Selector的Normal状态的颜色。

colorControlActivated:即激活状态,按照源代码仅有即几行解释应该是属于accent的一部分如checked状态(需要实际测试一下)。

colorControlHighlight:为选择高亮,如ripples,列表的selector。

colorSwitchThumbNormal:是指switch控件的色彩了。

windowBackground:这是指窗口容器的背景色,也就是layout文件在没有额外设置颜色的时候默认的颜色,个人觉得这个颜色非常重要,他影响到你几乎每个界面。

android:navigationBarColor:为底部虚拟按键。此属性需要API v21。

控件的调色属性,我目前仅仅使用了CheckBox类控件,感觉和主题配合起来效果非常好,其他几个属性经过测试之后再进行完善。更多属性可参考appcompat/res/values/attrs.xml文件。

对于高级的调色板应用

使用support v4 graphics类库提供的Palette工具。android.support.v7.graphics.Palette。其可以根据给定的图片按抽取颜色,抽取的颜色分为一下几类。

Vibrant: 充满活力

Vibrant dark: 充满活力的暗色

Vibrant light: 充满活力的亮色

Muted: 柔和

Muted dark: 柔和的暗色

Muted light: 柔和的亮色

按照官方的例子,根据图片获得Palette.Swatch对象,其提供给控件渲染颜色的方法,达到界面根据图片进行适应,但是在实际使用环境中,其提供的颜色究竟能达到什么效果,这个真的不好说。

关于动画

非常遗憾,谷歌宣传的各种看似非常华丽的动画在低于API v21上无法实现,至少在目前的support是无法实现。如Activity的转场动画,如各类进入和退出的explode,slide,fade动画,布局转换图像转场等。

而SharedElements类动画使用过度元素的思想,利用兼容低版本的ActivityOptions工具虽然编译上没有问题,但是经过在4.x版本(具体版本忘记了)测试发现并没有出现期待的效果,同样Multiple Shared Elements一样。兼容库在低版本上是否真的支持,还要进行进一步测试和仔细看官方文档才能确定。

但是对最令人印象深刻的触摸反馈功能没有支持倒是令人非常失望,尤其是Ripple相关,虽然一些第三方类库也可以实现这些效果,但是使用起来较为复杂,有些还破坏已有布局,感觉得不偿失。

关于谷歌的设计,关注的都知道,可以遵循,但是不能完全去遵循(笑)。