原文地址:http://blog.csdn.net/lavor_zl/article/details/51295364
谷歌在推出Android5.0的同時推出了全新的設計Material Design,谷歌為了給我們提供更加規范的MD設計風格的控件,在2015年IO大會上推出了Design支持包,Design常用的新控件有下面8種。
1. TextInputLayout(文本輸入布局)
TextInputLayout的作用是將EditText包裹起來,使得EditText的android:hint
屬性的值以浮動標簽的形式顯示出來,同時可以通過setErrorEnabled(boolean)
和setError(CharSequence)
來顯示錯誤信息。
在xml文件中定義TextInputLayout:
<android.support.design.widget.TextInputLayout
android:id="@+id/text_input_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:hint="作者"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.TextInputLayout>
在java文件中設置錯誤信息:
this.textinputlayout.setErrorEnabled(true);
this.textinputlayout.setError("作者不能包含標點符號");
2. TabLayout(選項卡布局)
Tablayout提供橫向布局顯示選項卡,它取代了ActionBar添加選項卡的方式。它經常與ViewPager配合使用。
在xml文件中定義TabLayout:
<android.support.design.widget.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.design.widget.TabLayout>
在java文件中添加選項卡:
tablayout.addTab(tablayout.newTab().setText("Tab1"));
tablayout.addTab(tablayout.newTab().setText("Tab2"));
tablayout.addTab(tablayout.newTab().setText("Tab3"));
Tablayout與ViewPager配合使用:
- tablayout.setupWithViewPager();
這種方法下面選項卡的標題由ViewPager決定
- viewPager.addOnPageChangeListener(new TabLayoutOnPageChangeListener(tablayout));
這種方法下面選項卡的標題由Tablayout決定
3. Snackbar
Snackbar提供比Toast輕量級的反饋操作,谷歌推薦使用Snackbar替代Toast。Snackbar顯示或者消失的時候有一個回調方法。
//tablayout是Snackbar努力找到持有自己的視圖
Snackbar snackbar=Snackbar.make(tablayout,"我是Snackbar",Snackbar.LENGTH_LONG);
//為snackbar設置回調方法
snackbar.setCallback(new Snackbar.Callback() {
@Overridepublic void onDismissed(Snackbar snackbar, int event) {
super.onDismissed(snackbar, event);
Log.i("Snackbar","Snackbar消失了");
}
@Overridepublic void onShown(Snackbar snackbar) {
super.onShown(snackbar);
Log.i("Snackbar","Snackbar出現了");
}
});
//顯示snackbar
snackbar.show();
4. FloatingActionButton(浮動按鈕)
FloatingActionButton在用戶界面中通常是一個漂浮的小圓圈,它有自身獨特的動態效果,比如變形、彈出、位移等等。
FloatingActionButton默認的背景顏色是主題的colorAccent
,還可以通過app:backgroundTint
來修改,也可以通過android:backgroundTint
屬性修改,但是android:backgroundTint
屬性只能在API21及以上使用。
FloatingActionButton的定義很簡單:
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab_add_task"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_add_circle_pink_400_18dp"
app:backgroundTint="@color/blue"
app:fabSize="normal" />
5. NavigationView(導航視圖)
NavigationView顧名思義是導航視圖,一般與DrawerLayout(抽屜布局)聯合使用。它為應用程序提供標准的導航菜單,菜單內容可以通過一個xml菜單文件來填充。
在xml文件中定義NavigationView
<android.support.design.widget.NavigationView
android:id="@+id/navigation_menu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/drawer_navigation_header"
app:menu="@menu/drawer_navigation_menu"
/>
app:headerLayout
:表示NavigationView的頭部布局app:menu
:表示NavigationView的導航菜單
頭部布局很簡單就是一個普通的布局文件,我們來看看導航菜單的定義吧。
<?xml version="1.0" encoding="utf-8"?><menu xmlns:android="http://schemas.android.com/apk/res/android"><group android:checkableBehavior="single"><item android:id="@+id/drawer_home"android:icon="@drawable/ic_home_black_24dp"android:title="@string/home" /><item android:id="@+id/section"android:icon="@drawable/ic_more_horiz_black_24dp"android:title="分組1"><menu><item android:id="@+id/drawer_favourite"android:icon="@drawable/ic_favorite_black_24dp"android:title="@string/favourite" /><item android:id="@+id/drawer_downloaded"android:icon="@drawable/ic_file_download_black_24dp"android:title="@string/downloaded" /></menu></item><item android:id="@+id/section2"android:title="分組2"><menu><item android:id="@+id/drawer_more"android:icon="@drawable/ic_more_horiz_black_24dp"android:title="@string/more" /><item android:id="@+id/drawer_settings"android:icon="@drawable/ic_settings_black_24dp"android:title="@string/settings" /></menu></item></group></menu>
我們來分析一下該xml文件: group
:表示組 android:checkableBehavior
:可以接受下面3種值
- single
組中只有一個菜單項可以checked
- all
組中所有菜單項可checked
- none
組中所有菜單項都不可checked
item
:表示項,下面可以有子菜單, item
與item
會默認有分割線分開。
6. AppBarLayout(應用程序欄布局)
AppBarLayout是一個垂直的線性布局,實現了Material Design概念的應用程序欄,支持滾動手勢。
它的子視圖提供所需的滾動行為:
- 在java文件中通過setScrollflags(int)
設置
- 在xml布局文件中通過““
AppBarLayout經常作為CoordinatorLayout的直接子視圖使用。
AppBarLayout的作用是把AppBarLayout包裹的內容都作為應用程序欄。
我們在xml文件中定義一個AppBarLayout,AppBarLayout下面有一個Toolbar和一個TabLayout
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
app:layout_scrollFlags="scroll|enterAlways"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:fitsSystemWindows="true"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.design.widget.TabLayout>
</android.support.design.widget.AppBarLayout>
我們向上滑動AppBarLayout看看有什么效果
此時我們發現Toolbar被隱藏了,我們再在向下滑動AppBarLayout,發現Toolbar又出來了。
這就相當於是一個可以折疊的工具欄。
這是因為Toolbar設置了app:layout_scrollFlags="scroll|enterAlways"
。 app:layout_scrollFlags
屬性里面必須至少啟用scroll
這個flag,這樣這個view才會滾動出屏幕,否則它將一直固定在頂部。可以使用的其他flag有:
- enterAlways: 一旦向下滾動,不管是否繼續滾動,該view都會變為可見。
- enterAlwaysCollapsed: 這個屬性是作為enterAlways
屬性的附加屬性使用的,這個flag定義的是何時進入,,當你定義了一個minHeight
,並且定義了enterAlways
屬性,那么view將在到達這個最小高度的時候開始顯示,並且從這個時候開始慢慢展開,當滾動到頂部的時候展開完。
- exitUntilCollapsed: 這個flag時定義何時退出,當你定義了一個minHeight
,這個view將在滾動到達這個最小高度的時候開始慢慢消失。
app:layout_scrollFlags
這個屬性其實一般就只有下面4種使用情況,我們來一一講解。
1. app:layout_scrollFlags="scroll"
- 該view顯示時,只有在滾動視圖頂部向上滾動時,該view才會慢慢消失。
- 該view消失后,只有在滾動視圖頂部向下滾動時,該view才會慢慢出現。
2. app:layout_scrollFlags="scroll|enterAlways"
- 該view顯示時,只要滾動視圖向上滾動,該view就會慢慢消失。
- 該view消失后,只要滾動視圖向下滾動,該view就會慢慢出現。
3. app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
,同時該view設置了minHeight
- 該view顯示時,只要滾動視圖向上滾動,該view就會慢慢消失。
- 該view消失后,只要滾動視圖向下滾動,該view就會慢慢出現:
- 當滾動視圖不在頂部時,該view只會慢慢出現
minHeight
高度的內容 - 當滾動視圖在頂部時,該view會慢慢出現全部的內容
- 當滾動視圖不在頂部時,該view只會慢慢出現
4. app:layout_scrollFlags="scroll|exitUntilCollapsed"
,同時該view設置了minHeight
- 該view顯示時,只有在滾動視圖頂部向上滾動時,該view才會慢慢消失,但不會完全消失,會保留着
minHeight
高度的內容依然可見。 - 該view消失后,只有在滾動視圖頂部向下滾動時,該view才會慢慢出現。
注意:只有AppBarLayout第一個設置app:layout_scrollFlags
屬性的直接子視圖可以折疊
7. CoordinatorLayout(協作布局)
CoordinatorLayout是一個超級強大的FrameLayout。
CoordinatorLayout有兩個主要用途:
- 作為頂級應用程序的裝飾或着色布局
- 作為特定交互的容器,與一個或多個孩子視圖交互
CoordinatorLayout作為一個父視圖,它的孩子可以通過特定的行為與CoordinatorLayout別的孩子交互。
當視圖類作為CoordinatorLayout的孩子時,可以定義特定的行為。
- 在xml文件中使用app:layout_behavior
。
- 在view類使用@DefaultBehavior
修飾符來添加注解。
在CoordinatorLayout的孩子視圖FloatingActionButton中設置 app:layout_behavior="com.lavor.designnewcontrols.ScrollBehavior"
com.lavor.designnewcontrols.ScrollBehavior
的代碼如下:
public class ScrollBehavior extends CoordinatorLayout.Behavior<View> {/** * 因為是在XML中使用app:layout_behavior定義靜態的這種行為, * 必須實現一個構造函數使布局的效果能夠正常工作。 * 否則 Could not inflate Behavior subclass error messages. */
public ScrollBehavior(Context context, AttributeSet attrs) {
super();
}
/** * 開始滾動時 */@Override
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {
//如果child可見,設置其不可見if(child.getVisibility()==View.VISIBLE){
((FloatingActionButton)child).hide();
}
//如果child不可見,設置其可見else{
((FloatingActionButton)child).show();
}
return super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
}
}
CoordinatorLayout的子視圖可以設置app:layout_anchor
屬性,該屬性的值對應着CoordinatorLayout中其它子視圖(不能是該視圖本身或其子視圖)的android:id
屬性。這可以將浮動視圖放在任意地方。
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab_add_task"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_add_circle_pink_400_18dp"
app:fabSize="normal"
app:layout_anchor="@id/toolbar"
app:layout_anchorGravity="bottom|right|end" />
我們將FloatingActionButton(浮動按鈕)放置到Toolbar的右下方結束位置。
注意:使用CoordinatorLayout時,AppBarLayout下面有一個RecyclerView時,RecyclerView會與AppBarLayout重疊,因為CoordinatorLayout是幀布局。
要解決這個問題可以設置RecyclerView的app:layout_behavior="@string/appbar_scrolling_view_behavior"
,其實此時該屬性的值就是android.support.design.widget.AppBarLayout$ScrollingViewBehavior
8. CollapsingToolbarLayout(折疊工具欄布局)
CollapsingToolbarLayout作用是提供了一個可以折疊的Toolbar,它繼承至FrameLayout,它通常是作為AppBarLayout直接子視圖使用。它提供的折疊工具欄更高級,還可以制造視覺差。
對於CollapsingToolbarLayout,我們通常是這樣使用的,將其定義為AppBarLayout的第一個直接子視圖,並且其自身定義如下:它里面有一個ImageView和一個Toolbar,形成折疊工具欄。
<android.support.design.widget.CollapsingToolbarLayout
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="48dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:src="@drawable/bg"
android:scaleType="centerCrop"
app:layout_collapseMode="parallax"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="60dp"
app:layout_collapseMode="pin"
android:background="?attr/colorPrimary"
android:fitsSystemWindows="true">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
- 首先,CollapsingToolbarLayout要設置
app:layout_scrollFlags
,這個屬性在介紹AppBarLayout的時候已經講過了,app:contentScrim
表示滾動達到一定閾值后Toolbar的背景顏色,app:expandedTitleMarginStart
設置擴張時候(還沒有收縮時)title向左填充的距離。 - 其次, ImageView的
app:layout_collapseMode
屬性的值為parallax
,設置為這個模式時,在內容滾動時,CollapsingToolbarLayout中的View(比如ImageView)也可以同時滾動,實現視差滾動效果,通常和app:layout_collapseParallaxMultiplier
屬性(設置視差因子)搭配使用,其值為0~1。 - 最后,Toolbar的
app:layout_collapseMode
屬性的值為pin
,設置為這個模式時,當CollapsingToolbarLayout完全收縮后,Toolbar還可以保留在屏幕上。
程序源代碼下載:一個Activity掌握Design新控件
關於Design新控件國外有一篇不錯的教程:https://guides.codepath.com/android/Handling-Scrolls-with-CoordinatorLayout
該教程源代碼的github地址:https://github.com/chrisbanes/cheesesquare