MaterialDesign
標簽(空格分隔): Android
ToolBar###
可以看一下自己寫的demo,名字叫TestMaterial
這個demo主要參考文章:博客一
也可以看一下這篇文章,知道一下開發過程中的坑,博客二
關于ToolBar與ActionBar的比較,還有ToolBar的用法博客三
ToolBar的一些特技:博客四
注意事項
1、不要把兼容包中的 Material Theme 使用到 Activity 上
兼容包中的 Material Theme 是提供給 AppCompatActivity 使用的
2、兼容包中與 Android 5.x 中的 Material Theme 在 style 中設置有區別
沉浸式狀態欄###
第一種:實現toolBar與狀態欄同色
請看鴻洋博客
實現原理請看為什么根布局加了一個與狀態欄等高的View,就可以將那個新增的view放到StatusBar的位置,實現沉浸式布局
這篇文章當中還有一些開發過程中的坑
第二種:實現用圖片覆蓋狀態欄
請見博客中的ImageTranslucentTheme
注意:StatusBar和NavigationBar都是系統級別的空間,開發者不可以像TextView那樣隨意調用,但是可以在Style.xml中設置
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
分別將StatusBar和NavigationBar變成透明
DrawerLayout實現抽屜菜單###
注意DrawerLayout不是materialDesign推出的,但是稱用于搭配MaterialDesign####
效果一:抽屜菜單覆蓋AppBar
1、使用toolBar實現:請參考這篇博客的效果一的有關段落
2、使用ActionBAr實現。其實這當中的原理跟使用ToolBar來實現差不多,只是ToolBar與ActionBar的區別而已,只要把DrawerLayout 寫在主布局的的最外層,這樣就可以是實現抽屜菜單覆蓋AppBar
效果二:抽屜菜單顯示在AppBar下方
1、使用ActionBAr實現:請參考這篇博客的效果二的有關段落
把DrawerLayout 寫在主布局的的最外層,可是使用的是ActionBAr,所以抽屜菜單不會覆蓋AppBar
這篇翻譯文檔也是實現抽屜菜單顯示在AppBar下方
2、使用toolBar實現。只要不把DrawerLayout 寫在主布局的的最外層,然后記得ToolBar的布局也不要被DrawerLayout包裹,這樣就可以是實現抽屜菜單顯示在AppBar下方
現在新出的Design Support Library,可以讓在6.0之前的版本可以更加方便的使用materialDesign的一些空間或者特性,例如里面的Navigation View通過使用menu,headerLayout等屬性進一步簡化了抽屜式導航框架的使用:
RippleDrawable###
視圖的水波紋效果,RippleDrawable 其實就可以當作一個 Drawable,
單一效果:
在控件中直接使用
android:attr/selectableItemBackground 有界限的波紋(低版本也可以使用)
android:attr/selectableItemBackgroundBorderless 可以超出視圖區域的波紋(minSdkVersion至少要21才能使用)
更多的效果:
drawable 文件夾中定義一個以 <ripple> 為根控件的 xml 文件,然后作為一個控件的背景即可。具體請看博客中的RippleDrawable部分【這個方法低版本不可以使用,只能用于5.0或之上】
Material Design動畫###
還沒了解
palette###
最新的用法看這篇博客
無論是5.0還是5.0以下的都可使用,要引入[v7 support libraries r21],并且使用Theme.AppCompat主題
應用場景:
說Palette之前先說下前面提到的Pager。ViewPager是什么大家應該都是知道的了,一般ViewPager、xxxTabStrip、Fragment三個好基友是一起出現的。這里的xxxTabStrip是使用Github上的PagerSlidingTabStrip。當我們的Pager切換時伴隨著Fragment的變化,而Fragment里的內容一般是不同的,所以每個Fragment里的一般視覺效果也是不同的,所以我們可以用Palette來去提取Fragment中的主色調,那Fragment中的拿什么給Palatte去提取顏色呢,這就需要自己根據自己的情況來決定的。比如我這個demo里,Fragment就一個TextView和給Fragment設了背景,那么我就可以把背景的圖片給Palette去提取顏色了。
視圖與陰影###
在5.0中加入了z值屬性,對應垂直方向上的高度變化
Z值由elevation與translation組成,
在layout中使用 android:elevation屬性去定義
在代碼中使用 View.setElevation 方法去定義
設置視圖的translation,可以使用View.setTranslationZ方法
(改變視圖高度的屬性只支持5.0)
或者在屬性動畫中view.annimate().translationZ(100);加入一個Z高度變化的動畫。
新的ViewPropertyAnimator.z和ViewPropertyAnimator.translationZ方法可以設置視圖的elevation值
(是否支持5.0以下的版本,還有待驗證!!!!)
可以參考一下這篇博客相應的部分
應用場景:
translationZ允許你創建一個動畫暫時的反應出View的高度值(elevation)變化。
這對于響應觸摸手勢很有用處,請看下面代碼
(官方Demo中的代碼):
int action = motionEvent.getActionMasked();
switch (action) {
case MotionEvent.ACTION_DOWN:
Log.d(TAG, "ACTION_DOWN on view.");
view.setTranslationZ(120);
break;
case MotionEvent.ACTION_UP:
Log.d(TAG, "ACTION_UP on view.");
view.setTranslationZ(0);
break;
default:
return false;
}
應用場景圖:


Tinting(著色)###
Android L還有一個獨特的特點就是現在可以定義圖片的alpha遮罩,并且可以輕松的使用android:tint屬性去調整色調。
使用tint屬性給背景調整不同顏色的例子:
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal">
<ImageView
...
android:src="@drawable/xamarin_white"
android:background="@drawable/mycircle"/>
<ImageView
...
android:src="@drawable/xamarin_white"
android:background="@drawable/mycircle"
android:tint="#2C3E50"/>
<ImageView
...
android:src="@drawable/xamarin_white"
android:background="@drawable/mycircle"
android:tint="#B4BCBC"/>
</LinearLayout>

Clipping Views(裁剪視圖)###
略
RecyclerView###
參考鴻洋大神博客,但是這篇博客的Click and LongClick請與泡在網上的日子的這篇博客一起看
可以引入支持包兼容低版本
dependencies {
compile 'com.android.support:appcompat-v7:21.0.+'
compile 'com.android.support:cardview-v7:21.0.+'
compile 'com.android.support:recyclerview-v7:21.0.+'
}
以下的內容參考張濤博客
RecyclerView重要的五個類:####
RecyclerView.LayoutManager 負責Item視圖的布局的顯示管理
RecyclerView.ItemDecoration 給每一項Item視圖添加子View,例如可以進行畫分隔線之類
RecyclerView.ItemAnimator 負責處理數據添加或者刪除時候的動畫效果
RecyclerView.Adapter 為每一項Item創建視圖
RecyclerView.ViewHolder 承載Item視圖的子布局
ItemDecoration 工作原理
temDecoration 是為了顯示每個 item 之間分隔樣式的。它的本質實際上就是一個 Drawable。當 RecyclerView 執行到 onDraw() 方法的時候,就會調用到他的 onDraw(),這時,如果你重寫了這個方法,就相當于是直接在 RecyclerView 上畫了一個 Drawable 表現的東西。 而最后,在他的內部還有一個叫getItemOffsets()的方法,從字面就可以理解,他是用來偏移每個 item 視圖的。當我們在每個 item 視圖之間強行插入繪畫了一段 Drawable,那么如果再照著原本的邏輯去繪 item 視圖,就會覆蓋掉 Decoration 了,所以需要getItemOffsets()這個方法,讓每個 item 往后面偏移一點,不要覆蓋到之前畫上的分隔樣式了。ItemAnimator工作原理
每一個 item 在特定情況下都會執行的動畫。說是特定情況,其實就是在視圖發生改變,我們手動調用notifyxxxx()的時候。通常這個時候我們會要傳一個下標,那么從這個標記開始一直到結束,所有 item 視圖都會被執行一次這個動畫。Adapter工作原理(與listView的adapter不同)
首先是適配器,適配器的作用都是類似的,用于提供每個 item 視圖,并返回給 RecyclerView 作為其子布局添加到內部。
但是,與 ListView 不同的是,ListView 的適配器是直接返回一個 View,將這個 View 加入到 ListView 內部。而 RecyclerView 是返回一個 ViewHolder 并且不是直接將這個 holder 加入到視圖內部,而是加入到一個緩存區域,在視圖需要的時候去緩存區域找到 holder 再間接的找到 holder 包裹的 View。ViewHolder
每個 ViewHolder 的內部是一個 View,并且 ViewHolder 必須繼承自RecyclerView.ViewHolder類。 這主要是因為 RecyclerView 內部的緩存結構并不是像 ListView 那樣去緩存一個 View,而是直接緩存一個 ViewHolder ,在 ViewHolder 的內部又持有了一個 View。既然是緩存一個 ViewHolder,那么當然就必須所有的 ViewHolder 都繼承同一個類才能做到了。
緩存與復用的原理:####

RecyclerView 的內部維護了一個二級緩存,滑出界面的 ViewHolder 會暫時放到 cache 結構中,而從 cache 結構中移除的 ViewHolder,則會放到一個叫做 RecycledViewPool 的循環緩存池中。
順帶一說,RecycledView 的性能并不比 ListView 要好多少,它最大的優勢在于其擴展性。但是有一點,在 RecycledView 內部的這個第二級緩存池 RecycledViewPool 是可以被多個 RecyclerView 共用的,這一點比起直接緩存 View 的 ListView 就要高明了很多,但也正是因為需要被多個 RecyclerView 公用,所以我們的 ViewHolder 必須繼承自同一個基類(即RecyclerView.ViewHolder)。
默認的情況下,cache 緩存 2 個 holder,RecycledViewPool 緩存 5 個 holder。對于二級緩存池中的 holder 對象,會根據 viewType 進行分類,不同類型的 viewType 之間互不影響。
CardView###
它是一個使用了Material Desgin風格的FrameLayout,只不過比普通的FrameLayout多了圓角背景和陰影效果。所以它常用作ListView 或者 RecyclerView等視圖Item的布局容器;
使用場景請看這篇博客有關CardView的部分
可以引入支持包支持低版本
dependencies {
compile 'com.android.support:appcompat-v7:21.0.+'
compile 'com.android.support:cardview-v7:21.0.+'
compile 'com.android.support:recyclerview-v7:21.0.+'
}
Meterial Dialog###
關于Meterial Dialog可以看一下這篇博客,當中也有講palette和CardView
Android Support Library v22.1 中開始提供了 Material 風格的 Dialog 控件(官方提供的,很好,很強大)
其實就是V7包的22版本
Activity的過渡動畫###
取代overpendingtranstion。
可是只支持5.0版本
基本用法可以看看《群英傳》
Circular Reveal###
只支持5.0版本
參考網上資料
View state changes Animation###
根據視圖狀態改變來設置一個視圖的狀態切換動畫
只支持5.0版本
- StateListAnimator
可以讓你定義動畫集,能在view狀態改變時工作。在切換狀態的時候有個切換動畫,不會像以前那么生硬!參考博客 - animated-selector
Curved motion(曲線運動)###
只支持5.0版本
Material design中的動畫依靠曲線,這個曲線適用于時間插值器和控件運動模式。
PathInterpolator類是一個基于貝塞爾曲線(Bézier curve)或路徑(Path)對象上的新的插值器。
Notification###
維護兼容性###
請看官方中文文檔
Theme.AppCompat 主題中提供了這些組件的 Material Design style:
EditText
Spinner
CheckBox
RadioButton
SwitchCompat
CheckedTextView
Material適配詳解###
請看泡在網上的日子博客
Android Design Support Library
關于Android Design Support Library的使用請看這兩篇博客的大概盤點:博客一、博客二
導讀:
這個兼容庫很容易和之前的 Android Support Library 22.1混淆,都是兼容庫,區別是這個庫多了個Design。 Android Support Library 22.1只是支持了一些基本控件的材料設計化,但是這個庫更多的是對一些特效的實現,這個庫和github上的很多開源項目是有很大關系的,material design的很多效果,同一種效果在github上有太多的實現,現在官方把部分效果標準化了。
- 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();
- Navigation View——更好地實現抽屜菜單
簡單例子:
<android.support.v4.widget.DrawerLayout
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:fitsSystemWindows="true">
<!-- your content layout -->
<android.support.design.widget.NavigationView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/drawer_header"
app:menu="@menu/drawer"/>
</android.support.v4.widget.DrawerLayout>
//app:headerLayout - 控制頭部的布局,
//app:menu - 導航菜單的資源文件(也可以在運行時配置)。
NavigationView處理好了和狀態欄的關系,可以確保NavigationView 在API21+設備上正確的和狀態欄交互。不用擔心會覆蓋住StatusBar!!
以通過設置一個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;
}
});
}
剩下的控件就不一一列出來了
Goolge新的開源項目——FlexboxLayout###
簡單使用:博客