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)題。
- 剛開(kāi)始以為CoordinatorLayout和FrameLayout之類(lèi)的布局一樣,沒(méi)有認(rèn)清CoordinatorLayout的作用
- 忽視了Behavior的重要性。
- 不熟悉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)了。效果圖如下:
疑問(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è)方法:
可以看到大神的介紹:
- 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實(shí)現(xiàn)很簡(jiǎn)單粗暴。dependency是AppBarLayout,那么就返回true
雖然沒(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)大!
后記
在網(wǎng)上看博客過(guò)程中,也了解了一些CoordinatorLayout的細(xì)節(jié)。
- CoordinatorLayout只能對(duì)直接子view操作。
- CoordinatorLayout和一些新的控件配合,可以實(shí)現(xiàn)很好的效果。CoordinatorLayout是 Material Design的一種很好體現(xiàn)