Android Material Design 之 CoordinatorLayout

什么是 CoordinatorLayout

官方文檔是這么描述的

CoordinatorLayout is a super-powered FrameLayout

CoordinatorLayout is intended for two primary use cases:

  1. As a top-level application decor or chrome layout
  2. As a container for a specific interaction with one or more child views

翻譯一下

CoordinatorLayout 是一個加強版的 FrameLayout

主要用途有兩個:

  1. 用作應用的頂層布局管理器给猾,也就是作為用戶界面中所有UI控件的容器
  2. 用作相互之間具有特定交互行為的UI控件的容器

Coordinator 是協(xié)調者的意思,協(xié)調者布局责循,其實就是協(xié)調各個子 View 的一個容器蓉媳。

很多 Material Design 的效果都離不開 CoordinatorLayout冒冬。
比如 https://material.io/guidelines/components/snackbars-toasts.html#snackbars-toasts-usage 中的 Don’t block the floating action button 部分舱沧。
比如 https://material.io/guidelines/patterns/scrolling-techniques.html#scrolling-techniques-app-bar-scrollable-regions 中的各種滑動時隱藏畫面頂部內容的效果溉愁。

本篇文章先介紹一下 CoordinatorLayout 的基本使用屋摇,之后的文章再講怎么實現(xiàn)各種 Material Design 效果揩魂。

CoordinatorLayout 的簡單使用

參考這篇博文中的例子,效果如下

例子中有一個 Button炮温,有一個 TextView火脉,拖動 Button,TextView 也跟著一起移動柒啤,這就是交互行為倦挂。

其實這是一個觀察者模式,Button 是被觀察者担巩,TextView 是觀察者方援,TextView 觀察 Button 的移動,一旦移動了涛癌,TextView 也跟著移動犯戏。

看看代碼是怎么實現(xiàn)的

首先添加 design library

compile 'com.android.support:design:25.4.0'

布局文件如下

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

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="被觀察者" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="觀察者"
        app:layout_behavior=".FollowBehavior" />

</android.support.design.widget.CoordinatorLayout>

把 Button 和 TextView 放到一個 CoordinatorLayout 中窥浪,并且設置 TextView 的 app:layout_behavior 屬性。

再來看看 FollowBehavior 類

public class FollowBehavior extends CoordinatorLayout.Behavior {

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

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

    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
        child.setX(dependency.getX() + 150);
        child.setY(dependency.getY() + 150);
        return true;
    }
} 

繼承自 CoordinatorLayout.Behavior笛丙。

layoutDependsOn 是用來確定 dependent view 的漾脂,CoordinatorLayout 下面的所有子 View 都會去判斷。例子中把 Button 作為本次交互的對象胚鸯。

onDependentViewChanged 當 dependent view 發(fā)生變化時骨稿,這個方法會被調用,從而完成交互行為姜钳。例子中設置始終跟隨 Button 移動坦冠。

控制 Button 移動的代碼如下

public class MainActivity extends AppCompatActivity {

    float downEventX, downEventY;
    float downButtonX, downButtonY;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.button).setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {

                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    downEventX = event.getRawX();
                    downEventY = event.getRawY();
                    downButtonX = v.getX();
                    downButtonY = v.getY();
                }

                if (event.getAction() == MotionEvent.ACTION_MOVE) {
                    v.setX(downButtonX + event.getRawX() - downEventX);
                    v.setY(downButtonY + event.getRawY() - downEventY);
                }

                return true;
            }
        });
    }
}

這樣,一個簡單的通過 CoordinatorLayout 來進行 View 的交互的例子就完成了哥桥。
View 的交互是通過 Behavior 來進行的辙浑,可以使用系統(tǒng)定義好的 Behavior,也可以像本例一樣自定義 Behavior拟糕。

CoordinatorLayout 的神奇之處就在于它能夠讓它的子 View 們知道彼此的存在判呕,CoordinatorLayout 作為一個通信的橋梁,通過 Behavior 進行通信送滞,把一個 View 的變化通知給另一個 View侠草。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市犁嗅,隨后出現(xiàn)的幾起案子边涕,更是在濱河造成了極大的恐慌,老刑警劉巖褂微,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件功蜓,死亡現(xiàn)場離奇詭異,居然都是意外死亡宠蚂,警方通過查閱死者的電腦和手機式撼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來肥矢,“玉大人端衰,你說我怎么就攤上這事「矢模” “怎么了旅东?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長十艾。 經(jīng)常有香客問我抵代,道長,這世上最難降的妖魔是什么忘嫉? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任荤牍,我火速辦了婚禮案腺,結果婚禮上,老公的妹妹穿的比我還像新娘康吵。我一直安慰自己劈榨,他們只是感情好,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布晦嵌。 她就那樣靜靜地躺著同辣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪惭载。 梳的紋絲不亂的頭發(fā)上旱函,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天,我揣著相機與錄音描滔,去河邊找鬼棒妨。 笑死,一個胖子當著我的面吹牛含长,可吹牛的內容都是我干的券腔。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼茎芋,長吁一口氣:“原來是場噩夢啊……” “哼颅眶!你這毒婦竟也來了?” 一聲冷哼從身側響起田弥,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎铡原,沒想到半個月后偷厦,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡燕刻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年只泼,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片卵洗。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡请唱,死狀恐怖,靈堂內的尸體忽然破棺而出过蹂,到底是詐尸還是另有隱情十绑,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布酷勺,位于F島的核電站本橙,受9級特大地震影響,放射性物質發(fā)生泄漏脆诉。R本人自食惡果不足惜甚亭,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一贷币、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧亏狰,春花似錦役纹、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至信不,卻和暖如春嘲叔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背抽活。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工硫戈, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人下硕。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓丁逝,卻偏偏與公主長得像,于是被迫代替她去往敵國和親梭姓。 傳聞我的和親對象是個殘疾皇子霜幼,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內容