符合Material Design的抽屜導航效果

符合Material Design的抽屜導航效果

前言:

現在看來,抽屜式導航已經成爲主流導航模式之一。儘管廣受批評,但我還是很喜歡該樣式,因此我決定在我寫的幾個app上添加這個控件。這篇文章想通過介紹我覺得抽屜式導航有趣的地方,幫助閱讀本文的 Android 開發者們學習到一些知識,同時從其他人的評論中學習到更多的東西。

這是三篇文章中的第二篇。歡迎查看第一篇和第三篇:

* [Material Design下的抽屜導航的大小](https://medium.com/@sotti/navigation-drawer-styling-under-material-design-f0767882e692)
* Material Design下的抽屜效果的行爲(敬請期待)

你可以從下面查看Material Design指南上關於抽屜導航的部分:

* [Navigation Drawer pattern](http://www.google.com/design/spec/patterns/navigation-drawer.html)
* [Material Design metrics and keylines](http://www.google.com/design/spec/layout/metrics-keylines.html#)
* [Toolbar metrics](http://www.google.com/design/spec/layout/structure.html#structure-toolbars)

開始:

抽屜式導航一直以來都是被爭論的熱點話題。當 Material Design 規範剛發佈的時候,抽屜式導航就在規範中處在一個尷尬的位置,使得開發者們很困惑到底要不要使用抽屜式導航,甚至在 Material Design 規範下的開發指南出來以後,有關如何在 Android 開發中對待抽屜式導航都沒有一個清晰的答案。

現在,雖然這兒已有一些漂亮的,甚至有一些Google的源碼能拿來看看… 但是,你之所以還來到這裏,可能是因爲你熱衷於編程

在這篇文章裏,我將會談論如何使用抽屜的樣式,但是並不會完全涉及 Material Design 指南上的所有樣式,只是撿一些我認爲需要強調的東西。

準備好了嗎?

位置

在過去,抽屜式導航欄 和 ActionBar 處於同一個 View 層級

隨着這種設計模式的發展,其中相互矛盾的地方也開始浮出水面……在 Material Design 中很清晰地指出:處於不同 View 層級的兩個頁面,是不能共存於同一個父佈局中的同一個 View 層級的。有關這個問題引發了許多討論,但更重要的是Google 並沒有給出好的解釋,不過最後抽屜式導航還是得到了一個被認可的定義:

左抽屜式導航打開後,導航欄的高度應該和屏幕一致,但要低於狀態欄。此外,其他任何在抽屜層以下的內容都應該被陰影覆蓋,但這些內容又是可見的。

左側的導航抽屜橫跨屏幕的高度並覆蓋下方的狀態欄。抽屜下的東西將會變暗。但仍是可見的。

注意圖中右邊的抽屜略有不同。

注:我假設你使用的是AppCompat toolbar

既然toolbar是View 層級的另一個view,不妨就就將toolbar置於抽屜的layout之下,跟其他的view一樣。

如果你在Google應用上看到如下的東西也不用擔心:

Google+ Photos可能是最後一個使用抽屜,卻沒有覆蓋ActionBar/Toolbar的Google應用,但是我想他應該很快就會被改過來。

旋轉標題圖標

你還記得當抽屜打開時那個ActionBar/Toolbar中的漂亮的圖標動畫嗎?這個動畫在Holo主題下並不是很好看,在 Matarial Design 下卻很漂亮。

我覺得當它第一次出現在Google Play Store時,很多的開發者和設計師都會很喜歡它。

僅在那數週之後,抽屜式導航上就開始出現該動畫。那時它顯得很特別,因爲在Google Material Design videos 和 promo features上都出現了它的身影。

我記得很多人在第一次遵循 Matarial Design 規範開發時,就是使用這個漢堡/箭頭圖標動畫。Google第一次實現這個抽屜式導航欄的時候,並不是把它放在 ToolBar 的上面,因此你可以看到這個精美的動畫。但是 Material Design 指南發佈後,出現了一個很奇怪的現象,很多的Google應用都在做與 Material Design 指南背道而馳的事情。即使是現在我寫這篇博文的時候,大部分的應用還是在遵循着 Material Desgin 指南,但我還是希望抽屜式導航欄都能在 Toolbar 上面。

在我看來,Material Design發佈的已經有點晚了。因爲圖標動畫已出現在發佈了的SDK中並且在默認情況下被使用了。

由於某些原因,即使要求把抽屜導航欄佈局到其他的view之上,但大多數的google應用還是會有這樣的動畫(注:在寫下這篇文章的時候,Gmail和Inbox已經停用了),即使你很難發現它(但如果你仔細看的話,在緩慢的移動抽屜式導航時,還是可以看到動畫的)。讓我很不爽的是:一旦你看到了,又會每次都忍不住去看,得不償失。因此,我也決定關掉這種動畫效果。

第一眼看來,DrawerArrowStyle的參數很容易懂:

< item name=”spineBars”> true < /item>

Android Developers中定義如下:

在移動抽屜導航欄的過程中,無論圖標是否應該旋轉,都要設定一個布爾值:要麼是 true,要麼是false.

但問題是,這並不能起到作用。如果你設置爲false,bars就會以一種奇怪的方式旋轉。

我發現的解決的方式是:覆寫onDrawerSlide方法。見下面鏈接的Gist。

既然這個圖標動畫的可視性較差,那就沒有必要再保留它了。如果你不注意看,你就看不到它,但當你注意看並看到的時候,又不知道是怎麼回事。

資料圖片

這張個人頭像是圓形的,我們有很多方法能讓圖片變成圓形,但我每次需要實現這個需求想起的都是 Romain Guy方法。所以這次我還是使用了 Romain Guy 的 CircleImageView,畢竟“信RM,無BUG”。有人可能會提到 Google IO 大會上被使用的那個 App,我還沒去了解過它的具體實現,可能值得我們看一看吧。

在Google Paly Movies與Google Paly Books上,這個圖片有一個白色的邊框。而其他的Google app上卻沒有。Google+和Hangouts的資料圖片在toolbar上,不過卻有白邊框。

注意:查看資料圖片大小

資料圖片是圓形的,通常沒有邊框。建議你通過Romain Guy推出的庫來獲得圓形。

封面圖片

封面圖片(不同於資料圖片),是賬號/頭像部分的背景(就是抽屜式導航的上部,通常你可以在此切換賬號,查看暱稱,email和你的資料圖片)。

這塊的文字是白色的,並且要確保能看的見,你可以應用一個前景或者半透明的黑色來覆蓋封面圖片。我試了一下,發現40-50% 的黑色是最好的。要注意的是,不要既弄得圖片不可見,又弄得文字沒法讀。

我是在FrameLayout中加一個前景。但我不知道這是不是最好的方法,歡迎大家交流。我並沒有實現在賬號切換的功能,而且這整個layout/section都是可點擊的,有touch反饋,或者是Lollipop中的ripple,或者兩者。當然你也可以使用centerCrop scaleType 讓它更漂亮。

仔細看一下這個圖片,你會發現其實它在狀態欄下也是可見的。當我寫下這行字的時候,Google apps正在應用這種效果。Gmail,Inbox,Keep,Playe Story和Hangouts已經實現了,而其他的也準備實現它。當然,這只是Lollipop及以上的版本中纔會有的效果。

即使是現在,在Play Store 上的Google IO 的有些應用的抽屜式導航也是完全錯的,但他們在改良代碼,並且準備下一個版本了(不過好像有段時間了… 可能會在今年幾個月後的Google IO 大會之前更新)

比較神奇的是Google ScrimInsets layout。拷貝,粘貼,然後自己試着修修改改就OK了。我覺得Google的人員應該比我做的更好。深入的閱讀一下gist上的代碼,瞭解一下關於 themes/styles 的更多的詳細內容,能讓你有更好地表現。

讓我有點疑惑就是ScrimInsets layout能不能應用到Lollipop以下的版本中。我知道在Kit Kat中是可行的,但是Google並沒這樣做。可以肯定的是“擠滿”狀態欄和/或導航欄在Lollipop下的版本中並不存在,這可能是背後的一個原因。

注意:查看封面照片的大小

只有在Lollipop中,抽屜導航會出現在狀態欄之下。在Lollipop之下的版本中,擠滿狀態或導航欄並不是什麼事情,這可能是其中的原因。

可選中行的背景,圖標和文字

當要更改抽屜中的主要行的樣式的時候,對每行的每個元素,我們都要處理其中的三個子元素(背景,圖標,文本)和3個不同的狀態(默認,選中,點擊)。但每一個開發者都需要明白:開發 App 不需要完全遵循規範 ,但是瞭解規範又是必不可少的,大家可以看看 Google 的 App 和其他的一些好看的apps是怎樣體現 Material Desgin 所包含的思想的,把你從這些 App 裏總結出來的東西應用到你的 App 中。

Okay,現在來看一下Google apps 都有哪些特徵。在下面的圖片中,第一行是默認的狀態,第二行是選中的狀態,第三行是點擊的狀態。

雖然上面的圖片看起來很相似,但其實它們是不一樣的。總結一下就是:

Google apps看起來十分的連貫,但是當你注意下細節時就會發現,此時抽屜式導航的選中行有超過10多種的樣式。

  • 拇指規則:

在自己不斷地嘗試並參考了設計指南與Google apps後,這是我提出的一些想法:

如何實現

儘管我想知道,但是沒人告訴我他是怎麼來實現的,所以我自己就這麼做了。

首先,使用兩個drawable作爲背景。一個放在res/drawable-v21裏,爲Lollipop及以上的版本使用;另一個在res/drawable中,目標是更低的版本。因爲ripple在5.0以下的版本中並不存在。

僅在Lollipop及以上的版本中使用ripple。Ripples並不支持5.0以下的版本。

每當你點擊一行的時候,ripple就會出現,不管它選中與否。因此,你在res/drawable-v21中的是有一組包含ripple的items的selector。這是因爲我們希望對於選中和未選中的行,在被點擊時都能顯示相同的ripple,但是未選中的背景是白色,而選中的item的背景是grey_200。

另外在res/drawable中,你需要的是一個不包含ripple的selector。

圖標

在最近的幾個月裏,我嘗試讓同一圖標呈現出不同的顏色來。 因此,我就把所有的圖標都先弄成白色,然後在用想要的顏色進行着色。這樣做的優點是,你不必每次創建一個新的圖標。你可以先從Google上得到不同大小和顏色的這些圖標,再用不同的顏色進行二次加工,看看那種效果最好。另外你要是使用不同顏色的同一圖標的話,要記得保存成相同的大小。如果你需要根據狀態(點擊,選中…)來改變它的顏色的話,可以設置一個color state list resource

我實現的方式是在一個自定義的ImageView中編寫的,因爲color state list在Kit Kat及其一下的版本中並不可用(android:tint中可以使用color,但是不能用color state)。

看一下下面鏈接中的gist中我是如何做的。如果你發現了更好的方式,或錯誤,請反饋給我。

Header和footer的表現

頭部(aka account section)中有些是不可滑動的,而有些是可滑動的。以我看來,如果可以的話,最好設計成不可滑動的。這樣的話,抽屜式導航看起來更美觀,連貫,易用。

底部(aka setting and support)可以是可滑動的,也可以不是。如果你看一下Google Apps,就會發現有些是不可滑動的,而有些是在可滑動的scroll的底部。如果你有需求是不能放在抽屜的底部的話,那就放在能滑動的列表的後面。

再次強調一下,在我看來,不可滑動是最好的方式,但是也可以有例外。比如,當頭部不可滑動時,有些條目就被固定了,因此在抽屜裏就有了可滾動的區域了。但是如果可滾動的空間太小,那麼看起來就很糟糕了(只有一行或兩行),要想得到更多的空間,那麼一個好的辦法就是將footer 解除固定。

頭部和底部理應被固定住,除非抽屜需要更多的空間以表現更出色。

由於抽屜選項,路徑,結構…的不同,因此這裏其實並沒有什麼拇指法則。

資源

-Google Official Material Design icons
-Material Design Color Definitions

代碼

-Github項目地址

總結

這是關於如何更改抽屜式導航的樣式,你仍需要花費很多時間來想清楚你想做成什麼樣,而這要比做到花費的時間要長的多。

如果你想要了解更改抽屜式導航的樣式,請看看另兩篇文章。

歡迎評論,反饋…

Hava fun!

發佈了180 篇原創文章 · 獲贊 85 · 訪問量 156萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章