通過Behavior在RecycleView中隱藏顯示FAB
之前寫過一篇FAB按鈕的隱藏顯示, ofollow,noindex">FloatingActionButton在RecycleView中滑動隱藏顯示 ,它是通過監聽RecycleView的滑動實現的,不過Google官方並沒有推薦這種方式,今天看看比較官方的做法通過重寫Behavior來實現。
public class FABBehavior extends FloatingActionButton.Behavior { private boolean visible = true;//是否可見 public FABBehavior(Context context, AttributeSet attrs) { super(); } //當觀察的RecyclerView發生滑動開始的時候回撥的 //axes滑動關聯軸,我們現在只關心垂直的滑動 @Override public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, @NonNull View directTargetChild, @NonNull View target, int axes, int type) { return axes == ViewCompat.SCROLL_AXIS_VERTICAL || super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, axes, type); } @Override public void onNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull FloatingActionButton child, @NonNull View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type) { super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type); if (dyConsumed > 0 && visible) { visible = false; animateOut(child); } else if (dyConsumed < 0 && !visible) { visible = true; animateIn(child); } } // FAB隱藏動畫 private void animateOut(FloatingActionButton fab) { CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) fab.getLayoutParams(); fab.animate().translationY(fab.getHeight() + layoutParams.bottomMargin).setInterpolator(new AccelerateInterpolator(3)); ViewCompat.animate(fab).scaleX(0f).scaleY(0f).start(); } // FAB顯示動畫 private void animateIn(FloatingActionButton fab) { fab.animate().translationY(0).setInterpolator(new DecelerateInterpolator(3)); ViewCompat.animate(fab).scaleX(1f).scaleY(1f).start(); } } 複製程式碼
程式碼註釋中對關鍵的地方已經註釋很清楚了,在不重複說明了,
下面看看介面佈局檔案
<?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" android:tooltipText="" tools:context="com.mtx.floatingactionbutton.MainActivity"> <android.support.v7.widget.RecyclerView android:id="@+id/rcv" android:layout_width="match_parent" android:layout_height="match_parent"> </android.support.v7.widget.RecyclerView> <android.support.design.widget.FloatingActionButton android:id="@+id/fcb" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="@dimen/default_margin" android:backgroundTint="@color/colorAccent" android:onClick="onClickFAB" android:src="@drawable/up" app:borderWidth="0dp" app:elevation="10dp" app:fabSize="normal" app:layout_anchor="@id/rcv" app:layout_anchorGravity="bottom|right|end" app:layout_behavior="com.mtx.floatingactionbutton.FABBehavior" app:rippleColor="@color/colorPrimary" /> </android.support.design.widget.CoordinatorLayout> 複製程式碼
CoordinatorLayout幫助協調定義在裡面的view之間的動畫,app:layout_behavior="com.mtx.floatingactionbutton.FABBehavior" 這一行是重點,app:layout_behavior的值為我們自定義的類,ayout_anchor 與 layout_anchorGravity 屬性就可以了,layout_anchor 指定參照物, anchorGravity 指定相對於參照物的位置,設定為 bottom|right則表示將FloatingActionButton放置於參照物的右下角。
注意點
- RecyclerView版本要是v22及以上,v21之前的版本不支援與CoordinatorLayout一起工作
- 和RecyclerView 22版本配合使用的時候會有一個已知的問題,如果滾動過快,會觸發NullPointerExceptionbug連線,不過這個問題應該已經修復了,我在recyclerview-v7:27版本中快速滑動已經沒有這個問題了
