FloatingActionButton(FAB) 是 Android 5.0 新特性——Material Design 中的一個控件,是一種懸浮的按鈕。
FloatingActionButton 是 ImageView 的子類,因此它具備ImageView的全部屬性。
FloatingActionButton 結合 CoordinatorLayout 使用,即可實現懸浮在任意控件的任意位置。
使用 FloatingActionButton 的難點主要是布局,其在JAVA代碼中的用法和普通的 ImageView 基本相同。
跟所有MD控件一樣,要使用FAB,需要在gradle文件中先注冊依賴:
compile 'com.android.support:design:25.0.0'
1、FAB 基本屬性:
android:src:FAB中顯示的圖標,最好是24dp的
app:backgroundTint:正常的背景顏色
app:rippleColor:按下時的背景顏色
app:elevation:正常的陰影大小
app:pressedTranslationZ:按下時的陰影大小
app:layout_anchor:設置FAB的錨點,即以哪個控件為參照設置位置
app:layout_anchorGravity:FAB相對於錨點的位置
app:fabSize:FAB的大小,normal或mini(對應56dp和40dp)
注意:要想讓FAB顯示點擊后的顏色和陰影變化效果,必須設置onClick事件
實例布局代碼:
<android.support.design.widget.CoordinatorLayout xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.design.widget.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="20.0dip" android:onClick="click" android:src="@mipmap/ic_launcher" app:backgroundTint="#30469b" app:borderWidth="0.0dip" app:elevation="5.0dip" app:fabSize="normal" app:layout_anchor="@id/container" app:layout_anchorGravity="right|bottom" app:pressedTranslationZ="10.0dip" app:rippleColor="#a6a6a6" /> </android.support.design.widget.CoordinatorLayout>
運行結果圖:

2、交互事件:
FloatingActionButton 的用法和ImageView基本相同,要想設置FloatingActionButton的點擊事件,直接調用setOnClickListener()方法即可。
值得一提的是,當FloatingActionButton與Snackbar一起使用的時候,有時候會發生“Snackbar將FloatingActionButton覆蓋”的問題,即FloatingActionButton不會因為Snackbar的彈出而上移,這是因為Snackbar的make()方法第一個參數沒有與FloatingActionButton綁定,只要Snackbar的make()方法第一個參數是FloatingActionButton對象,就不會出現上述問題,實例代碼如下:
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 第一個參數設置為FAB就可以使FAB跟隨Snackbar移動
Snackbar.make(v, "去下一頁?", Snackbar.LENGTH_LONG).setAction("確定", new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this, NextActivity.class));
}
}).show();
}
});
運行結果如下圖:


3、FAB 滑動隱藏/顯示:
很多應用中都有這種界面:界面中有一個FAB和一個RecyclerView,當RecyclerView向下滑動時,FAB消失;當RecyclerView向上滑動時,FAB又顯示出來。這是FAB與RecyclerView、CoordinatorLayout結合使用的結果。通過設置FAB在CoordinatorLayout中的Behavior來實現這種效果。下面貼代碼:
布局代碼:
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/activity_next" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/next_rv" android:layout_width="match_parent" android:layout_height="match_parent" /> <android.support.design.widget.FloatingActionButton android:id="@+id/next_fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="20.0dip" android:onClick="click" android:src="@mipmap/ic_launcher" app:backgroundTint="@color/colorPrimaryDark" app:elevation="5.0dip" app:fabSize="normal" app:layout_anchor="@id/next_rv" app:layout_anchorGravity="bottom|right" app:layout_behavior="com.example.testfloatingactionbutton.ScrollAwareFABBehavior" app:pressedTranslationZ="10.0dip" app:rippleColor="@color/colorPrimary" /> </android.support.design.widget.CoordinatorLayout>
ScrollAwareFABBehavior類中的代碼:
public class ScrollAwareFABBehavior extends FloatingActionButton.Behavior { // 動畫插值器,可以控制動畫的變化率 private static final Interpolator INTERPOLATOR = new FastOutSlowInInterpolator(); // 是否正在執行隱藏的動畫 private boolean mIsAnimatingOut = false; public ScrollAwareFABBehavior(Context context, AttributeSet attrs) { super(); } @Override public boolean onStartNestedScroll(final CoordinatorLayout coordinatorLayout, final FloatingActionButton child, final View directTargetChild, final View target, final int nestedScrollAxes) { // 如果是上下滑動的,則返回true return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL || super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes); } @Override public void onNestedScroll(final CoordinatorLayout coordinatorLayout, final FloatingActionButton child, final View target, final int dxConsumed, final int dyConsumed, final int dxUnconsumed, final int dyUnconsumed) { super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed); if (dyConsumed > 0 && !this.mIsAnimatingOut && child.getVisibility() == View.VISIBLE) { // 用戶向下滑動時判斷是否正在執行隱藏動畫,如果不是,而且FAB當前是可見的,則執行隱藏動畫隱藏FAB animateOut(child); } else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) { // 用戶向上滑動時判斷FAB是否可見,如果不可見則執行顯示動畫顯示FAB animateIn(child); } } // Same animation that FloatingActionButton.Behavior uses to hide the FAB when the AppBarLayout exits // 執行隱藏動畫隱藏FAB private void animateOut(final FloatingActionButton button) { if (Build.VERSION.SDK_INT >= 14) { ViewCompat.animate(button).scaleX(0.0F).scaleY(0.0F).alpha(0.0F).setInterpolator(INTERPOLATOR).withLayer() .setListener(new ViewPropertyAnimatorListener() { public void onAnimationStart(View view) { ScrollAwareFABBehavior.this.mIsAnimatingOut = true; } public void onAnimationCancel(View view) { ScrollAwareFABBehavior.this.mIsAnimatingOut = false; } public void onAnimationEnd(View view) { ScrollAwareFABBehavior.this.mIsAnimatingOut = false; view.setVisibility(View.GONE); } }).start(); } else { Animation anim = AnimationUtils.loadAnimation(button.getContext(), R.anim.fab_out); anim.setInterpolator(INTERPOLATOR); anim.setDuration(200L); anim.setAnimationListener(new Animation.AnimationListener() { public void onAnimationStart(Animation animation) { ScrollAwareFABBehavior.this.mIsAnimatingOut = true; } public void onAnimationEnd(Animation animation) { ScrollAwareFABBehavior.this.mIsAnimatingOut = false; button.setVisibility(View.GONE); } @Override public void onAnimationRepeat(final Animation animation) { } }); button.startAnimation(anim); } } // Same animation that FloatingActionButton.Behavior uses to show the FAB when the AppBarLayout enters // 執行顯示動畫顯示FAB private void animateIn(FloatingActionButton button) { button.setVisibility(View.VISIBLE); if (Build.VERSION.SDK_INT >= 14) { ViewCompat.animate(button).scaleX(1.0F).scaleY(1.0F).alpha(1.0F) .setInterpolator(INTERPOLATOR).withLayer().setListener(null) .start(); } else { Animation anim = AnimationUtils.loadAnimation(button.getContext(), R.anim.fab_in); anim.setDuration(200L); anim.setInterpolator(INTERPOLATOR); button.startAnimation(anim); } } }
FAB顯示的動畫fab_in:
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/decelerate_interpolator" android:zAdjustment="top"> <scale android:duration="@android:integer/config_mediumAnimTime" android:fromXScale="1.0" android:fromYScale="1.0" android:pivotX="50%p" android:pivotY="50%p" android:toXScale=".5" android:toYScale=".5" /> <alpha android:duration="@android:integer/config_mediumAnimTime" android:fromAlpha="1.0" android:toAlpha="0" /> </set>
FAB隱藏的動畫fab_out:
<set xmlns:android="http://schemas.android.com/apk/res/android"> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/decelerate_interpolator"> <scale android:duration="@android:integer/config_mediumAnimTime" android:fromXScale="2.0" android:fromYScale="2.0" android:pivotX="50%p" android:pivotY="50%p" android:toXScale="1.0" android:toYScale="1.0" /> </set> </set>
運行效果如下圖:
以上就是對FloatingActionButton用法的簡單介紹,下面貼出碼雲上的代碼,供大家參考。