Android Material Design 中的CorrdinatorLayout使用詳解

轉(zhuǎn)發(fā)請(qǐng)備注原文地址:https://www.niwoxuexi.com/blog/android/article/191.html
我在找了一些關(guān)于CoordinatorLayout
的教程篓吁,大部分文章都是講解把CoordinatorLayout, AppbarLayout ,CollapsingToolbarLayout以及Toolbar 等緩和一起使用,這很容易是大家混淆抛腕,不知道如何利用CoordinatorLayout使用到不同的場(chǎng)景中服赎。其實(shí)CoordinatorLayout的功能并不是局限于與AppBarLayout一起使用,它的功能非常強(qiáng)大梁沧,本文將針對(duì)CoordinatorLayout的使用進(jìn)行詳細(xì)介紹檀何,在后面再介紹將AppBarLayout和CollapsingToolBarLayout整合CoordinatorLayout一起。那么到底CoordinatorLayout是如何使用的呢,那就聽我細(xì)細(xì)道來(lái)吧~
CoordinatorLayout 到底是什么频鉴,能干什么栓辜?
先看一下官方的描述吧:
CoordinatorLayout is a super-powered FrameLayout
.
CoordinatorLayout is intended for two primary use cases:
As a top-level application decor or chrome layout
As a container for a specific interaction with one or more child views

簡(jiǎn)單的說(shuō)CoordinatorLayout是一個(gè)超級(jí)的FrameLayout 布局,它的作用是幫助我們協(xié)調(diào)它的個(gè)個(gè)子View的布局垛孔,我們先看一個(gè)案例動(dòng)畫組:


稍微解釋一下這個(gè)動(dòng)畫:小面的綠色小球是一個(gè)普通的View藕甩,上面的飛機(jī)是一個(gè)ImageView ,我們水平拖動(dòng)小球周荐,飛機(jī)向相反的方向運(yùn)動(dòng)狭莱;垂直方向拖動(dòng)小球會(huì)跟著相
同的方向運(yùn)動(dòng);
簡(jiǎn)而言之:水平方向反向運(yùn)動(dòng)概作,垂直方向同向運(yùn)動(dòng)腋妙;
這個(gè)例子就是運(yùn)用CoordinatorLayout實(shí)現(xiàn)的,當(dāng)然讓你不用CoordinatorLayout
去實(shí)現(xiàn)讯榕,應(yīng)該沒有任何問(wèn)題骤素,但是代碼的耦合度應(yīng)該非常大,你的代碼必須要持有
2個(gè)View的引用愚屁,然后在onTouchEvent里面做各種判斷和邏輯處理济竹,這耦合度未免太傷人傷力了~
而CoordinatorLayout既然號(hào)稱能幫我們協(xié)調(diào)子View的布局,我們接下來(lái)看看CoordinatorLayout如何實(shí)現(xiàn)~

<h2>CoordinatorLayout 的使用</h2>

CoordinatorLayout的使用核心是Behavior集绰,Behavior就是執(zhí)行你定制的動(dòng)作规辱。
看先Behavior的官方解釋吧:
<pre>
Interaction behavior plugin for child views of CoordinatorLayout.
</pre>
翻譯:Behavior就是用來(lái)給CoordinatorLayout的子view們實(shí)現(xiàn)交互的。
在講Behavior之前必須先理解兩個(gè)概念:Child和Dependency栽燕,什么意思呢罕袋?Child當(dāng)然是子View的意思了,是誰(shuí)的子View呢碍岔,當(dāng)然是CoordinatorLayout的子View浴讯;其
實(shí)Child是指要執(zhí)行動(dòng)作的CoordinatorLayout的子View。而Dependency是指Child依賴的View蔼啦。比如上面的gif圖中榆纽,綠色的小球的View就是Dependency,上面的小飛機(jī)的ImgeView就是Child捏肢,上面小飛機(jī)的動(dòng)作是依賴下面的綠色的View奈籽。簡(jiǎn)而言之,就是如過(guò)Dependency這個(gè)View發(fā)生了變化鸵赫,那么Child這個(gè)View就要相應(yīng)發(fā)生變化衣屏。發(fā)生變化是具體發(fā)生什么變化呢?這里就要引入Behavior辩棒,Child發(fā)生變化的具體執(zhí)行的代碼都是放在Behavior這個(gè)類里面狼忱。
怎么使用Behavior呢膨疏,首先,我們定義一個(gè)類钻弄,繼承CoordinatorLayout.Behavior<T>,其中佃却,泛型參數(shù)T是我們要執(zhí)行動(dòng)作的View類,也就是Child窘俺。然后就是去實(shí)現(xiàn)
Behavior的兩個(gè)方法:
<pre>
/**

  • 判斷child的布局是否依賴dependency
    /
    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
    //返回false表示child不依賴dependency饲帅,ture表示依賴
    return true;
    }
    /
    *
  • 當(dāng)dependency發(fā)生改變時(shí)(位置、寬高等)批销,執(zhí)行這個(gè)函數(shù)
  • 返回true表示child的位置或者是寬高要發(fā)生改變洒闸,否則就返回false
    */
    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
    //根據(jù)dependency的位置,設(shè)置child的位置
    return true;
    }
    </pre>
    看了上面的概念后均芽,我們看看具體怎么去實(shí)現(xiàn)吧~
    為了響應(yīng)跟隨手指移動(dòng)的操作,我們定義一個(gè)非常簡(jiǎn)單的View单鹿,這個(gè)View只響應(yīng)跟隨手指移動(dòng)掀宋,將這個(gè)View作為Dependency。由于過(guò)于簡(jiǎn)單仲锄,這個(gè)View源碼不粘貼劲妙,我們只需知道這個(gè)View的類名叫:DependentView。

<h5>先看一下:Behavior的實(shí)現(xiàn):</h5>
<pre>
package com.niwoxuexi.coordinatelayout;
import android.content.Context;
import android.support.design.widget.CoordinatorLayout;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.View;
/**

  • Created by zhuxiaocheng on 2017/7/6.
    /
    public class MyBehavior extends CoordinatorLayout.Behavior {
    private int screenWidth;
    public MyBehavior(Context context, AttributeSet attrs) {
    super(context, attrs);
    DisplayMetrics display = context.getResources().getDisplayMetrics();
    screenWidth = display.widthPixels;
    }
    /
    *
    • 判斷child的布局是否依賴dependency
      /
      @Override
      public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
      //返回false表示child不依賴dependency儒喊,ture表示依賴
      return true;
      }
      /
      *
    • 當(dāng)dependency發(fā)生改變時(shí)(位置镣奋、寬高等),執(zhí)行這個(gè)函數(shù)
    • 返回true表示child的位置或者是寬高要發(fā)生改變怀愧,否則就返回false
      /
      @Override
      public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
      //根據(jù)dependency的位置侨颈,設(shè)置child的位置
      int top = dependency.getTop();
      int left = dependency.getLeft();
      int x = screenWidth - left - child.getWidth();
      int y = top - 800;
      setPosition(child, x, y);
      return true;
      }
      private void setPosition(View v, int x, int y) {
      CoordinatorLayout.MarginLayoutParams layoutParams = (CoordinatorLayout.MarginLayoutParams) v.getLayoutParams();
      layoutParams.leftMargin = x;
      layoutParams.topMargin = y;
      v.setLayoutParams(layoutParams);
      }
      }
      </pre>
      再看一下DependentView的實(shí)現(xiàn):
      <pre>
      package com.niwoxuexi.coordinatelayout;
      import android.content.Context;
      import android.support.design.widget.CoordinatorLayout;
      import android.util.AttributeSet;
      import android.util.DisplayMetrics;
      import android.view.View;
      /
      *
  • Created by zhuxiaocheng on 2017/7/6.
    /
    public class MyBehavior extends CoordinatorLayout.Behavior {
    private int screenWidth;
    public MyBehavior(Context context, AttributeSet attrs) {
    super(context, attrs);
    DisplayMetrics display = context.getResources().getDisplayMetrics();
    screenWidth = display.widthPixels;
    }
    /
    *
    • 判斷child的布局是否依賴dependency
      /
      @Override
      public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
      //返回false表示child不依賴dependency,ture表示依賴
      return true;
      }
      /
      *
    • 當(dāng)dependency發(fā)生改變時(shí)(位置芯义、寬高等)哈垢,執(zhí)行這個(gè)函數(shù)
    • 返回true表示child的位置或者是寬高要發(fā)生改變,否則就返回false
      */
      @Override
      public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
      //根據(jù)dependency的位置扛拨,設(shè)置child的位置
      int top = dependency.getTop();
      int left = dependency.getLeft();
      int x = screenWidth - left - child.getWidth();
      int y = top - 800;
      setPosition(child, x, y);
      return true;
      }
      private void setPosition(View v, int x, int y) {
      CoordinatorLayout.MarginLayoutParams layoutParams = (CoordinatorLayout.MarginLayoutParams) v.getLayoutParams();
      layoutParams.leftMargin = x;
      layoutParams.topMargin = y;
      v.setLayoutParams(layoutParams);
      }
      }
      </pre>
      OK耘分,現(xiàn)在我們有了Dependency 的控件DependentView,并且定義好了跟隨Dependency一直變化的動(dòng)作(Behavior)MyBehavior绑警,接下來(lái)我們就要指定好為哪個(gè)具體的ImageView實(shí)例來(lái)綁定這些求泰。
      **方法灰常簡(jiǎn)單,直接布局文件指定就好:******

app:layout_behavior="com.niwoxuexi.coordinatelayout.MyBehavior"
直接上代碼计盒,大家自己體會(huì)吧
<pre>
<?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"
tools:context="com.niwoxuexi.coordinatelayout.MainActivity">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/plane"
android:scaleType="fitCenter"
android:layout_marginLeft="180dp"
android:layout_marginTop="100dp"
app:layout_behavior="com.niwoxuexi.coordinatelayout.MyBehavior"
/>
<com.niwoxuexi.coordinatelayout.DependentView
android:layout_width="50dp"
android:layout_height="50dp"
android:background="@drawable/button"
android:layout_marginLeft="180dp"
android:layout_marginTop="460dp" />
</android.support.design.widget.CoordinatorLayout>
</pre>
是不是很簡(jiǎn)單呢渴频?我們只需關(guān)注Behavior的編寫就好了,把Child和Dependency之間的在xml文件中設(shè)置就可以了~
最后是上代碼時(shí)間嘍:https://image.niwoxuexi.com/blog/downloadCoordinateLayout.zip

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末章郁,一起剝皮案震驚了整個(gè)濱河市枉氮,隨后出現(xiàn)的幾起案子志衍,更是在濱河造成了極大的恐慌,老刑警劉巖聊替,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件楼肪,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡惹悄,警方通過(guò)查閱死者的電腦和手機(jī)春叫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)泣港,“玉大人暂殖,你說(shuō)我怎么就攤上這事〉鄙矗” “怎么了呛每?”我有些...
    開封第一講書人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)坡氯。 經(jīng)常有香客問(wèn)我晨横,道長(zhǎng),這世上最難降的妖魔是什么箫柳? 我笑而不...
    開封第一講書人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任手形,我火速辦了婚禮,結(jié)果婚禮上悯恍,老公的妹妹穿的比我還像新娘库糠。我一直安慰自己,他們只是感情好涮毫,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開白布瞬欧。 她就那樣靜靜地躺著,像睡著了一般窒百。 火紅的嫁衣襯著肌膚如雪黍判。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評(píng)論 1 285
  • 那天篙梢,我揣著相機(jī)與錄音顷帖,去河邊找鬼。 笑死渤滞,一個(gè)胖子當(dāng)著我的面吹牛贬墩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播妄呕,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼陶舞,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了绪励?” 一聲冷哼從身側(cè)響起肿孵,我...
    開封第一講書人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤唠粥,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后停做,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體晤愧,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年蛉腌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了官份。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡烙丛,死狀恐怖舅巷,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情河咽,我是刑警寧澤钠右,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站库北,受9級(jí)特大地震影響爬舰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜寒瓦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望坪仇。 院中可真熱鬧杂腰,春花似錦、人聲如沸椅文。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)皆刺。三九已至少辣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間羡蛾,已是汗流浹背漓帅。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留痴怨,地道東北人忙干。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像浪藻,于是被迫代替她去往敵國(guó)和親捐迫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 上一篇爱葵,我們大體理解了 Behavior簡(jiǎn)單理解具體代碼可以見 https://github.com/295472...
    dodo_lihao閱讀 6,738評(píng)論 3 26
  • 最新項(xiàng)目中用到了些Material效果施戴,在此對(duì)自己的學(xué)習(xí)做個(gè)小結(jié)反浓。 首先養(yǎng)成良好的學(xué)習(xí)習(xí)慣-----看源碼: Co...
    風(fēng)少俠閱讀 4,854評(píng)論 5 37
  • Behavior 是 CoordinatorLayout為其 子視圖 提供的一種交互行為插件。它實(shí)現(xiàn)了用戶可以...
    小編閱讀 2,417評(píng)論 0 8
  • 昨天赞哗,送兒子去參加乒乓球訓(xùn)練雷则。我們趕到通知的地點(diǎn)時(shí),沒見一個(gè)隊(duì)員懈玻,也沒見教練的影子巧婶。問(wèn)了門衛(wèi)室的老大爺,人...
    蔓草漾閱讀 380評(píng)論 0 0
  • 兒時(shí)最喜歡的動(dòng)畫片之一想必會(huì)是《寵物小精靈》吧涂乌,總被那皮卡丘萌萌的聲音所吸引艺栈,也好希望自己也有如此呆萌的一個(gè)寵物~...
    港漂圈閱讀 698評(píng)論 0 1