CoordinatorLayout與滾動的處理

分類:技術 時間:2016-10-24

本博文專門講解和CoordinatorLayout相關的知識點,這也是Design Support Library中最重要與最難的部分。

概覽

CoordinatorLayout 實現了多種Material Design中提到的 滾動效果 。目前這個框架提供了幾種不用寫動畫代碼就能工作的方法,這些效果包括:

讓浮動操作按鈕上下滑動,為Snackbar留出空間

擴展或者縮小Toolbar或者頭部,讓主內容區域有更多的空間。

控制哪個view應該擴展還是收縮,以及其顯示大小比例,包括 視差滾動效果parallax scrolling effects 動畫。

Code Samples

官方為我們提供了一個漂亮的demo ,使用了 CoordinatorLayout 和其他的 design support library 特性.

詳情請查看 github

效果圖

Setup

Make sure to follow the Design Support Library instructions first.

Floating Action Buttons and Snackbars

The CoordinatorLayout can be used to create floating effects using the layout_anchor and layout_gravity attributes. See the Floating Action Buttons guide for more information.

When a Snackbar is rendered, it normally appears at the bottom of the visible screen. To make room, the floating action button must be moved up to provide space.

So long as the CoordinatorLayout is used as the primary layout, this animation effect will occur for you automatically. The floating action button has a default behavior that detects Snackbar views being added and animates the button above the height of the Snackbar.

Code

activity_fab__snackar.xml

lt;?xml version=quot;1.0quot; encoding=quot;utf-8quot;?gt;
lt;android.support.design.widget.CoordinatorLayout
    xmlns:android=quot;http://schemas.android.com/apk/res/androidquot;
    xmlns:app=quot;http://schemas.android.com/apk/res-autoquot;
    android:id=quot;@ id/main_contentquot;
    android:layout_width=quot;match_parentquot;
    android:layout_height=quot;match_parentquot;gt;

    lt;android.support.v7.widget.RecyclerView
        android:id=quot;@ id/rvToDoListquot;
        android:layout_width=quot;match_parentquot;
        android:layout_height=quot;wrap_contentquot;/gt;



    lt;android.support.design.widget.FloatingActionButton
        android:id=quot;@ id/floatingActionButtonquot;
        android:layout_width=quot;wrap_contentquot;
        android:layout_height=quot;wrap_contentquot;
        android:layout_gravity=quot;bottom|rightquot;
        android:layout_margin=quot;16dpquot;
        android:src=http://www.tuicool.com/articles/quot;@drawable/gur_project_10quot;
        app:layout_anchor=quot;@id/rvToDoListquot;
        app:layout_anchorGravity=quot;bottom|right|endquot;
        app:layout_behavior=quot;demo.turing.com.materialdesignwidget.floatingActionButton.ScrollAwareFABBehaviorquot;/gt;

lt;/android.support.design.widget.CoordinatorLayoutgt;

Fab_SnackarAct.java

public class Fab_SnackarAct extends AppCompatActivity {

    private RecyclerView recyclerView;
    private FloatingActionButton floatingActionButton;
    private CoordinatorLayout coordinatorLayout ;

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

        coordinatorLayout = (CoordinatorLayout) findViewById(R.id.main_content);

        floatingActionButton = (FloatingActionButton) findViewById(R.id.floatingActionButton);

        recyclerView = (RecyclerView) findViewById(R.id.rvToDoList);

        // 線性布局
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        // 設置適配器,填充數據
        recyclerView.setAdapter(new NormalRecyclerViewAdapter(this));


        floatingActionButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view,quot;HELLOquot;,Snackbar.LENGTH_SHORT).show();
            }
        });
    }
}

關鍵點

  • 根布局必須為CoordinatorLayout
  • FloatingActionButton設置 app:layout_anchor和app:layout_anchorGravity屬性
  • app:layout_behavior這個屬性也可以不加也能實現點擊floatingActionButton彈出Snackbar,fab自動上移的效果,app:layout_behavior的為自定義的效果,當下滑時,fab消失,上滑時fab顯示,詳情請查看本人博客 Floating Action Button-Android M新控件

運行圖

Expanding and Collapsing Toolbars(Toolbar的擴展與收縮)

  • The first step is to make sure you are not using the deprecated ActionBar. Make sure to follow the Using the ToolBar as ActionBar guide.
  • Also make sure that the CoordinatorLayout is the main layout container.
lt;android.support.design.widget.CoordinatorLayout xmlns:android=quot;http://schemas.android.com/apk/res/androidquot;
 xmlns:app=quot;http://schemas.android.com/apk/res-autoquot;
    android:id=quot;@ id/main_contentquot;
    android:layout_width=quot;match_parentquot;
    android:layout_height=quot;match_parentquot;
    android:fitsSystemWindows=quot;truequot;gt;

      lt;android.support.v7.widget.Toolbar
                android:id=quot;@ id/toolbarquot;
                android:layout_width=quot;match_parentquot;
                android:layout_height=quot;?attr/actionBarSizequot;
                app:popupTheme=quot;@style/ThemeOverlay.AppCompat.Lightquot; /gt;

lt;/android.support.design.widget.CoordinatorLayoutgt;

Responding to Scroll Events

Next, we must make the Toolbar responsive to scroll events using a container layout called AppBarLayout :

接下來,我們必須使用一個容器布局:AppBarLayout來讓Toolbar響應滾動事件。

lt;android.support.design.widget.AppBarLayout
        android:id=quot;@ id/appbarquot;
        android:layout_width=quot;match_parentquot;
        android:layout_height=quot;@dimen/detail_backdrop_heightquot;
        android:theme=quot;@style/ThemeOverlay.AppCompat.Dark.ActionBarquot;
        android:fitsSystemWindows=quot;truequot;gt;

  lt;android.support.v7.widget.Toolbar
                android:id=quot;@ id/toolbarquot;
                android:layout_width=quot;match_parentquot;
                android:layout_height=quot;?attr/actionBarSizequot;
                app:popupTheme=quot;@style/ThemeOverlay.AppCompat.Lightquot; /gt;

 lt;/android.support.design.widget.AppBarLayoutgt;

Note: AppBarLayout currently expects to be the first child nested within a CoordinatorLayout according to the official Google docs.

注意:根據官方的谷歌文檔,AppBarLayout目前必須是第一個嵌套在CoordinatorLayout里面的子view。

Next, we need to define an association between the AppBarLayout and the View that will be scrolled. Add an app:layout_behavior to a RecyclerView or any other View capable of nested scrolling such as NestedScrollView

The support library contains a special string resource @string/appbar_scrolling_view_behavior that maps to AppBarLayout.ScrollingViewBehavior , which is used to notify the AppBarLayout when scroll events occur on this particular view. The behavior must be established on the view that triggers the event.

然后,我們需要定義AppBarLayout與滾動視圖之間的聯系。在RecyclerView或者任意支持嵌套滾動的view比如NestedScrollView上添加 app:layout_behavior 。support library包含了一個特殊的字符串資源@string/appbar_scrolling_view_behavior,它和AppBarLayout.ScrollingViewBehavior相匹配,用來通知AppBarLayout 這個特殊的view何時發生了滾動事件,這個behavior需要設置在觸發事件(滾動)的view之上。

lt;android.support.v7.widget.RecyclerView
        android:id=quot;@ id/rvToDoListquot;
        android:layout_width=quot;match_parentquot;
        android:layout_height=quot;match_parentquot;
        app:layout_behavior=quot;@string/appbar_scrolling_view_behaviorquot;gt;

當CoordinatorLayout發現RecyclerView中定義了這個屬性,它會搜索自己所包含的其他view,看看是否有view與這個behavior相關聯。AppBarLayout.ScrollingViewBehavior描述了RecyclerView與AppBarLayout之間的依賴關系。RecyclerView的任意滾動事件都將觸發AppBarLayout或者AppBarLayout里面view的改變。

AppBarLayout里面定義的view只要設置了app:layout_scrollFlags屬性,就可以在RecyclerView滾動事件發生的時候被觸發:

lt;android.support.design.widget.AppBarLayout
        android:layout_width=quot;match_parentquot;
        android:layout_height=quot;wrap_contentquot;
        android:fitsSystemWindows=quot;truequot;
        android:theme=quot;@style/ThemeOverlay.AppCompat.Dark.ActionBarquot;gt;

            lt;android.support.v7.widget.Toolbar
                android:id=quot;@ id/toolbarquot;
                android:layout_width=quot;match_parentquot;
                android:layout_height=quot;?attr/actionBarSizequot;
                app:layout_scrollFlags=quot;scroll|enterAlwaysquot;/gt;

 lt;/android.support.design.widget.AppBarLayoutgt;

app:layout_scrollFlags屬性里面必須至少啟用scroll這個flag,這樣這個view才會滾動出屏幕,否則它將一直固定在頂部。可以使用的其他flag有:

  • enterAlways: 一旦向上滾動這個view就可見。

Normally, the Toolbar only appears when the list is scrolled to the top as shown below:

  • enterAlwaysCollapsed: 顧名思義,這個flag定義的是何時進入(已經消失之后何時再次顯示)。假設你定義了一個最小高度(minHeight)同時enterAlways也定義了,那么view將在到達這個最小高度的時候開始顯示,并且從這個時候開始慢慢展開,當滾動到頂部的時候展開完。

  • exitUntilCollapsed: 同樣顧名思義,這個flag時定義何時退出,當你定義了一個minHeight,這個view將在滾動到達這個最小高度的時候消失。

  • snap:Using this option will determine what to do when a view only has been partially reduced. If scrolling ends and the view size has been reduced to less than 50% of its original, then this view to return to its original size. If the size is greater than 50% of its sized, it will disappear completely.

記住,要把帶有scroll flag的view放在前面,這樣收回的view才能讓正常退出,而固定的view繼續留在頂部。

此時,你應該注意到我們的Toolbar能夠響應滾動事件了。

Creating Collapsing Effects(制造折疊效果)

如果想制造toolbar的折疊效果,我們必須把Toolbar放在CollapsingToolbarLayout中:

lt;android.support.design.widget.CollapsingToolbarLayout
            android:id=quot;@ id/collapsing_toolbarquot;
            android:layout_width=quot;match_parentquot;
            android:layout_height=quot;match_parentquot;
            android:fitsSystemWindows=quot;truequot;
            app:contentScrim=quot;?attr/colorPrimaryquot;
            app:expandedTitleMarginEnd=quot;64dpquot;
            app:expandedTitleMarginStart=quot;48dpquot;
            app:layout_scrollFlags=quot;scroll|exitUntilCollapsedquot;gt;

            lt;android.support.v7.widget.Toolbar
                android:id=quot;@ id/toolbarquot;
                android:layout_width=quot;match_parentquot;
                android:layout_height=quot;?attr/actionBarSizequot;
                app:layout_scrollFlags=quot;scroll|enterAlwaysquot;gt;lt;/android.support.v7.widget.Toolbargt;

lt;/android.support.design.widget.CollapsingToolbarLayoutgt;

現在效果就成了:

通常,我們我們都是設置Toolbar的title,而現在,我們需要把title設置在CollapsingToolBarLayout上,而不是Toolbar。

CollapsingToolbarLayout collapsingToolbar =
              (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
      collapsingToolbar.setTitle(quot;Titlequot;);

Note that when using CollapsingToolbarLayout , the status bar should be made translucent (API 19) or transparent (API 21) as shown in this file . In particular, the following styles should be set in res/values-xx/styles.xml as illustrated:

lt;!-- res/values-v19/styles.xml --gt;
lt;style name=quot;AppThemequot; parent=quot;Base.AppThemequot;gt;
    lt;item name=quot;android:windowTranslucentStatusquot;gt;truelt;/itemgt;
lt;/stylegt;

lt;!-- res/values-v21/styles.xml --gt;
lt;style name=quot;AppThemequot; parent=quot;Base.AppThemequot;gt;
    lt;item name=quot;android:windowDrawsSystemBarBackgroundsquot;gt;truelt;/itemgt;
    lt;item name=quot;android:statusBarColorquot;gt;@android:color/transparentlt;/itemgt;
lt;/stylegt;

Creating Parallax Animations(制造視差效果)

CollapsingToolbarLayout還能讓我們做出更高級的動畫,比如在里面放一個ImageView,然后在它折疊的時候漸漸淡出。同時在用戶滾動的時候title的高度也會隨著改變。

為了制造出這種效果,我們添加一個定義了app:layout_collapseMode=”parallax” 屬性的ImageView。

lt;android.support.design.widget.CollapsingToolbarLayout
          android:id=quot;@ id/collapsing_toolbarquot;
          android:layout_width=quot;match_parentquot;
          android:layout_height=quot;match_parentquot;
          android:fitsSystemWindows=quot;truequot;
          app:contentScrim=quot;?attr/colorPrimaryquot;
          app:expandedTitleMarginEnd=quot;64dpquot;
          app:expandedTitleMarginStart=quot;48dpquot;
          app:layout_scrollFlags=quot;scroll|exitUntilCollapsedquot;gt;

          lt;android.support.v7.widget.Toolbar
              android:id=quot;@ id/toolbarquot;
              android:layout_width=quot;match_parentquot;
              android:layout_height=quot;?attr/actionBarSizequot;
              app:layout_scrollFlags=quot;scroll|enterAlwaysquot;gt;lt;/android.support.v7.widget.Toolbargt;
          lt;ImageView
              android:src=http://www.tuicool.com/articles/quot;@drawable/cheese_1quot;
              app:layout_scrollFlags=quot;scroll|enterAlways|enterAlwaysCollapsedquot;
              android:layout_width=quot;wrap_contentquot;
              android:layout_height=quot;wrap_contentquot;
              android:scaleType=quot;centerCropquot;
              app:layout_collapseMode=quot;parallaxquot;
              android:minHeight=quot;100dpquot;/gt;

      lt;/android.support.design.widget.CollapsingToolbarLayoutgt;

Custom Behaviors (自定義Behavior)

CoordinatorLayout 與浮動操作按鈕 中我們討論了一個自定義behavior的例子。

譯文 http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0718/3197.html

CoordinatorLayout的工作原理是搜索定義了CoordinatorLayout Behavior 的子view,不管是通過在xml中使用app:layout_behavior標簽還是通過在代碼中對view類使用@DefaultBehavior修飾符來添加注解。當滾動發生的時候,CoordinatorLayout會嘗試觸發那些聲明了依賴的子view。

要自己定義CoordinatorLayout Behavior,你需要實現layoutDependsOn() 和onDependentViewChanged()兩個方法。比如AppBarLayout.Behavior 就定義了這兩個關鍵方法。這個behavior用于當滾動發生的時候讓AppBarLayout發生改變。

public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
          return dependency instanceof AppBarLayout;
      }

 public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
          // check the behavior triggered
          android.support.design.widget.CoordinatorLayout.Behavior behavior = ((android.support.design.widget.CoordinatorLayout.LayoutParams)dependency.getLayoutParams()).getBehavior();
          if(behavior instanceof AppBarLayout.Behavior) {
          // do stuff here
          }
 }

英文原文:

https://guides.codepath.com/android/Handling-Scrolls-with-CoordinatorLayout


Tags: 安卓開發

文章來源:http://blog.csdn.net/yangshangwei/article/details/


ads
ads

相關文章
ads

相關文章

ad