转载请注明出处:
http://blog.csdn.net/user11223344abc?viewmode=contents
出自【蛟-blog】
0.前言
CoordinatorLayout,协调者布局,本文主要从逻辑理解的角度来讨论该布局的基本用法。
先来看看本文最终实现的效果图:
效果很简单,就是拖动下面那个小按钮,然后中间的CD碟片跟着转动。
1.CoordinatorLayout究竟是个什么鬼?
协调者布局,强调协调二字,也就是说多人协作的意思,使用这个控件的场景,一般是需要至少2个View进行交互的场景。
就好比学生军训走正步,教官抬腿,学生就跟着抬腿,教官摆手或立正,学生就跟着摆手或立正(当然,前提是教官指定你这么做,如果教官指定其他动作也是可以的,这里动作是抽象的),这里,【教官】就是所谓的【协调者】,而【学生】在这就是【被协调者/依赖者】,【摆手或立正】即是【协调者(教官)】指定给学生的【动作】。
此间可以看出这里头包含3个元素:
- 教官—>协调者(Coordinator) //指派动作给【被协调者】
- 学生—>被协调者/依赖者(Dependenciy)//ps:后文我就统一叫做被协调者了。
- 动作—>(Behavior) //被协调者特有特征
需要注意的是,这里所谓的动作是抽象的,也就是说,教官派发给我的“动作”也可能是其他的行为,这里只是凸显出Behavior这一概念,也就是说这个“动作”是自定义的。
2.代码理解及使用
在逻辑上已有了感性认识,那么接下来看代码如何写。
2.1:首先得知道布局内该怎么定义吧?
导入依赖包之后,在xml布局中如下定义:(不知道如何导包的同学戳这里)
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.design.widget.CoordinatorLayout>
2.2:接下来定义三个角色(协调者,被协调者,以及被协调者所需要执行的"动作")
看如下代码:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="zj.zjcoordinatorlayoutdemo.MainActivity">
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@mipmap/bigback">
<!--被协调者-->
<ImageView
android:id="@+id/cd"
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_centerInParent="true"
android:layout_gravity="center"
android:layout_marginBottom="30dp"
android:scaleType="centerCrop"
android:src="@mipmap/cdimg"
app:layout_behavior="zj.zjcoordinatorlayoutdemo.CdBehavior" />
<View
android:background="@android:color/white"
android:layout_width="match_parent"
android:layout_gravity="bottom"
android:layout_marginBottom="43dp"
android:layout_height="1dp"/>
<zj.zjcoordinatorlayoutdemo.ZJSeekBar
android:id="@+id/seekBar1"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="bottom|left"
android:layout_marginBottom="15dp" />
</android.support.design.widget.CoordinatorLayout>
</RelativeLayout>
从该代码可以看出,我只是在协调者布局当中包裹了2个控件,这个1dp的View没什么特别的含义,只是为了布局好看一点,属于噪音代码吧,不用关注它,其他俩控件
其中包含3个角色分别是:
-
协调者:ZJSeekBar
从xml中的代码看,他只是一个普通的自定义View罢了,他被定义在协调者布局当中,并且没有被指定动作,那么他具备了“成为协调者的潜质”,为什么这么说?因为此刻他还并没有跟任何被协调者产生关系。 -
被协调者:ImageView -> android:id="@+id/cd"
这个ImageView标签下,有个属性叫做 app:layout_behavior=“zj.zjcoordinatorlayoutdemo.CdBehavior”
这行代码一写上去,该View是作为一个"被协调者了",为何这么说,因为它已经被指定了一个“动作(behavior)”。 -
动作:ImageView控件标签下的: app:layout_behavior=“zj.zjcoordinatorlayoutdemo.CdBehavior”,这是个什么东西,接下来我们就讨论它。
2.3:动作,Behavior
先上代码:这就是我定义的Behavior的最初形态
package zj.zjcoordinatorlayoutdemo;
import android.content.Context;
import android.support.design.widget.CoordinatorLayout;
import android.util.AttributeSet;
import android.view.View;
import android.widget.SeekBar;
/**
* Created by Administrator on 2017/7/23.
*/
public class CdBehavior extends CoordinatorLayout.Behavior {
public CdBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* 是否依赖(或者说是否顺从,是否成为被协调者)
*
* @param parent 父布局(协调者布局)
* @param child 被协调者
* @param dependency 协调者
* @return
*/
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
return false;
}
/**
* 具体动作
*
* @param parent 父布局(协调者布局)
* @param child 被协调者
* @param dependency 协调者
* @return
*/
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
return super.onDependentViewChanged(parent, child, dependency);
}
}
可以看到这里只复写了俩个方法,并且都只有3个参数,这三个参数是什么呢?
从注释可以看出来
@param parent 父布局
@param child 被协调者
@param dependency 协调者
接下来再具体的讨论这俩个方法。
- layoutDependsOn
这个方法直接决定者一个被协调者的定义,就想是一个契约,返回true,那么它则是一个被协调者,返回false则不是。
那么就会产生一个问题,“我被谁协调”,若是被被全部人协调,那么直接返回true就行了,若是有选择性的,则需要写一段逻辑,比如假设本文有俩个seekBar,我选择只被Seekbar1所协调。那么代码就应该修改如下:
public boolean layoutDependsOn(CoordinatorLayout pare