探索新的Android Material Design支援庫

丿灬安之若死發表於2017-11-03

Android Material Design支援庫提供了一些新元件,我們在這裡簡要的介紹一下這些元件,以及如何使用這些元件。

我是Material Design的粉絲,它使應用程式更具有一致性和整體性,而且看起來更美觀,更容易使用。
Google I / O大會2015年引進一些很棒的新Android特性,包括新的Material Design支援庫。
Material Design的介紹: Material Design Guidelines (譯註:請自備梯子)
讓我們一起來看看這些我們現在能用的新元件。

Snackbar

Snackbar是帶有動畫效果的快速提示條,它只會出現在螢幕底部。
它基本上繼承了Toast的方法和屬性,但與Toast不同的是,Snackbar上可以帶有按鈕,
當Snackbar出現時,使用者可以點選按鈕做相應的處理;
Snackbar支援滑動消失,類似通知欄的訊息;
如果使用者沒做任何操作,Snackbar在到達設定的時間後也會自動消失。

對開發者來說,我們只要簡單的幾行程式碼就可以實現Snackbar

Snackbar.make(mDrawerLayout, "Your message", Snackbar.LENGTH_SHORT)
.setAction(getString(R.string.text_undo), this)
.show();

注意: 不能同時顯示多個Snackbar

Floating Action Button

Floating Action Button (FAB)是一個懸浮按鈕, 它主要用於一些重要的操作,比如在列表介面上新增按鈕。
現在我們可以在程式裡很容易實現Floating Action Button,不再需要其他三方庫的支援。

這個按鈕我們使用時一般用以下2中尺寸:
Normal (56dp) — 大部分情況下使用
Mini (40dp) — 只有在與螢幕上其他元件保持一致性的時候使用


Normal (left) 和 Mini (right) FAB 按鈕

FAB按鈕預設會使用主題中定義的背景色,但我們也可以很容易的修改背景色,以下是一些我們一般會修改的屬性:

  • fabSize - 設定FAB的大小 (‘normal’ or ‘mini’)
  • backgroundTint - 設定邊框大小
  • rippleColor - 設定按下時的顏色
  • src - 設定在FAB中顯示的圖示
  • layout_anchor - 設定顯示座標的錨點
  • layout_anchorGravity - 設定錨點的對齊方式

我們只要簡單加入以下程式碼,就可以實現FAB:

<android.support.design.widget.FloatingActionButton
android:id=”@+id/fab_normal”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:src=”@drawable/ic_plus”
app:fabSize=”normal” />

EditText Floating Labels

TextInputLayout主要用於包含EditText,會預設生成一個浮動的Label, 當我們選擇EditText時, EditText中設定的hint會上浮到EditText的左上角.
這對提交使用者資料很有用。

實現很簡單,只要包含EditText就可以了:

<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/edit_text_email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textEmailAddress"
android:hint="@string/hint_email" />
</android.support.design.widget.TextInputLayout>

它同時支援顯示錯誤資訊, 我們主要加入如下程式碼即可:

setErrorEnabled(true);
setError(getString(R.string.text_error_message));

注意: 設定錯誤資訊需要在setErrorEnabled標誌之後,這樣可以保證在錯誤出現時layout大小不發生變化

Navigation Drawer在現在的APP中很常見, 以前實現一直不怎麼容易,
現在提供的NavigationView元件可以直接放在DrawerLayout中,
通過設定menu resource就能顯示選單項了。

<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<FrameLayout
android:id="@+id/main_content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="@+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/navigation_header"
app:menu="@menu/drawer" />
</android.support.v4.widget.DrawerLayout>

這個View有兩個主要屬性:

Header Layout

headerLayout是一個可選得屬性,通過設定它我們可以在導航欄上面增加一個Header,通用的做法我們在上面顯示使用者資訊。

menu屬性用來定義需要引用的menu resource。

如下所示, NavigationView menus我們一般有兩張用法,第一種是使用標準的單選模式:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity">
<group android:checkableBehavior="single">
<item
android:id="@+id/navigation_item_1"
android:checked="true"
android:icon="@drawable/ic_android"
android:title="@string/navigation_item_1" />
<item
android:id="@+id/navigation_item_2"
android:icon="@drawable/ic_android"
android:title="@string/navigation_item_2" />
</group>
</menu>

這樣選單項只是簡單的羅列,所有的選單項都屬於同一個分組。

第二種用法也是相似的,不過我們可以進行分組,給每一個分組定義標題,如下所示:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity">
<group android:checkableBehavior="single">
<item
android:id="@+id/navigation_subheader"
android:title="@string/nav_header">
<menu>
<!-- Menu items go here -->
</menu>
</item>
</group>
</menu>

這樣我們就可以把我們的選單項進行分組,這還是很有用得,我們可以按功能把選單項進行分組。

還有一些重要屬性的屬性我們可以設定,如下:

  • itemBackground — 設定選單項的背景
  • itemIconTint — 設定選單項的圖示
  • itemTextColor — 這隻選單專案的文字顏色

我們可以通過實現OnNavigationItemSelectedListener方法,處理選單項的點選事件。

注意: For API21+, the NavigationView automatically takes care of scrim protection for the status bar.

TabLayout

TabLayout可以很容易地在APP中新增Tab分組功能

我們有好幾種方式來使用它:

  • 固定Tabs,根據View的寬度適配

  • 固定Tabs, 在View中居中顯示

  • 可滑動的Tabs

要實現上述效果,首先我們需要加入TabLayout:

<android.support.design.widget.TabLayout
android:id="@+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabGravity="fill" />

然後, 我們可以通過以下這些屬性調整TabLayout的外觀:

  • tabMode - TabLayoutd模式,可以選擇 fixed 或 scrollable
  • tabGravity - Tab的對齊方式, 可以選擇 fill 或 centre
  • setText() - 設定Tab上的文字
  • setIcon() - 設定Tab上的圖示

我們還可以給TabLayout設定一些Listener:

  • OnTabSelectedListener - Tab被選中時,觸發的Listener
  • TabLayoutOnPageChangeListener
  • ViewPagerOnTabSelectedListener

我們新增好TabLayout後, 我們只需要通過setupWithViewPager方法加入viewpager:

ViewPager pager = (ViewPager)rootView.findViewById(R.id.viewPager);
pager.setAdapter(new MyPagerAdapter(getActivity().getSupportFragmentManager()));
TabLayout tabLayout = (TabLayout) rootView.findViewById(R.id.sliding_tabs);
tabLayout.addTab(tabLayout.newTab().setText("Tab One"));
tabLayout.addTab(tabLayout.newTab().setText("Tab Two"));
tabLayout.addTab(tabLayout.newTab().setText("Tab Three"));
tabLayout.setupWithViewPager(pager);

Coordinator Layout

CoordinatorLayout是組織它的子views之間協作的一個Layout,它可以給子View切換提供動畫效果。
要使用這個元件,請升級其他support library中的元件到最新版本,比如我需要把RecyclerView升級到22.2.0。

  • Floating Action Button

我們剛才已經知道Snackbar可以顯示在其他UI元件的上面,不過我們可以讓FloatingActionButton不被Snackbar覆蓋,
當Snackbar出現時,FAB上移,Snackbar消失時,FAB下移。

要實現如上的效果,FloatingActionBar必須包含在CoordinatorLayout中,
接著我們需要設定layout_anchor 和 layout_anchorGravity屬性

<android.support.design.widget.CoordinatorLayout
android:id="@+id/main_content">
<!-- Your other views -->
<android.support.design.widget.FloatingActionButton
android:id=”@+id/fab_normal”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:src=”@drawable/ic_plus”
app:layout_anchor="@id/main_content"
app:layout_anchorGravity="bottom|right"
app:fabSize=”normal” />
</android.support.design.widget.CoordinatorLayout>

最後, 在我們構造Snackbar時, 我們需要把CoordinatorLayout作為View引數傳遞過去, 如下所示:

Snackbar.make(mCoordinator, "Your message", Snackbar.LENGTH_SHORT).show();

App Bar

CoordinatorLayout我們讓我們根據滾動事件來調整子View的佈局,比如在滾動內容時,我們可以隱藏Toolbar。

要實現這個效果,首先我們需要設定layout_scrollFlags屬性,這個屬性用來控制跟隨View滾動還是固定在最上面,
這個屬性可以設定為以下幾種值:

  • enterAlways - 實現quick return效果, 當向下移動時,顯示View(比如Toolbar)


  • enterAlwaysCollapsed - 當你的View已經設定minHeight屬性又使用此標誌時,你的View只能以最小高度進入,只有當滾動檢視到達頂部時才擴大到完整高度。


  • exitUntilCollapsed - 向上滾動時收縮View,但可以韌體Toolbar一直在上面


注意: 設定scroll標誌的View必須在沒有設定的之前定義,這樣可以確保設定過的View都從上面移出, 只留下那些固定的View在下面。

如下程式碼所示, 我們的recycler view設定了layout_behavior屬性,
當我們的recycler view滑動時,就會觸發設定了layout_scrollFlags的控制元件發生狀態的改變。
不過我們沒有設定TabLayout的layout_scrollFlags屬性, 所以TabLayout會固定在螢幕最上方。

<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior=
"@string/appbar_scrolling_view_behavior" />
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
...
app:layout_scrollFlags="scroll|enterAlways" />
<android.support.design.widget.TabLayout
...
/>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>

ToolBars

現在我們可以使用CollapsingToolbarLayout,它可以實現當螢幕內容滾動時,收縮Toolbar

<android.support.design.widget.AppBarLayout
android:layout_height="192dp"
android:layout_width="match_parent">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<android.support.v7.widget.Toolbar
android:layout_height="?attr/actionBarSize"
android:layout_width="match_parent"
app:layout_collapseMode="pin" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>

當我們使用這個元件時, layout_collapseMode必須設定, 它有兩個選項:

  • Pin - 設定為這個模式時,當CollapsingToolbarLayout完全收縮後,Toolbar還可以保留在螢幕上

  • Parallax - 設定為這個模式時,在內容滾動時,CollapsingToolbarLayout中的View(比如ImageView)也可以同時滾動,實現視差滾動效果.
    可以通過layout_collapseParallaxMultiplier*設定視差因子。

通過CollapsingToolbarLayout的setText()方法,我們就可以實現讓文字大小隨著縮放慢慢變小。

Custom Views

我們還可以給自定義View定義Behaviour, 在onDependentViewChanged()方法中做相應的回撥處理,這可以更好處理touch事件, 手勢操作和子View之間的依賴關係。

那麼你還在等什麼呢? 加入這個Material Design支援庫,趕緊試試吧!

compile 'com.android.support:design:22.2.0'

相關文章