Android Design Support Library使用詳解

Google在2015的IO大會上,給我們帶來了更加詳細的Material Design設計規范,同時,也給我們帶來了全新的Android Design Support Library,在這個support庫里面,Google給我們提供了更加規范的MD設計風格的控件。最重要的是,Android Design Support Library的兼容性更廣,直接可以向下兼容到Android 2.2。這不得不說是一個良心之作。

使用Support Library非常簡單:添加引用即可:

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

下面我們來看看這些新控件的基本使用方法,我們從最簡單的控件開始說起。

Snackbar

Snackbar提供了一個介于Toast和AlertDialog之間輕量級控件,它可以很方便的提供消息的提示和動作反饋。Snackbar的使用與Toast的使用基本相同:

Snackbar.make(view, "Snackbar comes out", Snackbar.LENGTH_LONG)
                        .setAction("Action", new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                Toast.makeText(
                                        MainActivity.this,
                                        "Toast comes out",
                                        Toast.LENGTH_SHORT).show();
                            }
                        }).show();

需要注意的是,這里我們把第一個參數作為Snackbar顯示的基準元素,而設置的Action也可以設置多個。

顯示的效果就類似如下:

Android Design Support Library使用詳解

Snackbar在出現一定時間后,就會消失,這與Toast一模一樣。

Google API Doc 官方說明:

http://developer.android.com/reference/android/support/design/widget/Snackbar.html

Android Design Support Library使用詳解

TextInputLayout

TextInputLayout作為一個父容器控件,包裝了新的EditText。通常,單獨的EditText會在用戶輸入第一個字母之后隱藏 hint提示信息,但是現在你可以使用TextInputLayout 來將EditText封裝起來,提示信息會變成一個顯示在EditText之上的floating label,這樣用戶就始終知道他們現在輸入的是什么。同時,如果給EditText增加監聽,還可以給它增加更多的floating label。

下面我們來看這與一個TextInputLayout:

<android.support.design.widget.TextInputLayout
        android:id="@+id/til_pwd"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</android.support.design.widget.TextInputLayout></pre>

一定要注意,他是把EditText包含起來的,不能單獨使用。

</div>

在代碼中,我們給它設置監聽:

final TextInputLayout textInputLayout = (TextInputLayout) findViewById(R.id.til_pwd);

    EditText editText = textInputLayout.getEditText();
    textInputLayout.setHint("Password");

    editText.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            if (s.length() > 4) {
                textInputLayout.setError("Password error");
                textInputLayout.setErrorEnabled(true);
            } else {
                textInputLayout.setErrorEnabled(false);
            }
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
        }

        @Override
        public void afterTextChanged(Editable s) {
        }
    });
}</pre><br />

這樣:顯示效果如下:

Android Design Support Library使用詳解

當輸入時:

Android Design Support Library使用詳解

這里需要注意的是,TextInputLayout的顏色來自style中的colorAccent的顏色:

<item name="colorAccent">#1743b7</item>

下面我們給出Google API Doc上的說明,了解TextInputLayout的詳細使用方法:

http://developer.android.com/reference/android/support/design/widget/TextInputLayout.html

Android Design Support Library使用詳解

Floating Action Button

floating action button 是一個負責顯示界面基本操作的圓形按鈕。Design library中的FloatingActionButton 實現了一個默認顏色為主題中colorAccent的懸浮操作按鈕,like this:

Android Design Support Library使用詳解

FloatingActionButton——FAB使用非常簡單,你可以指定在加強型FrameLayout里面——CoordinatorLayout,這個我們后面再將。關于FAB的使用,你可以把它當做一個button即可。

<android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_margin="@dimen/fab_margin"
        android:src="@drawable/ic_done"/>

通過指定layout_gravity就可以指定它的位置。同樣,你可以通過指定anchor,即顯示位置的錨點:
<android.support.design.widget.FloatingActionButton
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        app:layout_anchor="@id/app_bar"
        app:layout_anchorGravity="bottom|right|end"
        android:src="@android:drawable/ic_done"
        android:layout_margin="15dp"
        android:clickable="true"/>

除了一般大小的懸浮操作按鈕,它還支持mini size(fabSize=”mini”)。FloatingActionButton繼承自ImageView,你可以使用android:src或者 ImageView的任意方法,比如setImageDrawable()來設置FloatingActionButton里面的圖標。

http://developer.android.com/reference/android/support/design/widget/FloatingActionButton.html

TabLayout

Tab滑動切換View并不是一個新的概念,但是Google卻是第一次在support庫中提供了完整的支持,而且,Design library的TabLayout 既實現了固定的選項卡 – view的寬度平均分配,也實現了可滾動的選項卡 – view寬度不固定同時可以橫向滾動。選項卡可以在程序中動態添加:

TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
        tabLayout.addTab(tabLayout.newTab().setText("tab1"));
        tabLayout.addTab(tabLayout.newTab().setText("tab2"));
        tabLayout.addTab(tabLayout.newTab().setText("tab3"));

但大部分時間我們都不會這樣用,通常滑動布局都會和ViewPager配合起來使用,所以,我們需要ViewPager來幫忙:
mViewPager = (ViewPager) findViewById(R.id.viewpager);
        // 設置ViewPager的數據等
        setupViewPager();
        TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
        tabLayout.setupWithViewPager(mViewPager);

通過一句話setupWithViewPager,我們就把ViewPager和TabLayout結合了起來。

Android Design Support Library使用詳解

http://developer.android.com/reference/android/support/design/widget/TabLayout.html

NavigationView

NavigationView在MD設計中非常重要,之前Google也提出了使用DrawerLayout來實現導航抽屜。這次,在 support library中,Google提供了NavigationView來實現導航菜單界面,所以,新的導航界面可以這樣寫了:

<android.support.v4.widget.DrawerLayout
    android:id="@+id/dl_main_drawer"
    xmlns:android="

<!-- 你的內容布局-->
<include layout="@layout/navigation_content"/>

<android.support.design.widget.NavigationView
    android:id="@+id/nv_main_navigation"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    app:headerLayout="@layout/navigation_header"
    app:menu="@menu/drawer_view"/>

</android.support.v4.widget.DrawerLayout></pre>

其中最重要的就是這兩個屬性:

app:headerLayoutapp:menu

通過這兩個屬性,我們可以非常方便的指定導航界面的頭布局和菜單布局:

Android Design Support Library使用詳解

其中最上面的布局就是app:headerLayout所指定的頭布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="

<ImageView
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:layout_marginTop="16dp"
    android:background="@drawable/ic_user"/>

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="16dp"
    android:gravity="center"
    android:text="XuYisheng"
    android:textAppearance="@style/TextAppearance.AppCompat.Body1"
    android:textSize="20sp"/>

</LinearLayout></pre>
而下面的菜單布局,我們可以直接通過menu內容自動生成,而不需要我們來指定布局:

<?xml version="1.0" encoding="utf-8"?>

<menu xmlns:android=";

<group android:checkableBehavior="single">
    <item
        android:id="@+id/nav_home"
        android:icon="@drawable/ic_dashboard"
        android:title="CC Talk"/>
    <item
        android:id="@+id/nav_messages"
        android:icon="@drawable/ic_event"
        android:title="HJ Class"/>
    <item
        android:id="@+id/nav_friends"
        android:icon="@drawable/ic_headset"
        android:title="Words"/>
    <item
        android:id="@+id/nav_discussion"
        android:icon="@drawable/ic_forum"
        android:title="Big HJ"/>
</group>

<item android:title="Version">
    <menu>
        <item
            android:icon="@drawable/ic_dashboard"
            android:title="Android"/>
        <item
            android:icon="@drawable/ic_dashboard"
            android:title="iOS"/>
    </menu>
</item>

</menu></pre>
你可以通過設置一個OnNavigationItemSelectedListener,使用其 setNavigationItemSelectedListener()來獲得元素被選中的回調事件。它為你提供被點擊的 菜單元素 ,讓你可以處理選擇事件,改變復選框狀態,加載新內容,關閉導航菜單,以及其他任何你想做的操作。例如這樣:

private void setupDrawerContent(NavigationView navigationView) {
        navigationView.setNavigationItemSelectedListener(
                new NavigationView.OnNavigationItemSelectedListener() {
                    @Override
                    public boolean onNavigationItemSelected(MenuItem menuItem) {
                        menuItem.setChecked(true);
                        mDrawerLayout.closeDrawers();
                        return true;
                    }
                });
    }

可見,Google將這些東西封裝的非常易于使用了。

AppBarLayout

AppBarLayout跟它的名字一樣,把容器類的組件全部作為AppBar。like this:

Android Design Support Library使用詳解

這里就是把Toolbar和TabLayout放到了AppBarLayout中,讓他們當做一個整體作為AppBar。

<android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

    <android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</android.support.design.widget.AppBarLayout></pre><br />

http://developer.android.com/reference/android/support/design/widget/AppBarLayout.html

CoordinatorLayout

CoordinatorLayout是這次新添加的一個增強型的FrameLayout。在CoordinatorLayout中,我們可以在FrameLayout的基礎上完成很多新的操作。

Floating View

MD的一個新的特性就是增加了很多可懸浮的View,像我們前面說的Floating Action Button。我們可以把FAB放在任何地方,只需要通過:

android:layout_gravity="end|bottom"

來指定顯示的位置。同時,它還提供了layout_anchor來供你設置顯示坐標的錨點:

app:layout_anchor="@id/appbar"

創建滾動

CoordinatorLayout可以說是這次support library更新的重中之重。它從另一層面去控制子view之間觸摸事件的布局,Design library中的很多控件都利用了它。

一個很好的例子就是當你將FloatingActionButton作為一個子View添加進CoordinatorLayout并且將 CoordinatorLayout傳遞給 Snackbar.make(),在3.0及其以上的設備上,Snackbar不會顯示在懸浮按鈕的上面,而是FloatingActionButton 利用CoordinatorLayout提供的回調方法,在Snackbar以動畫效果進入的時候自動向上移動讓出位置,并且在Snackbar動畫地消 失的時候回到原來的位置,不需要額外的代碼。

</div>

官方的例子很好的說明了這一點:

<android.support.design.widget.CoordinatorLayout
        xmlns:android="

 <! -- Your Scrollable View -->
<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
              ...
              app:layout_scrollFlags="scroll|enterAlways">
 </android.support.design.widget.AppBarLayout>

</android.support.design.widget.CoordinatorLayout></pre>

其中,一個可以滾動的組件,例如RecyclerView、ListView( 這里需要注意的是,貌似只支持RecyclerView、ListView,如果你用一個ScrollView,是沒有效果的 )。如果:

1、給這個可滾動組件設置了layout_behavior

2、給另一個控件設置了layout_scrollFlags

那么,當設置了layout_behavior的控件滑動時,就會觸發設置了layout_scrollFlags的控件發生狀態的改變。

</div>

Android Design Support Library使用詳解

設置的layout_scrollFlags有如下幾種選項: