CoordinatorLayout


title: CoordinatorLayout
date: 2017-04-12 20:46:01
tags: 學(xué)習(xí)
categories: android


[TOC]

CoordinatorLayout

CoordinatorLayout 主要使用于以下兩個(gè)場(chǎng)景

  • 作為一個(gè)頂層父容器出現(xiàn)
  • 協(xié)調(diào)一個(gè)或多個(gè)子View之間的交互

CoordinatorLayout 通過(guò)Behaviors指定子View的交互行為。

使用CoordinatorLayout需要導(dǎo)入design包

我進(jìn)入的誤區(qū)

才開(kāi)始接手CoordinatorLayout,沒(méi)有理清CoordinatorLayout的具體用途和使用場(chǎng)所。所以在學(xué)習(xí)過(guò)程中出現(xiàn)了很多不必要的問(wèn)題。

  1. 剛開(kāi)始以為CoordinatorLayout和FrameLayout之類(lèi)的布局一樣,沒(méi)有認(rèn)清CoordinatorLayout的作用
  2. 忽視了Behavior的重要性。
  3. 不熟悉CoordinatorLayout,想著直接可以上手,忽視了對(duì)Demo的研究

CoordinatorLayout簡(jiǎn)單使用

CoordinatorLayout的核心就是Behavior,Behavior就是定制子View的行為。

布局

CoordinatorLayout 繼承與ViewGroup,但是最基本的表現(xiàn)形式和FrameLayout很相識(shí)。

也就是布局是重疊的從左上角開(kāi)始。

如果要用好CoordinatorLayout,那么最基本的就是通過(guò)Behavior去控制。

實(shí)現(xiàn)效果

想通過(guò)CoordinatorLayout布局,實(shí)現(xiàn)頂層Toolbar加中間Fragment加底部菜單這種通用型的布局。

  • 更換父布局為android.support.design.widget.CoordinatorLayout
  • 按照網(wǎng)上的實(shí)例,對(duì)toolbar上封裝一層AppBarLayout
  • 添加frameLayout布局。
<FrameLayout
android:id="@+id/fragmet_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffffff"
app:layout_behavior="@string/appbar_scrolling_view_behavior">

</FrameLayout>
  • 添加底部布局LinearLayout.因?yàn)镃oordinatorLayout表現(xiàn)形式和FrameLayout很相識(shí),所以底部布局我直接增加底部對(duì)齊

很好,效果實(shí)現(xiàn)了。效果圖如下:


image

疑問(wèn)

  • 對(duì)于網(wǎng)上的事例,我首先的問(wèn)題是,Toolbar必須用AppBarLayout封裝么?

我動(dòng)手刪掉了AppBarLayout,然后運(yùn)行效果是:Toolbar直接不顯示了!好詭異,開(kāi)始糾結(jié)這個(gè)問(wèn)題。半個(gè)小時(shí)后發(fā)現(xiàn),Toolbar被FrameLayout給覆蓋住了..

但是結(jié)果還是不對(duì)???難道要我主動(dòng)對(duì)frameLayout增加一個(gè)marginTop?如果我不知道toolbar的高度,或者不好獲取這個(gè)高度,那不是坑大了?

  • 對(duì)比發(fā)現(xiàn)唯一的不同之處就是多了layout_behavior屬性。這個(gè)屬性是干什么的?

看到這里。要感謝大神寫(xiě)的博客CoordinatorLayout的使用如此簡(jiǎn)單.

因?yàn)榘l(fā)現(xiàn)各種的坑,又不明白原理?;究鞂?duì)CoordinatorLayout打差評(píng)的我,發(fā)現(xiàn)這個(gè)博客,然后一步一步研究這個(gè),并且根據(jù)網(wǎng)上各種人的說(shuō)法,把重心放在Behavior上。然后研究behavior的layoutDependsOn和onDependentViewChanged方法。

Behavior

最主要的兩個(gè)方法:


image

可以看到大神的介紹:

  • layoutDependsOn主要是判斷child布局是否依賴當(dāng)前這個(gè)View。
  • onDependentViewChanged主要是當(dāng)依賴的View改變時(shí),這個(gè)child布局改變動(dòng)作

看到這里,我突然有點(diǎn)明白了,CoordinatorLayout是協(xié)調(diào)一個(gè)或多個(gè)子View之間的交互。那么FrameLayout在Toolbar下面出現(xiàn),這是不是也是一種依賴關(guān)系呢?

如果是我想的這樣,那么我會(huì)在layoutDependsOn檢查當(dāng)dependency是Toolbar的時(shí)候,就返回true

在onDependentViewChanged的方法中,獲取dependency的高度,然后動(dòng)態(tài)的把這個(gè)高度設(shè)置給child,也就是FrameLayout。

AppBarLayout

懶得動(dòng)手,我選擇直接去找AppBarLayout中是如何實(shí)現(xiàn)Behavior中的兩個(gè)方法的。打算復(fù)制過(guò)來(lái)看看。


layoutDependsOn

layoutDependsOn實(shí)現(xiàn)很簡(jiǎn)單粗暴。dependency是AppBarLayout,那么就返回true


onDependentViewChanged
offsetChildAsNeeded

雖然沒(méi)用過(guò)ViewCompat.offsetTopBottom方法,但是大概理解這個(gè)方法的意思。好吧,我的猜想完全是正確的。

代碼實(shí)現(xiàn)

<?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">

<FrameLayout
android:id="@+id/fragmet_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00ffffff"
app:layout_behavior="com.xiaoqiang.view.MyBehavior">

</FrameLayout>

<include layout="@layout/tool_bar_base" />

<LinearLayout
android:id="@+id/rl_bottom_menu"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom"
android:orientation="horizontal">

<Button
android:id="@+id/btn_first"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="first" />

<Button
android:id="@+id/btn_second"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="second" />

<Button
android:id="@+id/btn_three"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="three" />
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>

app:layout_behavior="com.xiaoqiang.view.MyBehavior",這里我自定義了一個(gè)MyBehavior.

public class MyBehavior extends CoordinatorLayout.Behavior<FrameLayout> {

public MyBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}

@Override
public boolean layoutDependsOn(CoordinatorLayout parent, FrameLayout child, View dependency) {
return dependency instanceof ToolLinearLayout;
}

@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, FrameLayout child, View dependency) {
ViewCompat.setPaddingRelative(child,0,dependency.getBottom() - child.getTop(),0,0);
return false;
}
}

layoutDependsOn中,當(dāng)dependency是ToolLinearLayout的時(shí)候,直接返回true.這里我的想法是如果一個(gè)布局文件中有多個(gè)toolbar,那么直接使用會(huì)不會(huì)導(dǎo)致動(dòng)作錯(cuò)亂。所以仿照了AppBarLayout。

執(zhí)行后,效果果然和我的一樣。對(duì)于CoordinatorLayout也才有了一點(diǎn)點(diǎn)的理解。感覺(jué)功能很強(qiáng)大!

image

后記

在網(wǎng)上看博客過(guò)程中,也了解了一些CoordinatorLayout的細(xì)節(jié)。

  • CoordinatorLayout只能對(duì)直接子view操作。
  • CoordinatorLayout和一些新的控件配合,可以實(shí)現(xiàn)很好的效果。CoordinatorLayout是 Material Design的一種很好體現(xiàn)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容