参考的原文如下:
在这里感谢上述文章的作者。
一、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,留意右下角。
可以看到。
F
loatingActionButton会让按钮浮在Snackbar上面,这个就是通过behavior来协调的,而ImageButton由于没有Behaviors的帮助,就没有浮在上面,因此被Snackbar挡住了
。
上面就是 最简单的应用CoordinatorLayout的例子,FloatingViewButton默认使用FloatingActionButton.Behavior来协调。
2.2
CoorDinatorLayout和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这两个一直陪伴着我们的控件似乎要被舍弃了。。