### 緒
今年的Google IO給我們android開發著帶來了三樣很屌很屌的library:
> 1. ASD(Android Support Design)
> 1. APL(Android Percent Layout)
> 1. DBL(Data Binding Library)
這三個庫都是很屌很屌的庫,第一個可以讓我們在低版本的Android上使用Material Design,第二個是為了更好的適配,提供了基于百分比的Layout;至于第三個,能讓Activity更好負責MVC中C的職責,讓我們開發者更少的去findViewById。
ok,首先我們來看看第一個庫,可能也是最主要的庫-ASD。
### ASD簡介
前面說了,ASD給我們提供了Material Design提供了向下的兼容,當然我們也需要學習幾個控件的使用,最后用一個實例的形式綜合一個需要學習的這幾個控件。
如何使用ASD?很簡單,在AS中添加以下一句話就ok啦。
> compile ‘com.android.support:design:22.2.0’
當然,我們在我們學習一些控件的時候還需要AppCompat Library。所以:
> compile ‘com.android.support:appcompat-v7:22.2.0’
### Snackbar
Snackbar我認為他是一個介于Dialog和Toast之前的玩意,可以在作為一種用戶選擇提醒時使用。Snackbar的使用很簡單,接下來我們以代碼和效果的形式快速預覽一下這玩意的使用。
~~~
public void click(View view) {
Snackbar.make(view, "真要點我?", Snackbar.LENGTH_LONG)
.setAction("真的!", new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "你真點我了!",
Toast.LENGTH_SHORT).show();
}
}).show();
}
~~~
來看看效果。

好吧,這玩意真的很簡單,對照著上面的代碼這下面的效果,肯定秒懂的。
### FloatingActionButton
在看看看另一個小控件,也許在項目中我們需要一個圓形的Button, 你可能會想到用自定義Shape的方式去做,但那樣文本的顯示不好居中,這時估計就想到用自定義控件去解決了。好吧,現在ASD給我們提供了FloatingActionButton可以輕松的創建圓形Button,而且更牛x的是FloatingActionButton具有更絢麗的效果。
FloatingActionButton的使用也很簡單,他直接繼承ImageView,所以ImageView的所有屬性都可以用在FloatingActionButton上。來,看看我們的demo:
~~~
<android.support.design.widget.FloatingActionButton
xmlns:app="http://schemas.android.com/apk/res-auto"
android:onClick="click"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_margin="0dp"
android:src="@drawable/add"
app:backgroundTint="#FF00FF00"
app:rippleColor="#FF0000FF"
app:borderWidth="0dp"
app:fabSize="normal"
app:elevation="10dp"
app:pressedTranslationZ="20dp"/>
~~~
簡單解釋一下命名空間為app的配置項。
1. app:backgroundTint是指定默認的背景顏色
2. app:rippleColor是指定點擊時的背景顏色
3. app:borderWidth border的寬度
4. app:fabSize是指FloatingActionButton的大小,可選normal|mini
5. app:elevation 可以看出該空間有一個海拔的高度
6. app:pressedTranslationZ 哈,按下去時的z軸的便宜
來看看FloatingActionButton的效果:

恩,不錯,但是有一個明顯的缺陷就是FloatingActionButton和Snackbar的配合不太好,這對于Material Design簡直就是恥辱!
想要解決這個問題,我們需要引入另一個控件。
### CoordinatorLayout
CoordinatorLayout這個控件的作用是讓它的子view更好的去協作,在接下來的時間里,我們基本都會用到這個控件,這里我們只是簡單的用CoordinatorLayout來包裹一下FloatingActionButton來達到和Snackbar更好協作的效果。修改我們的布局:
~~~
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true">
<android.support.design.widget.FloatingActionButton
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="0dp"
android:onClick="click"
android:layout_gravity="right"
android:src="@drawable/add"
app:backgroundTint="#FF00FF00"
app:borderWidth="0dp"
app:elevation="20dp"
app:fabSize="normal"
app:pressedTranslationZ="10dp"
app:rippleColor="#FF0000FF" />
</android.support.design.widget.CoordinatorLayout>
~~~
此時的效果:

可以看到,當Snackbar顯示的時候,Button自動往上移動了,而當Snackbar消失以后,Button又回到了原來的位置。
### TabLayout
TabLayout也是一個好東西,有了它我們再也不需要使用麻煩人的PagerTabStrip了,也不需要使用自定義view的形式來達到效果。首先來看看簡單用法。
~~~
<android.support.design.widget.TabLayout
android:id="@+id/tl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabIndicatorColor="#FFFF0000"
app:tabSelectedTextColor="#FF0000FF"
app:tabTextColor="#FFFFFFFF"
app:tabMode="scrollable"
app:tabGravity="fill"/>
~~~
還是只解釋app命名空間的。
1. app:tabIndicatorColor tab的指示符顏色
2. app:tabSelectedTextColor 選擇tab的文本顏色
3. app:tabTextColor 普通tab字體顏色
4. app:tabMode 模式,可選fixed和scrollable fixed是指固定個數,scrollable是可以橫行滾動的(逼格高)
5. app:tabGravity 對齊方式,可選fill和center
在來看看activity的代碼:
~~~
final TabLayout tabLayout = (TabLayout) findViewById(R.id.tl);
for(int i=0;i<20;i++) tabLayout.addTab(tabLayout.newTab().setText("TAB" + i));
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
Toast.makeText(MainActivity.this, tab.getText(), Toast.LENGTH_SHORT).show();
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
~~~
首先,獲取該控件,然后一個for循環添加20個tab,使用:
> tabLayout.addTab(tabLayout.newTab().setText(“TAB”));
添加新的tab。然后通過setOnTabSelectedListener來設置tab的item點擊事件。so easy。 來看看效果。

### AppBarLayout
AppBarLayout這個控件也是讓子view共同協作的,它和CoordinatorLayout的區別在于:
> AppBarLayout是在效果上的協作,用AppBarLayout包裹的子view會以一個整體的形式作為AppBar。
> CoordinatorLayout是在行為上的一種協作,尤其是在滾動的協作上,可以說非常完美(額, 也不是那么完美)
首先來看一下我們要做的效果吧。

從效果圖上看,Toolbar和TabLayout成為了一體。
再來看看我們的代碼
~~~
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/tb"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"/>
<android.support.design.widget.TabLayout
android:id="@+id/tl"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
~~~
僅僅是用AppBarLayout包裹了一下Toolbar和TabLayout。細心的朋友可能看到了我們的TabLayout的背景也變了顏色,這里是因為我們在theme中設置了:
~~~
<item name="colorPrimary">#FF00FF00</item>
~~~
那上面那個白色背景的呢? 好難看!難道沒有設置嗎?其實我也設置了,但是沒有體現到TabLayout上,從這里也驗證了我們上面所說的:
> AppBarLayout是在效果上的一種協作
既然我們驗證了該假設,那么順便來驗證一下
> CoordinatorLayout是在行為上的一種協作
的假設吧。 修改代碼:
~~~
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/tb"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways"/>
<android.support.design.widget.TabLayout
android:id="@+id/tl"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="50dp"
android:text="Loader最帥"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="50dp"
android:text="Loader最帥"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="50dp"
android:text="Loader最帥"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="50dp"
android:text="Loader最帥"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="50dp"
android:text="Loader最帥"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="50dp"
android:text="Loader最帥"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="50dp"
android:text="Loader最帥"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="50dp"
android:text="Loader最帥"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="50dp"
android:text="Loader最帥"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="50dp"
android:text="Loader最帥"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="50dp"
android:text="Loader最帥"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="50dp"
android:text="Loader最帥"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="50dp"
android:text="Loader最帥"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="50dp"
android:text="Loader最帥"/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
~~~
對比上面的代碼,首先我們添加了app的命名空間,為什么要添加這個?因為我們下面要用到!(靠!什么回答)
而且,我們給Toolbar增加了一條配置:
~~~
app:layout_scrollFlags="scroll|enterAlways"
~~~
表示這個控件是可以滾出屏幕的,而且是隨時可以再顯示
layout_scrollFlags的其他取值有:
1. scroll 誰要滾出屏幕,誰就設置這個值
2. enterAlways 其他向上滑動時,可以立即顯示出來
3. exitUntilCollapsed 將關閉滾動直到它被折疊起來(有 minHeight) 并且一直保持這樣
4. enterAlwaysCollapsed 定義了 View 是如何回到屏幕的,當你的 view 已經聲明了一個最小高度(minHeight) 并且你使用了這個標志,你的 View 只有在回到這個最小的高度的時候才會展開,只有當 view 已經到達頂部之后它才會重新展開全部高度。
(以上解釋,參考了其他文章[目測也是翻譯的官方文檔])
在CoordinatorLayout中我們還引入了另外一個新的控件:
NestedScrollView,這個view其實是ScrollView的增強版,增強在哪呢?他支持屬性:
~~~
app:layout_behavior="@string/appbar_scrolling_view_behavior"
~~~
這條語句的作用是標識他要一起來寫作完成scroll的效果。換句話說,上面的滾出屏幕的效果要配合一個可以滾動的View,并且得設置了該屬性后才可以。(至少你得告訴人家,誰要滾出去,滑動誰時才滾出去吧)
好吧,來看看此時的效果:

看到了吧,我們在滑動下面的時候,Toolbar自覺的滾出了屏幕,而且在往上滑動的時候,Toolbar立馬出現了,這就是enterAlways的功勞。
### CollapsingToolbarLayout
最后,我們來看一個逼格同樣高的控件:CollapsingToolbarLayout。
該控件的的子view必須要有Toolbar,他的作用就是提供一個可折疊的標題欄。通常情況下,該控件會和上面我們說的一些控件搭配使用,達到一種**固定的效果**。
CollapsingToolbarLayout本身的使用很簡單,只是他的子view需要設置很多屬性來達到這種效果,下面,我們就提供一個demo實例,來學習一下CollapsingToolbarLayout的使用,順便復習一下上面所學到的一些控件。我們來實現一個這樣的UI:

首先來分析一下,最直觀的,可以看到有一個行為上的協作, 那肯定需要`CoordinatorLayout`這個控件,而且還會有一個效果上的協作,那肯定是`AppBarLayout`啦,當然,細心的朋友可能還會看出來,那個圖片和Toolbar會有一種視差的效果,而且整個banner部分是一種折疊的效果,這就需要`CollapsingToolbarLayout`這個控件了。
來說一下`CoolapsingToolbarLayout`,這個控件必須要有一個Toolbar的子view,而且它將作為`AppBarLayout`的唯一直接子view使用,它提供了一個可以折疊的AppBar,并且還提供一種視差的效果。下面就讓我們從例子中感受`CoolapsingToolbarLayout`的使用。
~~~
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/ctl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/banner"
android:scaleType="fitXY"
app:layout_collapseMode="parallax"/>
<android.support.v7.widget.Toolbar
android:id="@+id/tb"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true">
<android.support.design.widget.FloatingActionButton
android:onClick="add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_margin="0dp"
android:src="@drawable/add"
app:backgroundTint="#FF00FF00"
app:rippleColor="#FF0000FF"
app:borderWidth="0dp"
app:fabSize="normal"
app:elevation="10dp"
app:pressedTranslationZ="20dp"/>
</android.support.design.widget.CoordinatorLayout>
</RelativeLayout>
~~~
分析一下這個布局,最外層一個`RelativeLayout`他包含了兩個`CoordinatorLayout` , 第二個`CoordinatorLayout`比較簡單就是包括了一個`FloatingActionButton`,這樣的用法可以參考博客上面講的。
我們的重點是放在第一個`CoordinatorLayout`上。它有兩個直接子view,和我們說的一樣,一個提供滾出效果,一個提供滾動的效果。接下來一個`AppBarLayout`將`ImageView`和`Toolbar`作為了AppBar。可是它不是直接包含了這兩個小控件,而是通過`CollapsingToolbarLayout`,而且表示滾動標識的`app:layout_scrollFlags="scroll|exitUntilCollapsed"`也是賦值給了`CollapsingToolbarLayout`,在這里思考一下,這樣整個`CoolapsingToolbarLayout`將會作為一個整體滾出界面。可是看效果并不是啊, `Toolbar`明明還在那,那么接下來,我們來觀察一下這個`ImageView`和`Toolbar`有什么神奇之處:
~~~
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/banner"
android:scaleType="fitXY"
app:layout_collapseMode="parallax"/>
<android.support.v7.widget.Toolbar
android:id="@+id/tb"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"/>
~~~
ImageView有一條屬性`app:layout_collapseMode="parallax"`表示這個ImageView以視差的形式折疊(效果上看著貌似就是有點小偏移)。
Toolbar的`app:layout_collapseMode="pin"`表示Toolbar在折疊的過程中會停靠頂部(pin的意思是釘住)。
最后我們使用了一個`RecyclerView`,并且給這個控件設置`app:layout_behavior="@string/appbar_scrolling_view_behavior"`,至于`RecyclerView`如果你不會用,請自行*網補*。
繼續…, 繼續觀察上面的效果,在滑動的過程中有一個蛋疼的顏色–綠色,它是一個從無到有的過程,是一個漸變的效果,它是怎么控制的呢?
來看看`CollapsingToolbarLayout`它有一條屬性是:`app:contentScrim="?attr/colorPrimary"`,設置這條屬性,在滑動的過程中,會自動變化到該顏色。
最后,要注意一下,**現在我們不能給`Toolbar`設置標題了,而是給`CollapsingToolbarLayout`設置標題,可以看到標題在滾動的過程中會有一個大小的變化。**
現在這個效果的逼格已經很高了,但是我們還不滿足,那個綠色太TMD的難看了, 哎?能不能跟隨那個圖片的顏色?這樣看起來逼格是不是更高!! 哈哈,完全可以!這需要我們再引用另一個庫`Palette`,關于`Palette`的使用,可以看我之前的博客:[《Android5.0之Palette簡單實用》](http://blog.csdn.net/qibin0506/article/details/42063913)。
我們在activity中這么使用:
~~~
final CollapsingToolbarLayout ctl = (CollapsingToolbarLayout) findViewById(R.id.ctl);
ctl.setTitle("Cool UI");
...
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.banner);
Palette.generateAsync(bmp, new Palette.PaletteAsyncListener() {
@Override
public void onGenerated(Palette palette) {
Palette.Swatch swatch = palette.getDarkMutedSwatch();
ctl.setContentScrimColor(swatch.getRgb());
}
});
~~~
來看看此時的效果:

`CollapsingToolbarLayout`的ContentScrim是我們從那個Bitmap上取的。好了,就這么多吧,累尿了,休息去了。
源碼下載: [demo下載](http://download.csdn.net/detail/qibin0506/8892329)
- 前言
- 高逼格UI-ASD(Android Support Design)
- AndroidSupportDesign之TabLayout使用詳解
- RecyclerView的高級用法——定制動畫
- Android官方數據綁定框架DataBinding(一)
- Android官方數據綁定框架DataBinding(二)
- 你所不知道的Activity轉場動畫——ActivityOptions
- RecyclerView+ImageLoader打造多選圖庫
- Android Material Design動畫
- RecyclerView添加Header的正確方式
- CoordinatorLayout高級用法-自定義Behavior