Material Design 系列(2)—CoordinatorLayout,协调者布局

本文详细介绍了Android Material Design中的CoordinatorLayout,一种用于协调多个视图交互的布局。通过实例解析了其工作原理,包括Behavior的概念,以及如何定义和使用Behavior来实现特定的视图联动效果。
摘要由CSDN通过智能技术生成

转载请注明出处:
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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值