完全搞懂CoordinatorLayout Behavior 你能做些什麼

完全搞懂CoordinatorLayout Behavior 你能做些什麼
完全搞懂CoordinatorLayout Behavior 系列之API講解
完全搞懂CoordinatorLayout Behavior之源碼學習
完全搞懂CoordinatorLayout Behavior之實戰一

國外的一些應用經常可以看到一些比較炫酷的滑動動畫交互,例如摺疊、 放大縮小、平移、透明度變化等等,最近幾年國內也有很多app逐漸使用了這種動畫。比如這些。
螞蟻財富 APP首頁
小米瀏覽器首頁效果
58同城首頁,之前有個很炫酷的首頁動畫,現在找不到了
我自己設計的一個首頁動畫半成品, 剩下一個title部分沒有完成
只有完全搞懂CoordinatorLayout Behavior 相關的知識點,包括原理我們才能夠對上面的各種動態效果信手拈來。在這之前我說一個我自己的經歷,在我自己項目中,我之前第一次看到58同城的那個首頁效果時就想搬到我自己的項目中, 於是百度 google 各種搜索, 好不容易在github上找了一個有點相像的效果,然後ctrl+c 和Ctrl+V 就放到自己項目中了。 但是別人的和你自己想要的終歸有點差別, 有時候也有小改動,所以每次我都是摸索着 改一些參數和數值, 帶着一種運氣的成分調試,最後調成一個自己覺得湊合的效果, 但是始終不知道其中的原理。 在後來工作中我一直沒放棄研究這個,經過一段時間的學習和研究,我終於搞懂了這中間的祕密。

CoordinatorLayout 是協調者,用於協調所有子視圖之間的動作, 一個子視圖發生了改變,想要另一個視圖跟着改變,需要怎麼做呢?它不能直接告訴它的兄弟視圖, 因爲事件傳遞的時候,他不可能得到它兄弟視圖的引用。 但是呢?它的父親可以找到他兄弟視圖的引用,所以它把它坐了那些事 告訴它的父親,然後它的父親在把它做的這些事, 轉告給需要跟着一起改變的兄弟視圖。但是怎麼改變呢?總不能我走一步,兄弟視圖也走一步吧? 那這種一模一樣的改變是完全沒有意義的。 所以父親定義了一個抽象的動作類,每次只需要把子視圖的做的那些動作,原樣轉給兄弟視圖。 然後兄弟視圖自己要做怎樣的改變,它自己來定,比如說 你前進一步, 我向左向後各走半步。 這種動作被抽象出來,在開發上叫做解耦。

爲了更好的說明CoordinatorLayout與Behavior以及子視圖之間的關係,我畫了一張圖方便大家理解。至於被觀察的子視圖怎麼告訴父視圖的,以及父視圖又是怎麼告訴觀察者視圖的。 主要跟Behavior 以及 NestedScrollingParent2 、NestedScrollingChild2有關係。如果細心的同學可以看出來,CoordinatorLayout實現了NestedScrollingParent2接口,NestScrollView 實現了NestedScrollingChild2接口。
NestedScrollingParent2源碼鏈接
NestedScrollingChild2源碼鏈接

  /**
   * This interface should be implemented by {@link android.view.ViewGroup ViewGroup} subclasses
   * that wish to support scrolling operations delegated by a nested child view.
   *
   * <p>Classes implementing this interface should create a final instance of a
   * {@link NestedScrollingParentHelper} as a field and delegate any View or ViewGroup methods
   * to the <code>NestedScrollingParentHelper</code> methods of the same signature.</p>
   *
   * <p>Views invoking nested scrolling functionality should always do so from the relevant
   * {@link ViewCompat}, {@link ViewGroupCompat} or {@link ViewParentCompat} compatibility
   * shim static methods. This ensures interoperability with nested scrolling views on all versions
   * of Android.</p>
   */
  public interface NestedScrollingParent2 extends NestedScrollingParent 

實現這個接口可以實現嵌套滾動的分派動作。但是分派動作的功能由NestedScrollingParentHelper代理執行。

  /**
   * This interface should be implemented by {@link View View} subclasses that wish
   * to support dispatching nested scrolling operations to a cooperating parent
   * {@link android.view.ViewGroup ViewGroup}.
   *
   * <p>Classes implementing this interface should create a final instance of a
   * {@link NestedScrollingChildHelper} as a field and delegate any View methods to the
   * <code>NestedScrollingChildHelper</code> methods of the same signature.</p>
   *
   * <p>Views invoking nested scrolling functionality should always do so from the relevant
   * {@link ViewCompat}, {@link ViewGroupCompat} or {@link ViewParentCompat} compatibility
   * shim static methods. This ensures interoperability with nested scrolling views on all versions
   * of Android.</p>
   */
  public interface NestedScrollingChild2 extends NestedScrollingChild

實現了這個接口的子類希望能夠把自己的滾動動作分派給父類在協作處理。

所以通常我們使用的是NestedScrollView 作爲子類,然後CoordinatorLayout作爲父類,然後定義一些子視圖並設置好他們的Behavior動作,然後監聽NestedScrollView的滾動,做出自己對應的改變。
這裏只是做一個簡單的說明,後面會結合源碼以及Behavior對應的方法,從源碼的角度證明上面我描述的這些東西。 當然也會有上面貼圖的實戰內容。
謝謝閱讀歡迎大家批評指正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章