Design新控件学习之CoordinatorLayout

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 提供以下属性和方法是用

    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”改变。值de的范围[0.0,1.0],值越大视察越大。
    5. 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值