AppCompat V21:將 Materia Design 兼容到於5.0以前的設備html
本篇文章翻譯自Chris Banes(就任於Google,是Android-PullToRefresh,PhotoView,photup的做者,GitHub地址:https://github.com/chrisbanes,博客地址:https://chris.banes.me/2014/10/17/appcompat-v21/ ,如今這篇文章已經收錄到Android官方博客了:http://android-developers.blogspot.jp/2014/10/appcompat-v21-material-design-for-pre.html,下面是翻譯正文,末尾介紹了一個已經兼容到5.0以前設備的App,提供2014 Google開發者大會信息的app: Google Iosched,具體信息能夠看文章結尾處。android
博客正文ios
android 5.0今天發佈。在不少很棒的更新中,包括了新的UI組件和建立 Material Design 主題的能力。爲了使你可以將新的設計中更新到舊的系統中,git
咱們同時更新了包含 AppCompat 的support libraries。在這篇文章中,我將整體說明一下appCompat的新特性並介紹一下如何應用於你的app中。github
AppCompat (aka ActionBarCompat)是爲了Android 4.0中的ActionBar的向後兼容到 Gingerbread(2.3) 系統。在兼容性實現和
Framework實現的上層提供了一個通用的API層。這個最新的 21Version appcompat 提供一些5.0的API和特性設置。app
Android5.0引入了一個新的ToolBar widget,這是一個ActionBar模式的衍生,但爲你的使用提供了更多的控制和便利性。ide
Toolbar 和你的View層級關係中的其它View同樣。但它使得界面更容易的與其它部分交互,好比View,動畫,Scroll事件的響應。
添加依賴佈局
若是你正在使用Gradle,只要把appcompat做爲一個依賴庫添加到你的build.gradle中便可。gradle
dependencies { ... compile "com.android.support:appcompat-v7:21.0.0" }
新的集成
若是你如今沒有使用AppCompat,或者徹底是從頭開始,請參考下面幾個步驟:
1.全部的Activities都必須繼承自ActionBarActivity,它繼承自v4包的FragmentActivity,所以你能夠繼續使用fragments。
2.全部的主題必須繼承Theme.AppCompat. 這裏有一些變量,包括Light和NoActionBar。
3.當你要經過ActionBar來展現任何東西的時候(好比用於List導航的SpinnerAdapter),請確保你使用了ActionBar的主題上下文,你能夠經過
getSupportActionBar().getThemedContext().來獲取。
4.對於全部的MenuItem action的調用,你必須使用靜態方法MenuItemCompat。
ActionBar API 指南 (http://developer.android.com/guide/topics/ui/actionbar.html) 是一個AppCompat的綜合的介紹。但也須要更新到 21 版本。只要忽略底部的「Example theme」,它提到了你應該設置爲每個ActionBar設置兩個版本的style屬性。
從以前的建立中遷移
若是你早已擁有了AppCompat的搭建,緊接着這裏會介紹如何使用新的特性去更新你的主題。動畫
咱們如今在全部的版本上支持Toobar/ActionBar的實現。意味着你在ActionBar中將再也看不到任何的android:屬性。(過去爲了兼容都須要設置兩個屬性,一個要帶android:的,一個不帶)對於那些已經使用AppCompat的app建立,意味着你應該從新設置那些在Android name space 中重置的V14+的主題。
請注意,這些僅僅用於那些影響到ActionBar的屬性。
對於大多數的App,你應該須要在values中添加一個主題的聲明:values/themes.xml:
<style name="Theme.MyTheme" parent="Theme.AppCompat.Light"> <!-- Here we setting appcompat’s actionBarStyle --> <item name="actionBarStyle">@style/MyActionBarStyle</item> <!-- ...and here we setting 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>
主題
AppCompat已經支持了新的color palette主題屬性(http://developer.android.com/training/material/theme.html#ColorPalette), 這將容許你更簡單的經過一個主要及基本色調(http://www.google.com/design/spec/style/color.html#color-ui-color-application) 去自定義主題去適應你的品牌。
示例:values/themes.xml:
<style name="Theme.MyTheme" parent="Theme.AppCompat.Light"> <!-- colorPrimary is used for the default action bar background --> <item name="colorPrimary">@color/my_awesome_color</item> <!-- colorPrimaryDark is used for the status bar --> <item name="colorPrimaryDark">@color/my_awesome_darker_color</item> <!-- colorAccent is used as the default value for colorControlActivated which is used to tint widgets --> <item name="colorAccent">@color/accent</item> <!-- You can also set colorControlNormal, colorControlActivated colorControlHighlight & colorSwitchThumbNormal. --> </style>
在 API21+ 上,經過設置這些,AppCompat將會自動的將這些值傳遞到framework的屬性中。會自動填充狀態欄和最近的任務項的顏色。
在老的系統平臺上,AppCompat會在須要的地方模擬顏色主題。如今,對於ActionBar和一些widget的着色將會受到限制。
Widget 着色(Widget Tinting)
當運行在5.0的設備上,全部的widget將會使用咱們剛纔討論的 color theme 屬性着色。
在Lollipop上,有兩種主要的特性是被容許的: drawabel着色和在drawables中引用主題的屬性。
AppCompat爲 在老的系統的 UI widget的子集提供了類似的表現行爲:
全部的東西都由 AppCompat的 toolbar提供
EditText
Spinner
CheckBox
RadioButton
Switch(使用supportV7中的SwitchCompat,https://developer.android.com/reference/android/support/v7/widget/SwitchCompat.html)CheckedTextView
你不須要作任何特殊的工做,只需像之前同樣在你的佈局中使用這些控制而且AppCompat會爲你作剩下的工做(請看FAQ)。
Widgets
ToolBar
首先,在AppCompat中ToolBar被很好的支持,而且擁有過去Framework Widget中的全部API。
你須要經過 android.support.v7.widget.Toolbar (https://developer.android.com/reference/android/support/v7/widget/Toolbar.html) 使用它。
這裏有兩種方式使用ToolBar:
1.將ToolBar做爲ActionBar來使用 當你ActionBar的功能一些基本功能,(好比menu 填充和selection,ActionBarDrawerToggle等),
但還不可以知足你的需求的時候。
2.ToolBar做爲獨立使用。在如下場景中:
不支持ActionBar的狀況、在同一個屏幕中使用多個toolbar的狀況。
Action Bar
當把ToolBar做爲ActionBar使用的時候,第一件事就是去禁用 Decor 提供ActionBar的功能。最簡單的方式是繼承 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.my_layout); Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar); setSupportActionBar(toolbar); }
全部的menu 條目將會在你的ToolBar中展現,經過標準的options menu進行回調。
基於上述幾點,全部的menu 條目將被展現在你的ToolBar中,經過標準的menu回調。
Standalone(單獨使用)
和上面很相似,可是在這種模式下,你不用去設置ToolBar做爲ActionBar使用。因爲這個緣由,你可使用任何AppCompat主題而且你不須要禁用decor提供的ActionBar。
當它被獨立使用的時候,你須要經過content/actions手動的填充ToolBar、好比,若是你想它展現一些actions,你須要填充一個menu進去。
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.my_layout); Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar); // Set an OnMenuItemClickListener to handle menu item clicks toolbar.setOnMenuItemClickListener( new Toolbar.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { // Handle the menu item return true; } }); // Inflate a menu to be displayed in the toolbar toolbar.inflateMenu(R.menu.your_toolbar_menu); }
ToolBar還能夠作不少事情,具體的能夠參考文檔:https://developer.android.com/reference/android/support/v7/widget/Toolbar.html
Styling
ToolBar的樣式與標準的ActionBar是不同的。它是被直接設置到View上的。
一個常被開發者問到的問題是,如何實現一個看起來像DarkActionBar的Toolbar(深色的內容,亮色的覆蓋在上層的菜單)(這應該是側邊欄滑出時的那種效果),這樣的樣式能夠經過提供theme和popupTheme屬性實現:
<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的更新,它們會變得更加可定製和樣式多樣化。基於這些,咱們如今使用 L 樣式結構代替舊的SearchView主題屬性:
下面展現瞭如何改變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"> <!-- The layout for the search view. Be careful. --> <item name="layout">...</item> <!-- 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>
很顯然,你不須要去設置上面的全部屬性,缺省的就已經能夠知足大多數App了。
但願這篇文章能夠幫助你構建一個基於AppCompat,更加完美,Materia Desigh 的App,若是有任何AppCompat或者support libraries的使用問題,你能夠經過G+/Twitter來告知咱們,咱們將會提供更多的文檔。
常見問題:
爲何EditText(或者其它的Widget List)在Lollipop以前的系統上沒有被着色。
在AppCompat中 Widget 的着色原理是:
經過攔截任何佈局填充而且插入一個特殊的 tint-aware版本的Widget到它的位置上。對於大多數人,是能夠生效的,但我也考慮到了幾種未生效的場景:
你已經擁有自定義版本的Widget(好比,你繼承了EditText)
你經過一個LayoutInflater去建立了一個EditText(好比你調用new EditText)
你正在與LayoutInflater的Factory正關聯着。
這個特殊的 tint aware Widget 已經被隱藏了,由於它們是一個未完成的實現(這裏不太明白是什麼意思)。
Google Iosched
相信不少人對這個項目都不會陌生,開源有一段時間了,關鍵的是隨着5.0正式版的推出,它當即向5.0以前的系統作了兼容,相信之後還會持續更新GitHub地址:https://github.com/google/iosched 在個人微盤下提供了一個APK,你們能夠先看一下,固然仍是但願你們clone源碼,仔細研究下,很不錯的項目,下載地址:http://vdisk.weibo.com/s/av06eFs1kWSeE?from=page_100505_profile&wvr=6 ,若是沒有使用數據,微盤下的另外一個Apk或許能夠幫到你哦。下面是幾張截圖,交互很棒,趕忙下載源碼去看實現吧,還有個項目也能夠關注下:https://github.com/antoniolg/MaterialEverywhere,看名字就知道了