AppCompat 21实现低版本手机使用Material Design
Android5.0 Lollipop 的sdk发布以后,我就希望兼容包中也包含了新的Material Design主题,幸运的是的确如此。
这个新的主题包含在AppCompat 21中,所以需要注意的是如果你要将Material Design运用到以前的项目中,需要做点额外的工作。
本文演示用最基本的工具创建一个以Material作为主题的应用。我这里并不会详细的介绍如何应用这个主题,而是重点介绍如何向前兼容以及使用Lollipop中的transitions(过度效果)。
注:到目前位置Lollipop中的transitions仍然不能做到兼容非5.0系统的手机。
项目设置:
在gradle项目中,你需要将compile sdk版本设置成21,如下:
android {
compileSdkVersion 21
buildToolsVersion "21.0.0"
defaultConfig {
applicationId "com.antonioleiva.materialeverywhere"
minSdkVersion 14
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
...
}
dependencies {
compile fileTree(dir: 'libs', include: \['*.jar'\])
compile 'com.android.support:appcompat-v7:21.+'
}
指定Material Theme主题
你需要将自己的主题继承自Theme.AppCompat,新的AppCompat有你所需要的支持Material Design的兼容代码与资源文件。在values-v21中我用自定义的base thmeme替代了原始主题,这是因为我要在里面使用5.0的各种transitions(过度)效果。
values/themes.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="AppTheme.Base"/>
<style name="AppTheme.Base" parent="Theme.AppCompat">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimary</item>
<item name="android:windowNoTitle">true</item>
<item name="windowActionBar">false</item>
</style>
</resources>
values-v21/themes.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="AppTheme.Base">
<item name="android:windowContentTransitions">true</item>
<item name="android:windowAllowEnterTransitionOverlap">true</item>
<item name="android:windowAllowReturnTransitionOverlap">true</item>
<item name="android:windowSharedElementEnterTransition">@android:transition/move</item>
<item name="android:windowSharedElementExitTransition">@android:transition/move</item>
</style>
</resources>
在上面的代码中 我们设置了primary colors,同时去掉了actionbar,这是因为我们要使用一种新的工具替代它:ToolBar。后面我们将谈到ToolBar。
设置ToolBar
ToolBar基本上就是我们熟知的ActionBar,他们最主要的区别是ToolBar是我们所能控制的布局的一部分, 所以我们可以随意的实现一些自定义的效果,比如在ToolBar上使用动画、设定其高度之类的。
如下:
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimaryDark"/>
Toolbar使用的时候就跟一般的控件一样,但是我们得告诉activity,这里的ToolBar是ActionBar的替代者。
@Override
protectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getLayoutResource());
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
if(toolbar != null) {
setSupportActionBar(toolbar);
}
}
如上所示当调用了setSupportActionBar(toolbar)之后toolbar就有了特殊的地位,虽然他只是activity布局中的一个元素,但是他能像actionbar那样直接显示menu目录中的菜单资源。 需要注意的是使用setSupportActionBar要求你的activity继承自ActionBarActivity。
Lollipop系统Activity之间的切换效果
上面我们提到了在5.0以下的系统中没法看到Lollipop中的那些生动的切换效果,所以我们得想法解决这个问题。兼容包为我们提供了以下方法:
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(
activity, transitionView, DetailActivity.EXTRA_IMAGE);
ActivityCompat.startActivity(activity, newIntent(activity, DetailActivity.class),
options.toBundle());
ActivityCompat让我们连判断版本的代码都省了。
下面是我实现的一个demo app的效果,代码已经放在了github上。this project in my Github.
纠正:
ActivityOptionsCompat.makeSceneTransitionAnimation只能在5.0上才可以看到效果,在5.0以下只能确保程序不出错,但没有效果,其中的原因估计是这样的:
ActivityOptionsCompat的确支持makeSceneTransitionAnimation方法,但是没法开启Window.FEATURE_CONTENT_TRANSITIONS(不管是代码还是xml中),在本文的demo中开启FEATURE_CONTENT_TRANSITIONS的代码如下:
<item name="android:windowContentTransitions">true</item>
这是21以上才有的属性。
当然也有可能ActivityOptionsCompat能开启FEATURE_CONTENT_TRANSITIONS
,只是我们不知道而已。至少本文的demo是没有能够在5.0以下开启FEATURE_CONTENT_TRANSITIONS
的。就差这一步 很无赖。