天天看點

Android M新控件之AppBarLayout,NavigationView,CoordinatorLayout,CollapsingToolbarLayout的使用

【轉載請注明出處:http://blog.csdn.net/feiduclear_up/article/details/46514791 CSDN 廢墟的樹】

Android M新控件之AppBarLayout,NavigationView,CoordinatorLayout,CollapsingToolbarLayout的使用

上一篇部落格我們學習了Android Design Support Library庫中的 是個簡單的元件,不了解的童鞋可以參考之前的部落格

Android M新控件之FloatingActionButton,TextInputLayout,Snackbar,TabLayout的使用。

這篇部落格我們繼續學習Design庫中的其他四個元件,分别是AppBarLayout,NavigationView,CoordinatorLayout,CollapsingToolbarLayout。

同樣,你需要在你的工程中引入

AppBarLayout

效果圖是這樣的

Android M新控件之AppBarLayout,NavigationView,CoordinatorLayout,CollapsingToolbarLayout的使用

AppBarLayout 是繼承LinerLayout實作的一個ViewGroup容器元件,它是為了Material Design設計的App Bar,支援手勢滑動操作。

預設的AppBarLayout是垂直方向的,它的作用是把AppBarLayout包裹的内容都作為AppBar。類似上面圖檔貼出來的效果,代碼布局如下:

<android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        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="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:minHeight="?attr/actionBarSize"></android.support.v7.widget.Toolbar>

        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll"
            app:tabIndicatorColor="@android:color/holo_red_dark"
            app:tabSelectedTextColor="@android:color/holo_red_dark"
            app:tabTextColor="@android:color/black" />

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

此處将Toolbar 和Tablayout的組合部分共同構成 AppBar的效果。

注意: AppBarLayout必須作為Toolbar的父布局容器

AppBarLayout是支援手勢滑動效果的,不過的跟CoordinatorLayout配合使用,接下來學習一下CoordinatorLayout元件怎麼使用?

CoordinatorLayout

Android M新控件之AppBarLayout,NavigationView,CoordinatorLayout,CollapsingToolbarLayout的使用

從開發文檔中可以了解到,CoordinatorLayout是一個增強型的FrameLayout。它的作用有兩個

  1. 作為一個布局的根布局
  2. 最為一個為子視圖之間互相協調手勢效果的一個協調布局

例如一下布局代碼:

<?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/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        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="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|enterAlways" />

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


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

    <!--可滑動的布局内容-->
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    <android.support.design.widget.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_discuss"
        android:layout_gravity="bottom|end"/>


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

從上面布局看到,CoordinatorLayout協調布局中包裹了兩個布局,一個是NestedScrollView,一個是AppBarLayout,以及FAB按鈕。

我們來看看CoordinatorLayout是怎麼來協調這兩個子視圖手勢操作的。

1.由于CoordinatorLayout是FrameLayout布局,我們可以通過

屬性來控制元件在整個布局中的位置,比如上面效果中的FAB就是通過android:layout_gravity=”bottom|end”來确定 FAB的位置在底端的最右邊的位置。

2.為了達到上面效果圖的手勢動畫效果,我們必須做如下設定,通過app:layout_scrollFlags=”scroll|enterAlways” 屬性來确定哪個元件是可滑動的

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

  • scroll: 所有想滾動出螢幕的view都需要設定這個flag- 沒有設定這個flag的view将被固定在螢幕頂部。
  • enterAlways: 這個flag讓任意向下的滾動都會導緻該view變為可見,啟用快速“傳回模式”。
  • enterAlwaysCollapsed: 當你的視圖已經設定minHeight屬性又使用此标志時,你的視圖隻能已最小高度進入,隻有當滾動視圖到達頂部時才擴大到完整高度。
  • exitUntilCollapsed: 滾動退出螢幕,最後折疊在頂端。

我們上面的布局中 給Toolbar設定了app:layout_scrollFlags屬性,是以,Toolbar是可以滾動出螢幕,且向下滾動有可以出現。

3.為了使得Toolbar可以滑動,我們必須還得有個條件,就是CoordinatorLayout布局下包裹一個可以滑動的布局,比如 RecyclerView,NestedScrollView(經過測試,ListView,ScrollView不支援)具有滑動效果的元件。并且給這些元件設定如下屬性來告訴CoordinatorLayout,該元件是帶有滑動行為的元件,然後CoordinatorLayout在接受到滑動時會通知AppBarLayout 中可滑動的Toolbar可以滑出螢幕了。

總結: 為了使得Toolbar有滑動效果,必須做到如下三點:

  1. CoordinatorLayout必須作為整個布局的父布局容器。
  2. 給需要滑動的元件設定 app:layout_scrollFlags=”scroll|enterAlways” 屬性。
  3. 給你的可滑動的元件,也就是RecyclerView 或者 NestedScrollView 設定如下屬性:

CollapsingToolbarLayout

Android M新控件之AppBarLayout,NavigationView,CoordinatorLayout,CollapsingToolbarLayout的使用

CollapsingToolbarLayout包裹 Toolbar 的時候提供一個可折疊的 Toolbar,一般作為AppbarLayout的子視圖使用。

CollapsingToolbarLayout 提供以下屬性和方法是用:

  1. Collapsing title:ToolBar的标題,當CollapsingToolbarLayout全屏沒有折疊時,title顯示的是大字型,在折疊的過程中,title不斷變小到一定大小的效果。你可以調用setTitle(CharSequence)方法設定title。
  2. Content scrim:ToolBar被折疊到頂部固定時候的背景,你可以調用setContentScrim(Drawable)方法改變背景或者 在屬性中使用 app:contentScrim=”?attr/colorPrimary”來改變背景。
  3. Status bar scrim:狀态欄的背景,調用方法setStatusBarScrim(Drawable)。還沒研究明白,不過這個隻能在Android5.0以上系統有效果。
  4. Parallax scrolling children:CollapsingToolbarLayout滑動時,子視圖的視覺差,可以通過屬性app:layout_collapseParallaxMultiplier=”0.6”改變。
  5. CollapseMode :子視圖的折疊模式,有兩種“pin”:固定模式,在折疊的時候最後固定在頂端;“parallax”:視差模式,在折疊的時候會有個視差折疊的效果。我們可以在布局中使用屬性app:layout_collapseMode=”parallax”來改變。

布局代碼如下:

<?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.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="160dp">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:expandedTitleMarginEnd="64dp"
            app:contentScrim="?attr/colorPrimary"
            app:expandedTitleMarginStart="48dp"
            app:statusBarScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"

            >

            <ImageView
                android:id="@+id/image"
                app:layout_collapseParallaxMultiplier="0.6"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="fitXY"
                android:src="@drawable/image"
                app:layout_collapseMode="parallax" />

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


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

      <--your scroll content-->可滑動的内容
    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

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

    <android.support.design.widget.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_discuss"
        app:backgroundTintMode="multiply"
        app:layout_anchor="@id/appbar"
        app:layout_anchorGravity="bottom|end|right"></android.support.design.widget.FloatingActionButton>

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

總結: CollapsingToolbarLayout主要是提供一個可折疊的Toolbar容器,對容器中的不同視圖設定layout_collapseMode折疊模式,來達到不同的折疊效果。

1.Toolbar 的高度layout_height必須固定,不能 “wrap_content”,否則Toolbar不會滑動,也沒有折疊效果。

2.為了能讓FloatingActionButton也能折疊且消失出現,我們必須給FAB設定錨點屬性

意思是FAB浮動按鈕顯示在哪個布局區域。

且設定目前錨點的位置

app:layout_anchorGravity=”bottom|end|right”

意思FAB浮動按鈕在這個布局區域的具體位置。

兩個屬性共同作用才是的FAB 浮動按鈕也能折疊消失,出現。

3.給需要有折疊效果的元件設定 layout_collapseMode屬性。

【轉載請注明出處:http://blog.csdn.net/feiduclear_up/article/details/46514791 CSDN 廢墟的樹】

NavigationView

Android M新控件之AppBarLayout,NavigationView,CoordinatorLayout,CollapsingToolbarLayout的使用

用于側滑菜單中的menu布局。之前Google在V4包中推出自己的 DrawerLayout作為抽屜側滑菜單,标準使用方法可以參考 google 原生态 抽屜式側滑菜單 Android DrawerLayout 布局的使用介紹。

當時的官方布局是這樣的:

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:id="@+id/drawer_layout"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent" >  

    <!-- the main content view -->  

    <FrameLayout  
        android:id="@+id/frame_content"  
        android:layout_width="match_parent"  
        android:layout_height="match_parent" >  
    </FrameLayout>  

    <!-- the navigetion view -->  

    <ListView  
        android:id="@+id/drawer_list"  
        android:layout_width="240dp"  
        android:layout_height="match_parent"  
        android:layout_gravity="start"  
        android:background="#9999cc"  
        android:choiceMode="singleChoice"  
        android:divider="@android:color/transparent"  
        android:dividerHeight="0dp" >  
    </ListView>  

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

其實這次谷歌隻是将上面的ListView布局替換成NavigationView了。簡化了之前ListView寫擴充卡的繁瑣。

先如今布局改成如下:

<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">

    <!-- the main content view -->

    <include layout="@layout/layout_content" />

    <!-- the navigetion view -->

    <android.support.design.widget.NavigationView
        android:id="@+id/navigationView"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="left"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/layout_header"
        app:menu="@layout/layout_menu">

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

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

其中NavigationView 中的 android:layout_gravity=”start” 屬性來控制抽屜菜單從哪邊滑出,一般“start ”從左邊滑出,“end”從右邊滑出。

這裡最主要的兩個屬性分别是:

1.app:headerLayout: 給NavigationView添加頭部布局

2.app:menu:給NavigationView添加menu菜單布局

app:headerLayout布局如下:

<?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="200dp"
    android:background="@drawable/img1"
    android:gravity="center"
    android:orientation="vertical">

    <ImageView
        android:layout_width="125dp"
        android:layout_height="125dp"
        android:scaleType="centerCrop"
        android:src="@drawable/image" />

    <TextView
        android:layout_marginTop="15dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="CSDN廢墟的樹部落格"
        android:textColor="@android:color/white" />

</LinearLayout>
           

app:menu 布局如下:

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

    <group
        android:checkableBehavior="single"
        android:title="Home items">

        <item
            android:id="@+id/nav_blog"
            android:icon="@drawable/ic_account_balance_black_24dp"
            android:title="部落格位址" />

        <item
            android:id="@+id/nav_ver"
            android:icon="@drawable/ic_error_outline_black_36dp"
            android:title="版本資訊" />

        <item
            android:id="@+id/nav_about"
            android:icon="@drawable/ic_error_outline_black_36dp"
            android:title="關于我" />

    </group>

    <item android:title="Sub items">

        <menu>

            <item
                android:id="@+id/sub_exit"
                android:icon="@drawable/ic_power_settings_new_black_36dp"
                android:title="退出應用" />

            <item
                android:id="@+id/sub_switch"
                android:icon="@drawable/ic_settings_applications_black_36dp"
                android:title="切換主題" />
        </menu>
    </item>

</menu>
           

代碼中控制NavigationView

private void initNavigationView(){
        navigationView = (NavigationView) findViewById(R.id.navigationView);
        drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        //設定側滑菜單選擇監聽事件
        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(MenuItem menuItem) {
                menuItem.setChecked(true);
                //關閉抽屜側滑菜單
                drawerLayout.closeDrawers();
                return true;
            }
        });
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == android.R.id.home){
            //打開抽屜側滑菜單
            drawerLayout.openDrawer(GravityCompat.START);
        }
        return super.onOptionsItemSelected(item);
    }
           

關于NavigationView中item的字型顔色和icon選中狀态顔色是去目前主題theme中的

<--正常狀态下字型顔色和icon顔色-->
<item name="android:textColorPrimary">@android:color/darker_gray</item>
<--選中狀态icon的顔色和字型顔色-->
 <item name="colorPrimary">@color/accent_material_light</item>
           

當然你可以通過如下方法或者屬性來改變這一狀态:

  1. setItemBackgroundResource(int):給menu設定背景資源,對應的屬性app:itemBackground
  2. setItemIconTintList(ColorStateList):給menu的icon設定顔色,對應的屬性app:itemIconTint
  3. setItemTextColor(ColorStateList):給menu的item設定字型顔色,對應的屬性app:itemTextColor

至此,Android Support Design Library庫的使用基本學習完。

源碼位址 https://github.com/xujinping/AndroidDesignLibrary/tree/master