AppCompat 21實現低版本手機使用Material Design
來自: http://www.jcodecraeer.com//a/anzhuokaifa/androidkaifa/2014/1028/1856.html
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
的。就差這一步 很無賴。