CoordinatorLayout是design包中的新特性,可以用通过配合CoordinatorLayout来满足我们一些功能上的实现
CoordinatorLayout是一个什么,有什么作用?
在接触一个新的东西的时候我们首先是要看有什么效果,它的特性是什么,有什么作用。
CoordinatorLayout可以说一个布局管理器,加强版的Fragment,为什么说他是一个Fragment,
看下效果:
代码:
<?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">
<android.support.design.widget.AppBarLayout
android:id="@+id/tab"
android:layout_width="match_parent"
android:layout_height="200dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/coordinat"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:src="@mipmap/bg_icon"
app:layout_collapseMode="parallax" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:title="Toolbar"></android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
></android.support.v7.widget.RecyclerView>
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
app:layout_anchor="@id/tab"
app:layout_anchorGravity="bottom|right" />
</android.support.design.widget.CoordinatorLayout>
如果在RecyclerView ,中加入
app:layout_behavior="@string/appbar_scrolling_view_behavior"
效果如下:
同时:AppBarLayout线性布局效果,CollapsingToolbarLayout fragment布局效果。
CoordinatorLayout,还有一个比较强的功能就是能够自定义布局里面子的view的Behavior(行为),
定义行为干嘛,就是用来观察目标view。CoordinatorLayout 翻译过来就是协调布局,他会根据给定view制定行为的时候,会优先把事件给设置行为的这个view。
定义什么行为,我需要定义行为干嘛。
首先来简单的说明一下一个view会具有什么样的行为,比如、点击这个view,向左移动,向右移动,向上滚动,向下滚动,手指触摸这个view,这些都是view的行为,然后我们在操作一个view的时候是可以对容器里面的view产生影响的,那如何实现,让两个view之前产生联系,那就是给view设置一个Behavior(行为),来观察布局中的某个view的行为,然后根据被观察的view的行为做一下操作,更改view的操作
根据上面的话简单提炼下
- 我们要定义行为
- 如果有个两个view,A,B,我们把A定义成观察者,那么B就是被观察者,这种做法就是定义行为;
- 被观察者做了什么的,我们观察者就能接收到观察者的动作,并做出反馈,举个例子:猎人在草原上观察梅花鹿,猎杀梅花鹿。
- 面向对象的思想,面对B,A做出反馈完成相应动作。
效果:
- CoordinatorLayout的工作原理就是在布局中确定观察者和被观察者,观察者受被观察者的影响,两者会产生一个依赖的关系,而这个依赖关系的确认是通过view引入:
app:layout_behavior=”.FollowBehavior”
通过一个简单的例子来学习下:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.xuanma.testday.testapplication.MainActivity">
<TextView
android:id="@+id/guan_cha_zhe"
android:layout_width="wrap_content"
android:text="观察者"
app:layout_behavior=".FollowBehavior"
android:layout_height="wrap_content" />
<Button
android:id="@+id/bei_guan_cha_zhe"
android:layout_width="wrap_content"
android:text="被观察者"
android:layout_gravity="center"
android:layout_height="wrap_content" />
</android.support.design.widget.CoordinatorLayout>
定义了一个观察者和一个被观察者,在被观察者中引入我们自定义的
app:layout_behavior=”.FollowBehavior” (跟activity同包所以这样引入)
引入说明:
app:layout_behavior=“你的Behavior包含包名的类名”
public class FollowBehavior extends CoordinatorLayout.Behavior<TextView> {
/**
* 构造方法
*/
public FollowBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* 判断child的布局是否依赖 dependency
* <p>
* 根据逻辑来判断返回值,返回 false 表示不依赖,返回 true 表示依赖
* <p>
* 在一个交互行为中,Dependent View 的变化决定了另一个相关 View 的行为。
* 在这个例子中, Button 就是 Dependent View,因为 TextView 跟随着它。
* 实际上 Dependent View 就相当于我们前面介绍的被观察者
*/
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, TextView child, View dependency) {
return dependency instanceof Button;
}
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, TextView child, View dependency) {
child.setX(dependency.getX());
child.setY(dependency.getY() + 100);
return true;
}
}
接下来我们要让我们的被观察者动起来,重写触摸事件
private void findViewById() {
Button button= (Button) findViewById(R.id.bei_guan_cha_zhe);
button.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_MOVE){
v.setX(event.getRawX());
v.setY(event.getRawY());
}
return true;
}
});
}
layoutDependsOn()重写这个方法是用来确认哪一个view是被观察者,让他们产生一个可依赖的关系,即观察者依赖被观察者 。被观察者 Dependent View ,观察者被归类于child。
重写onDependentViewChanged ,让child 跟随View dependency一起移动
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, TextView child, View dependency) {
child.setX(dependency.getX());
child.setY(dependency.getY() + 100);
return true;
}
接下来我们看下更复杂的使用:
效果:
<?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:layout_width="match_parent"
android:layout_height="wrap_content"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
布局中引入默认的行为:
app:layout_behavior="@string/appbar_scrolling_view_behavior"
设置了滚动标记:
app:layout_scrollFlags=”scroll|enterAlways”
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways">
layout_scrollFlags
根据官方文档,layout_scrollFlags 的取值可以为以下几种。scroll
设成这个值的效果就好比本 View 和 Scrolling view 是“一体”的。具体示例我们在上面已经给出。有一点特别需要我们的注意,为了其他的滚动行为生效,必须同时指定 Scroll 和相应的标记,比如我们想要 exitUntilCollapsed 所表现的滚动行为,必须将 layout_scrollFlags 指定为 scroll|exitUntilCollapsed 。exitUntilCollapsed
当本 View 离开屏幕时,会被“折叠”直到达到其最小高度。我们可以这样理解这个效果:当我们开始向上滚动 Scrolling view 时,本 View 会先接管滚动事件,这样本 View 会先进行滚动,直到滚动到了最小高度(折叠了),Scrolling view 才开始实际滚动。而当本 View 已完全折叠后,再向下滚动 Scrolling view,直到 Scrolling view 顶部的内容完全显示后,本 View 才会开始向下滚动以显现出来。enterAlways
当 Scrolling view 向下滚动时,本 View 会一起跟着向下滚动。实际上就好比我们同时对 Scrolling view 和本 View 进行向下滚动。enterAlwaysCollapsed
从名字上就可以看出,这是在 enterAlways 的基础上,加上了“折叠”的效果。当我们开始向下滚动 Scrolling View 时,本 View 会一起跟着滚动直到达到其“折叠高度”(即最小高度)。然后当 Scrolling View 滚动至顶部内容完全显示后,再向下滚动 Scrolling View,本 View 会继续滚动到完全显示出来。snap
在一次滚动结束时,本 View 很可能只处于“部分显示”的状态,加上这个标记能够达到“要么完全隐藏,要么完全显示”的
CollapsingToolbarLayout 提供以下属性和方法是用:
Collapsing title:ToolBar的标题,当CollapsingToolbarLayout全屏没有折叠时,title显示的是大字体,在折叠的过程中,title不断变小到一定大小的效果。你可以调用setTitle(CharSequence)方法设置title。
Content scrim:ToolBar被折叠到顶部固定时候的背景,你可以调用setContentScrim(Drawable)方法改变背景或者 在属性中使用 app:contentScrim=”?attr/colorPrimary”来改变背景。
- Status bar scrim:状态栏的背景,调用方法setStatusBarScrim(Drawable)。还没研究明白,不过这个只能在Android5.0以上系统有效果。
- Parallax scrolling children:CollapsingToolbarLayout滑动时,子视图的视觉差,可以通过属性app:layout_collapseParallaxMultiplier=”0.6”改变。值de的范围[0.0,1.0],值越大视察越大。
- CollapseMode :子视图的折叠模式,在子视图设置,有两种“pin”:固定模式,在折叠的时候最后固定在顶端;“parallax”:视差模式,在折叠的时候会有个视差折叠的效果。我们可以在布局中使用属性app:layout_collapseMode=”parallax”来改变。
CoordinatorLayout 还提供了一个 layout_anchor 的属性,连同 layout_anchorGravity 一起,可以用来放置与其他视图关联在一起的悬浮视图(如 FloatingActionButton)。
app:layout_anchor="@id/appbar"
app:layout_anchorGravity="bottom|right|end"
demo地址:https://github.com/Followk/CoordinatorLayout_testday/
demo 效果
参考大神地址:
http://blog.csdn.net/xyz_lmn/article/details/48055919
http://www.jianshu.com/p/f418bf95db2d
http://www.jianshu.com/p/640f4ef05fb2