随着 Android 5.0 Lollipop SDK 的发布, 谷歌还同时升级了 AppCompat support 库,最新的 21 版本中添加了对 Toolbar 和纸墨设计主题的支持。
下面来介绍下如何使用 V21 版本的 AppCompat 库。
Read more: http://blog.chengyunfeng.com/?p=626#ixzz3XpNZoL8S
设置
如果您使用的是 Gradle 来 build 应用, 在 build.gradle 文件中添加如下内容:
dependencies {
compile "com.android.support:appcompat-v7:21.0.+"
}
如果已经有了 appcompat 的定义,只需要修改版本号为即可。
如果你使用的是 Eclipse, 则只需要把 sdk_home\extras\android\support\v7\appcompat 目录作为项目导入到 eclipse , 在你的项目中引用该库项目即可。
从头开始
如果你的应用之前没有使用 Appcompat, 则需要按照如下步骤来集成:
- 所有的 Activity 都需要继承至 ActionBarActivity ,这个类继承至 support v4 包中的 FragmentActivity 。所以你还可以继续使用 Fragment。
- 所有需要使用 ActionBar 或者 Toolbar 的主题(themes)都需要继承至Theme.AppCompat 主题,该主题还有一些不同的风格,比如 Light 和 NoActionBar 等。
- 当需要在 ActionBar 上显示的控件,需要使用 ActionBar 的主题(getSupportActionBar().getThemedContext())。例如 列表导航使用的 SpinnerAdapter 。
- MenuItem 上的所有和 action 相关的函数都需要用 MenuItemCompat 来调用。
从之前的版本迁移
如果你的应用已经使用了 AppCompat 库, 大部分情况下你只需要在 values/ 目录下 定义一个主题即可: values/themes.xml:
<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>
现在 所有的 values-v14+ Action Bar 样式都没用了, 可以删除这些内容了。
改变主题
新版 AppCompat 支持 新的 color palette theme 主题机制,方便你自定义控件的颜色来符合你应用的主题色。 values/themes.xml:
<style name="Theme.MyTheme" parent="Theme.AppCompat.Light">
<!-- colorPrimary 定义 ActionBar 的背景色 -->
<item name=”colorPrimary”>@color/my_awesome_color</item>
<!-- colorPrimaryDark 定义状态栏的背景色 -->
<item name=”colorPrimaryDark”>@color/my_awesome_darker_color</item>
<!-- colorAccent 为 colorControlActivated 的默认值,该值用户显示控件的高亮状态 -->
<item name=”colorAccent”>@color/accent</item>
<!-- 还可以设置 colorControlNormal, colorControlActivated
colorControlHighlight, 和 colorSwitchThumbNormal 的值来控制控件的颜色. -->
</style>
设置上面的值后,AppCompat会自动应用到 Lollipop 以及以后版本的控件和状态栏中。在Lollipop 之前的版本中, AppCompat 也会尽可能的模拟控件的主题。
控件主题
目前 AppCompat 支持如下控件的主题色。
- AppCompat Toolbar 提供的所有功能
- EditText
- Spinner
- CheckBox
- RadioButton
- Switch(需要使用 android.support.v7.widget.SwitchCompat 控件替代)
- CheckedTextView
对于上面的控件,只需要在 AppCompat 主题中定义主题色即可实现 控件的主题色变化。再也不用使用 HoloEverywhere https://github.com/Prototik/HoloEverywhere 等第三方库了。
Toolbar 控件
Toolbar
AppCompat 支持 Toolbar 的所有功能。在 AppCompat 中 Toolbar 通过android.support.v7.widget.Toolbar 类实现。 使用 Toolbar 的方式有两种:
- 把 Toolbar 当做 ActionBar 使用,除了可以使用 ActionBar 的功能以为还可以更加详细的控制 Toolbar 的外观等。
- 在界面的其他地方使用 Toolbar。
ActionBar
要把 Toolbar 当做 ActionBar 使用, 需要先禁用系统的 ActionBar,可以通过继承 NoActionBar 主题来实现 例如 Theme.AppCompat.NoActionBar。
然后创建一个 Toolbar, 通常是在 布局文件中定义:
<android.support.v7.widget.Toolbar
android:id=”@+id/my_awesome_toolbar”
android:layout_height=”wrap_content”
android:layout_width=”match_parent”
android:minHeight=”?attr/actionBarSize”
android:background=”?attr/colorPrimary” />
宽度、高度、背景等属性都由你自己来定义。 一个 Toolbar 只是一个控件(ViewGroup),你可以按照你想要的方式来使用和显示它。
然后在 Activity 或者 Fragment 中把 Toolbar 设置为 ActionBar。
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.blah);
Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
setSupportActionBar(toolbar);
}
这样,所有的菜单都会显示到你的 Toolbar 中,菜单的操作和之前一样。
独立使用 Toolbar
独立使用 Toolbar 意味着无需把 Toolbar 设置为 ActionBar了,这样你就可以随心所欲的控制 Toolbar 的样式了。 独立使用 Toolbar 的时候你还需要手工来添加菜单或者功能到 Toolbar 里面。例如:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.blah);
Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
// 设置一个 OnMenuItemClickListener 来处理菜单的点击事件
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
// Handle the menu item
return true;
}
});
// 手工把 菜单 添加到 Toolbar 中
toolbar.inflateMenu(R.menu.your_toolbar_menu);
}
Toolbar 还有很多其他功能,详情请参考 Toolbar API reference.
Toolbar 的样式
Toolbar 的样式和 ActionBar 有点区别,Toolbar 的样式是直接设置到 Toolbar 控件上的。例如:
<android.support.v7.widget.Toolbar
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
app:theme="@style/ThemeOverlay.AppCompat.ActionBar" />
还可以使用 layout 属性来定义 Toolbar 的样式, 下面是一个实现 DarkActionBar (内容为 黑色的但是弹出菜单为浅色的)样式的方式:
<android.support.v7.widget.Toolbar
android:layout_height=”wrap_content”
android:layout_width=”match_parent”
android:minHeight=”@dimen/triple_height_toolbar”
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
SearchView 的样式
AppCompat 支持 Lollipop 新版的 SearchView api, 可以更加详细的控制 SearchView 的样式。 下面是使用 Lollipop 方式 来定义 SearchView 的样式:
values/themes.xml:
<style name=”Theme.MyTheme” parent=”Theme.AppCompat”>
<item name=”searchViewStyle”>@style/MySearchViewStyle</item>
</style>
<style name=”MySearchViewStyle” parent=”Widget.AppCompat.SearchView”>
<!-- Background for the search query section (e.g. EditText) -->
<item name="queryBackground">...</item>
<!-- Background for the actions section (e.g. voice, submit) -->
<item name="submitBackground">...</item>
<!-- Close button icon -->
<item name="closeIcon">...</item>
<!-- Search button icon -->
<item name="searchIcon">...</item>
<!-- Go/commit button icon -->
<item name="goIcon">...</item>
<!-- Voice search button icon -->
<item name="voiceIcon">...</item>
<!-- Commit icon shown in the query suggestion row -->
<item name="commitIcon">...</item>
<!-- Layout for query suggestion rows -->
<item name="suggestionRowLayout">...</item>
</style>
Toolbar 来袭
希望上面的介绍能够帮助你创建符合纸墨设计风格的应用。欢迎你分享你关于纸墨设计方面的创意。
常见问题
为什么我的 EditText 或者其他控件(上面提到过的)并没有支持颜色主题呢?
AppCompat 中的控件主题颜色是通过在解析布局文件的时候 动态拦截生成的,大部分情况下都是正常的,但是下面几种情况可能无法正常使用:
- 你使用的是自定义版本的控件(例如 继承至 EditText)
- 你不是使用 LayoutInflater 来创建 EditText的
为什么不是所有的控件都支持自定义主题色呢?
目前 AppCompat 只支持上面提到的几种控件, 未来可能会支持更多的控件。
为啥我的 ActionBar 下方在 Lollipop 上会显示一个阴影?我已经设置android:windowContentOverlay 为 null 了
在Lollipop 中,ActionBar 的阴影是通过新的 elevation api 实现的。可以通过 getSupportActionBar().setElevation(0) 来删除该阴影,也可以在 ActionBar 主题中设置 elevation 的值。
为啥在 Lollipop 之前的版本中不支持纸墨动画效果呢(Ripple 水波纹效果)?
Android Lollipop 引入的 RenderThread 可以让 RippleDrawable 运行的更加流畅。为了优化 5.0之前的版本,我们暂时考虑先不在之前版本支持 RippleDrawable 。
Android Lollipop 引入的 RenderThread 可以让 RippleDrawable 运行的更加流畅。为了优化 5.0之前的版本,我们暂时考虑先不在之前版本支持 RippleDrawable 。
在 api v11+ 版本中你可以在 ActionBarActivity 中使用 PreferenceFragment。对于之前的版本,你可以考虑使用 https://github.com/kolavar/android-support-v4-preferencefragment (云在千峰注:笔者经过测试, 该库可以和 AppCompat v21 使用,并且里面的 CheckBox 等控件也会自动应用主题色)