Android Material Design 兼容庫的使用

前言:近來學(xué)習了Android Material Design 兼容庫,為了把這個弄懂,才有了這篇博客,這里先推薦兩篇博客:1.Android Material Design 兼容庫的使用詳解
2.Android應(yīng)用Design Support Library完全使用實例
第一篇博客是這個兼容庫的詳細解析,我參考了里面的許多內(nèi)容,第二篇是兼容庫的大致介紹,如果你能把這兩篇全部弄懂,我這篇也沒有必要看了。說了這么多,開始正文吧,大家有什么問題或建議,歡迎留言交流。

文章所用的示例地址:[mecury/MeterialDesignSupportLibrary]

1.概述

在2015年,google官方升級了Design Support Library,為開發(fā)者增加了不少可用的開發(fā)控件。

2綜述

支持Android 2.1以上設(shè)備。
Gradle build script dependency:

compile 'com.android.support:design:22.2.0' //可修改版本號為自己匹配

Design Support Library包含8個控件,具體如下:

  • android.support.design.widget.TextInputLayout
    強大帶提示的MD風格的EditText
  • android.support.design.widget.FloatingActionButton
    MD風格的圓形按鈕,來自于ImageView
    +android.support.design.widget.Snackbar
    類似Toast,添加了簡單的單個Action
  • android.support.design.widget.TabLayout
    選項卡
  • android.support.design.widget.NavigationView
    DrawerLayout的SlideMenu
  • android.support.design.widget.CoordinatorLayout
    超級FrameLayout
  • android.support.design.widget.AppBarLayout
    MD風格的滑動Layout
  • android.support.design.widget.CollapsingToolbarLayout
    可折疊MD風格ToolbarLayout

注意事項:
這里需要添加額外的命名空間appNs(xmlns:app="http://schemas.android.com/apk/res-auto" )

在介紹各個控件之前,大家先看一下預(yù)覽圖,這里我自己寫了一個示例,看起來不太好,但是用來介紹是夠了,下面看圖。

演示動畫.gif

2.1 FLoatingActionButton

演示gif

![FloatingActionButton]NU.png](http://upload-images.jianshu.io/upload_images/1916953-89275ffd20b1f6e5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

一個負責顯示界面基本操作的圓形按鈕。Design library中的FloatingActionButton 實現(xiàn)了一個默認顏色為主題中colorAccent的懸浮操作按鈕。FloatingActionButton繼承自ImageView,你可以通過android:src或者 ImageView的任意方法,比如setImageDrawable()來設(shè)置FloatingActionButton里面的圖標。下面介紹幾種常用的設(shè)置屬性:

  • app:fabSize 設(shè)置按鈕的大小,有mini和normal可選,默認為normal
  • app:elevation 設(shè)置按鈕的高度,影響陰影范圍的顯示
  • app:rippleColor 設(shè)置漣漪效果的顏色(當點擊按鈕時的水波紋)

code:

<android.support.design.widget.FloatingActionButton    android:id="@+id/floatingButton"    
android:layout_width="wrap_content"    
android:layout_height="wrap_content"    
android:src="@mipmap/ic_launcher"    
app:elevation="5dp"    
app:fabSize="normal" />

無特別注意項,和普通控件類似。

2.2 TextInputLayout

演示gif:

TextInputLayout.gif

在MD中,使用TextInputLayout將EditText進行了封裝。其最大的改變就是為EditText添加了兩個提示效果。一個顯示在上面,提示用戶輸入的是什么,另一個可以設(shè)為Error提示,當輸入錯誤的時候顯示出來。

code:

<android.support.design.widget.TextInputLayout 
android:id="@+id/textInput" 
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>

在代碼中使用的是時候,需要監(jiān)聽EditText的變化。

editText.addTextChangedListener(new TextWatcher() {
           @Override
           public void beforeTextChanged(CharSequence s, int start, int count, int after) {

           }

           @Override
           public void onTextChanged(CharSequence s, int start, int before, int count) {
               Log.e("TAG",s.length()+"");
               if (s.length() > 4){//字符超過5個時,出現(xiàn)EditText提示
                   inputLayout.setError("字符不能超過5個");
                   inputLayout.setErrorEnabled(true);
               }else{
                   inputLayout.setErrorEnabled(false);
               }
           }

           @Override
           public void afterTextChanged(Editable s) {

           }
       });

注意項

TextInputLayout中至少嵌套一個EditText。

2.3 SnackBar

演示gif:

SnackBar.gif

SnackBar提供一個輕量級的、快速的反饋。它可以說是一個增強功能的Toast,不同的是SnackBar被固定在底部(Snackbar試圖找到一個合適的父親以確保自己是被放置于底部),包含一段文本信息與一個可選的操作按鈕。它會在時間到達時刪除,或者被用戶點擊按鈕提前刪除。
code
SnackBar的使用十分簡單,和Toast十分類似,使用下面代碼就可以創(chuàng)建一個SnackBar:

final Snackbar snackbar = Snackbar.make(view,"你點擊按鈕",Snackbar.LENGTH_SHORT);
snackbar.show();

此時如果,你想添加在SnackBar上添加一個按鈕,你可以這樣:

snackbar.setAction("知道了", new View.OnClickListener() {    
@Override   
 public void onClick(View v) {       
 snackbar.dismiss();   
 }});

上面代碼放在一起,就是動態(tài)圖的效果。

無特別注意項,和普通控件類似。

CoordinatorLayout

CoordinatorLayout.gif

我們來看看官方對他的描述:

  • CoordinatorLayout is a super-poweredFrameLayout.
  • CoordinatorLayout is intended for two primary use cases:1.As a top-level application decor or chrome layout2.As a container for a specific interaction with one or more child views
    從這里我們可以知道它是一個增強版的FrameLayout,他可以協(xié)調(diào)其子View的交互,控制手勢機滾動技巧。這個控件十分的強大,用處也十分的廣泛。就比如剛才說的FloatingActionButton如果用CoordinatorLayout 作為FloatingActionButton的父布局,它將很好的協(xié)調(diào)Snackbar的顯示與FloatingActionButton(見上圖,可以見到FloatingActionButton隨著SnackBar的出現(xiàn)而移動),在Snackbar以動畫效果進入的時候自動向上移動讓出位置,并且在Snackbar動畫地消失的時候回到原來的位置,不需要額外的代碼。

CoordinatorLayout的另一個用例是ActionBar與滾動技巧。你可能已經(jīng)在自己的布局中使用了Toolbar ,它允許你更加自由的自定義其外觀與布局的其余部分融為一體。Design library把這種設(shè)計帶到了更高的水平,使用AppBarLayout可以讓你的Toolbar與其他View(比如TabLayout的選項卡)能響應(yīng)被標記了ScrollingViewBehavior的View的滾動事件。

code

<?xml version="1.0" encoding="utf-8"?>
<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:orientation="vertical">    
<TextView       
 android:id="@+id/tv"        
android:layout_width="match_parent"        
android:layout_height="wrap_content"        
android:text="CoordinatorLayout展示界面,當點擊右下角的FloatingActionButton時,可以看到明顯的移動。另外:點擊下面的按鈕跳轉(zhuǎn)到CoordinatorLayout,AppbarLayout,toolbar等演示界面:" />    
<android.support.v7.widget.AppCompatButton        
android:id="@+id/act_btn"        
android:layout_width="match_parent"        
android:layout_height="wrap_content"        
android:layout_marginTop="100dp"        
android:text="跳轉(zhuǎn)" 
/>    
<android.support.design.widget.FloatingActionButton        
android:id="@+id/fab_btn"        
android:layout_width="wrap_content"        
android:layout_height="wrap_content"        
android:layout_gravity="bottom|right"        
android:layout_margin="10dp"        
android:src="@mipmap/ic_launcher"        
app:fabSize="normal" 
/>
</android.support.design.widget.CoordinatorLayout>

無特別注意項,和普通控件類似。

NavigationView

演示gif
這個在上面的錄制過程中忘了錄了,這里也錄的有點小瑕疵,大家見諒啊。

Navigation.gif

NavgationView是一個抽屜式的導(dǎo)航控件,它可以讓我們很方便的建立一個滑動菜單。
關(guān)于用法,以上圖為例,見下面代碼:
code
navigationview_layout.xml:

<?xml version="1.0" encoding="utf-8"?>
<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:orientation="vertical">     

   <!--內(nèi)容區(qū)-->    
<include layout="@layout/activity_main"
/>    

<!--左側(cè)導(dǎo)航菜單-->    
<android.support.design.widget.NavigationView        
android:id="@+id/navigationView"        
android:layout_width="wrap_content"        
android:layout_height="match_parent"        
android:layout_gravity="start"        
android:fitsSystemWindows="true"        
app:headerLayout="@layout/head"        
app:menu="@menu/navigationview_item"
/>
</android.support.v4.widget.DrawerLayout>

里面內(nèi)容區(qū)的布局,就是側(cè)滑不滑動時顯示的布局。里面headerLayout和menu分別為側(cè)滑導(dǎo)航中的頭部和item。這里我頭部用了一張圖片:
head.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    
android:layout_width="match_parent"    
android:layout_height="wrap_content"    
android:orientation="vertical">    

<ImageView        
android:layout_width="match_parent"        
android:layout_height="match_parent"        
android:adjustViewBounds="true"        
android:src="@drawable/header" 
/>
</LinearLayout>

對于menu,就是菜單項的配置:
navigationview_item.xml:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<group 
android:checkableBehavior="single">    
<item        
android:id="@+id/menu_main"        
android:icon="@mipmap/ic_home_white"        
android:title="首頁"        
app:showAsAction="always" 
/>    
<item        
android:id="@+id/menu_about"        
android:icon="@mipmap/ic_about"        
android:title="關(guān)于"       
app:showAsAction="always"
/>
</group>
</menu>

上面的布局已經(jīng)完成了,如果我們添加抽屜導(dǎo)航的Item的點擊事件,那又該怎么做呢?下面簡單介紹一下:

private void navigationViewListener(){    
NavigationView mNavigationView = (NavigationView) findViewById(R.id.navigationView);    
mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {        
@Override        
public boolean onNavigationItemSelected(MenuItem item) {            
switch(item.getItemId()){                
case R.id.menu_main:                    
Toast.makeText(MainActivity.this, "點擊了首頁", Toast.LENGTH_SHORT).show();                    
break;                
case R.id.menu_about:                    
Toast.makeText(MainActivity.this, "點擊了關(guān)于", Toast.LENGTH_SHORT).show();                    
break;            
}            
item.setChecked(true);            
mDrawerLayout.closeDrawer(Gravity.LEFT); //關(guān)閉側(cè)滑菜單           
return false;        
}    
});
}
看了上面的代碼,大家應(yīng)該很明白應(yīng)該怎么做了。

TabLayout

TabLayout.png

通過選項卡的方式切換View并不是MD中才有的新概念,它們和頂層導(dǎo)航模式或者組織app中不同分組內(nèi)容(比如,不同風格的音樂)是同一個概念。 Design library的TabLayout 既實現(xiàn)了固定的選項卡(View的寬度平均分配),也實現(xiàn)了可滾動的選項卡(View寬度不固定同時可以橫向滾動)。如果你使用ViewPager在 tab之間橫向切換,你可以直接從PagerAdapter的getPageTitle() 中創(chuàng)建選項卡,然后使用setupWithViewPager()將兩者聯(lián)系在一起。它可以使tab的選中事件能更新ViewPager,同時 ViewPager的頁面改變能更新tab的選中狀態(tài)。

ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager);
FragmentAdapter mAdapter = new FragmentAdapter(getSupportFragmentManager(), titles, fragments);
viewPager.setAdapter(mAdapter);
tabLayout.setupWithViewPager(viewPager);
tabLayout.setTabsFromPagerAdapter(mAdapter);

注意事項
如果你使用ViewPager在tab之間橫向切換,切記可以直接從PagerAdapter的getPageTitle() 中創(chuàng)建選項卡,然后使用setupWithViewPager()將兩者聯(lián)系在一起。

AppBarLayout、CollapsingToolbarLayout

這介紹這兩個之前,大家要明白什么是ToolBar。
ToolBar:這代表一個標題欄,圖中的綠色區(qū)域就是ToolBar。

AppBarLayout:其繼承于LinearLayout,使用AppBarLayout可以讓包含在其中的子控件能響應(yīng)被標記了ScrollingViewBehavior的的滾動事件(要與CoordinatorLayout 一起使用),利用它我們可以很容易的去實現(xiàn)視差滾動效果,見下圖(藍色區(qū)域就是AppBarLayout)。

AppBarLayout.gif

CollapsingToolbarLayout:可伸縮折疊的Toolbar (Collapsing Toolbar),直接添加Toolbar到AppBarLayout可以讓你使用enterAlwaysCollapsed和 exitUntilCollapsedscroll標志,但是無法控制不同元素如何響應(yīng)collapsing的細節(jié)。當你讓CollapsingToolbarLayout和Toolbar在一起使用的時候,title 會在展開的時候自動變得大些,而在折疊的時候讓字體過渡到默認值。

這里面有一些屬性十分重要:這里先介紹一下:
1.app:layout_collapseMode
pin:來確保Toolbar在view折疊的時候仍然被固定在屏幕的頂部
parallax:見3
2. app:layout_scrollFlags
scroll: 所有想滾動出屏幕的view都需要設(shè)置這個flag,沒有設(shè)置這個flag的view將被固定在屏幕頂部。
enterAlways: 這個flag讓任意向下的滾動都會導(dǎo)致該view變?yōu)榭梢姡斚蛏匣臅r候Toolbar就隱藏,下滑的時候顯示。
enterAlwaysCollapsed: 顧名思義,這個flag定義的是何時進入(已經(jīng)消失之后何時再次顯示)。假設(shè)你定義了一個最小高度(minHeight)同時enterAlways也定義了,那么view將在到達這個最小高度的時候開始顯示,并且從這個時候開始慢慢展開,當滾動到頂部的時候展開完。
exitUntilCollapsed: 同樣顧名思義,這個flag時定義何時退出,當你定義了一個minHeight,這個view將在滾動到達這個最小高度的時候消失。

3.定位到ImageView,有這兩個屬性是我們平常用沒看到的,說明我寫在注釋上了

app:layout_collapseMode="parallax"http://這個是配置當ImageView消失或者顯示時候有一種視差滾動效果
app:layout_collapseParallaxMultiplier="0.7"http://視差因子,越大視差特效越明顯,最大為1

code
xml文件:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <!--toolbar-->
    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="300dp">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsingtoolbarlayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="#77db93"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
        </android.support.design.widget.CollapsingToolbarLayout>
    </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">
       <!--省略了很多ImagView-->
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:src="@mipmap/ic_launcher" />

        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>

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

 

activity:

public class CoordinationActivity extends AppCompatActivity {

    private Toolbar toolbar;
    private CollapsingToolbarLayout collapsingToolbarLayout;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_coordinator);

        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        collapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsingtoolbarlayout);
        collapsingToolbarLayout.setTitle("極客學(xué)院");  //設(shè)置toolbar的標題
        //使用右上角的返回按鈕
        getSupportActionBar().setHomeButtonEnabled(true);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBackPressed();
            }
        });
    }
}

附(一些控件使用使用應(yīng)注意的地方):
1.在使用CardView的時候,一定要注意,當CardView的寬和高填充父容器的時候,CardView的margin最好要比cardElevation大,不然就看不到立體的效果。

2.我們知道ListView有一個onItemClick的事件,但是RecyclerView卻沒有,那么我們應(yīng)該怎樣去設(shè)置呢?其實很簡單,關(guān)于RecyclerView設(shè)置item的點擊事件,只需在創(chuàng)建ViewHolder的時候,給填充的View設(shè)置單擊事件即可。

3.在使用android.support.design.widget.AppBarLayout的時候內(nèi)容區(qū)最好使用android.support.v4.widget.NestedScrollView,之前我的內(nèi)容區(qū)用的是ScrollView,在往上拉的時候AppBarLayout一直沒有動畫效果,折騰了幾個小時都沒找到原因。最后逼不得用Android Studio創(chuàng)建了一個他自帶的關(guān)于AppBarLayout的模板項目,看到他用的是NestedScrollView作為內(nèi)容區(qū),我果斷就把我的內(nèi)容區(qū)換成了這個,立馬就有動畫效果了。
NestedScrollView官方的描述:
NestedScrollView is just likeScrollView, but it supports acting as both a nested scrolling parent and child on both new and old versions of Android. Nested scrolling is enabled by default.
如果感覺還不錯的就給個喜歡支持一下吧,有問題請留言,謝謝
最后附一張MD的主題色解析圖:

主題色.jpg

參考
1.Android Material Design 兼容庫的使用詳解
2.Android應(yīng)用Design Support Library完全使用實例

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容