參考的原文如下:
在這裏感謝上述文章的作者。
一、CoordinatorLayout的作用
一言概之:Super-power FrameLayout 可以把它看成是一個加強版的FrameLayout
主要功能:
1.作爲頂層佈局
2.調度協調子佈局
特點:
CoordinatorLayout使用新的思路:通過協調調度子佈局的形式實現觸摸影響佈局的形式產生動畫果.CoorDinator是通過設置子View的Behaviors來調度子View.
在SupprtV7中,提供了AppBarLayout.Behavior、AppBarLayout.ScrollingViewBehavior、FloatingActionButton.Behavior,SwipeDismissBehavior<V extends View > 等Behaviors.
因此,也就是說:上述有Behavior的View放在CoordinatorLayout中,則CoordinatorLayout會對他們進行協調控制,反之,如果沒有Behavior,那麼CoordinatorLayout對於他們來說,就是一個FrameLayout而已。
接下來,我們就談談CoordinatorLayout的幾種應用情況。
二、CoordinatorLayout的應用
2.1 CoordinatorLayout和FloatingActionButton
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.example.happy.myapplication.MainActivity">
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
android:src="@android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
佈局文件activity_main.xml如下:
MainActivity.java的源碼如下:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
}
下面就給出效果對比,左邊是普通的ImageButton,右邊是FloatingActionButton,留意右下角。
可以看到。FloatingActionButton會讓按鈕浮在Snackbar上面,這個就是通過behavior來協調的,而ImageButton由於沒有Behaviors的幫助,就沒有浮在上面,因此被Snackbar擋住了。
上面就是 最簡單的應用CoordinatorLayout的例子,FloatingViewButton默認使用FloatingActionButton.Behavior來協調。
2.2CoorDinatorLayout和ActionBarLayout
2.2.1AppBarLayout嵌套TabsLayout
佈局源碼:
<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/coordinator_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<android.support.v7.widget.Toolbar
android:id="@+id/toolBar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#30469b"
app:layout_scrollFlags="scroll|enterAlways" />
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#30469b"
app:tabGravity="fill"
app:tabMode="fixed"
app:tabSelectedTextColor="#ff0000"
app:tabTextColor="#ffffff" />
</android.support.design.widget.AppBarLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:scrollbars="none"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
Fragment 源碼:
Fragment1:<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.myapplication.com.example.fragment.FragmentOne">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none" />
</FrameLayout>
fragment3:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.myapplication.com.example.fragment.FragmentTwo">
<TextView
android:id="@+id/fragment_tv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="25sp" />
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"></ListView>
</FrameLayout>
然後,就會發現,在滾動的時候,fragment1、2會讓標題欄滾動,而Fragment3由於使用了ListView 因此,AppBar是不會動的。
因爲fragment1和fragment2採用的是RecylerView而,Frgament3用的是ListView.
由此,可以知道:RecyclerView會把滑動事件通過Behavior傳遞給CoorDinatorLayout,然後CoordinatorLayout再使用Behavior讓AppBarLayout和TabsLayout實現隱藏的效果。因此重點在於:子View的Behavior.
這裏主要是通過AppBarLayout的子視圖的屬性控制,觀察AppBarLayout的子佈局,Toolbar有app:layout_scrollFlags屬性,這個就是控制滑動效果的屬性,這個屬性有四個值:
1.scroll:所有想滾動出屏幕的View都需要設置這個值,沒有設置這個值,View就會被固定在屏幕頂部。比如沒有設置這個值,屬性是:
app:layout_scrollFlags="enterAlways"
那麼,上面的fragment1的效果和Frgament3的AppBarLayout都是不可滑動的。
2.enterAlways:這個是讓這個View在向下滑動的時候,可以看得見。使得他能“快速返回”,意思就是,你隨便向下滑一下,如果你設置了enteralways ,那麼都會讓Toolbar完整地顯示出來 (不是100%但是幾乎都會這樣子,如果你不設置,你向下滑動 顯示出來的Toolbar不一定是完整的。)。
3.enterAlwaysCollapsed:當你的視圖已經設置minHeight屬性又使用此標誌時,你的視圖只能以最小高度進入,只有當滾動視圖到達頂部時才擴大到完整高度。
<android.support.v7.widget.Toolbar
android:id="@+id/toolBar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#30469b"
android:minHeight="10dp"
app:layout_scrollFlags="scroll|enterAlwaysCollapsed" />
運行效果是:滑動到頂部以後,AppBar不再滾動了,比較詭異,目前還是不太理解用法。後面發現,原來這個必須要用在CollapsingToolbarLayout這個佈局裏面,纔有效果。
4.exitUntilCollapsed: 滾動退出屏幕,最後摺疊在頂端。這個的父佈局必須是CollapsingToolbarLayout。
下面是文檔的原文:
scroll
:
this flag should be set for all views that want to scroll off the screen - for views that do not use this flag, they’ll remain pinned to the top of the screenenterAlways
:
this flag ensures that any downward scroll will cause this view to become visible, enabling
the ‘quick return’ patternenterAlwaysCollapsed
:
When your view has declared a minHeight and you use this flag, your View will only enter at its minimum height (i.e., ‘collapsed’), only re-expanding to its full height when the scrolling view has reached it’s top.exitUntilCollapsed
:
this flag causes the view to scroll off until it is ‘collapsed’ (its minHeight) before exiting
問題在:上面說的This View是指哪個,後面閱讀了
發現,原來指的是ToolBar
因此Scroll表示的是:使用Scroll的話,那麼TooBar是可以滑動的。而enterAlways經常配合 scroll一起用。來打到,向下滑動也會快速地顯示出Toolbar
因此,想要Toolbar實現滑動的效果需要如下:
1、CoordinatorLayout作爲父佈局
2、在需要滑動的控件(不僅僅是Toolbar)裏面設置如下屬性:
app:layout_scrollFlags="scroll|enterAlways"
3、給滑動的組件設置
app:layout_behavior="@string/appbar_scrolling_view_behavior"
如下:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:scrollbars="none"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
也可以去掉LinearLayout,直接放在Viewpager裏面。如:
注意: 不能直接放到ViewPager裏面,否則滾動事件分發會出問題,導致內容顯示不全等問題。因爲Viewpager的Behavior並沒有傳遞給CoordinatorLayout,所以,必須要設置在CoordinatorLayout的直接子View.
4.內容支持滾動。比如viewpager裏面嵌套了RecyclerView,而ListView、GridView則不行不行,這裏只能感慨ListView和GridView這兩個一直陪伴着我們的控件似乎要被捨棄了。。