前言
作為Material Design成員之一,旨在在手機、平板電腦、臺式機和其它的平臺提供一致、更廣泛的外觀和感覺。它有自身獨特的動態效果,比如變形、彈出、位移等等,代表著當前頁面上用戶的特定操作。FloatingActionButton在用戶界面起著不可替代的作用,看到這里是不是有一種躍躍欲試的感覺。
效果~

Part 1、FloatingActionButton常規應用
配置
dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') compile 'com.android.support:design:25.0.1'}代碼 <android.support.design.widget.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_margin="16dp" android:src="@android:drawable/ic_dialog_email" app:backgroundTint="@color/colorAccent" app:elevation="10dp" app:fabSize="normal" app:PRessedTranslationZ="12dp" android:clickable="true" app:rippleColor="#ff0" android:onClick="rotate"/>tips:1、app:fabSize="" : 設置Fab的大小,normal(56dp) mini(40dp)
2、app:backgroundTint="" : 設置Fab的背景
3、app:rippleColor="" : 設置Fab按下時的波紋效果(在5.0以上起作用)
4、app:elevation="" : 設置Fab正常狀態下的海拔高度
5、app:pressedTranslationZ="" : 設置Fab按下的時候Z軸距離
6、在你想觸發點擊事件之前要設置clickable為true
效果~

從效果圖可以看出5.0以上和5.0以下Fab的位置不一樣,因為在5.0以下會默認為Fab設置邊距所以在這里要使用兩種尺寸
在5.0以下設置
android:layout_margin="0dp"在5.0以上設置android:layout_margin="16dp"效果~ 
問題解決了~
我們還可以為Fab設置動畫效果
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) fab.getLayoutParams();// fab.animate().translationY(fab.getHeight()+layoutParams.bottomMargin).setInterpolator(new AccelerateInterpolator(3)); //fab.animate().translationY(0).setInterpolator(new DecelerateInterpolator(3)); ObjectAnimator go = ObjectAnimator.ofFloat(fab,"translationY",0,fab.getHeight()+layoutParams.bottomMargin); go.setDuration(500); go.setInterpolator(new AccelerateInterpolator()); go.start(); go.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) fab.getLayoutParams(); ObjectAnimator back = ObjectAnimator.ofFloat(fab,"translationY",fab.getHeight()+layoutParams.bottomMargin,0); back.setDuration(500); back.setInterpolator(new DecelerateInterpolator()); back.start(); } });效果~

當然你也可以使用github上的庫,如下所示

地址:https://github.com/makovkastar/FloatingActionButton
Part 2、FloatingActionButton的源碼分析
* <p>Floating action buttons come in two sizes: the default and the mini. The size can be * controlled with the {@code fabSize} attribute.</p> * 懸浮的按鈕有兩個尺寸,默認和mini大小,這個尺寸和控制FabSize屬性 * <p>As this class descends from {@link ImageView}, you can control the icon which is displayed * via {@link #setImageDrawable(Drawable)}.</p> * 這個類繼承ImageView,你可以通過設置setImageDrawable來設置是否顯示icon * <p>The background color of this view defaults to the your theme's {@code colorAccent}. If you * wish to change this at runtime then you can do so via * {@link #setBackgroundTintList(ColorStateList)}.</p> 這個View的默認背景顏色為你的主題colorAccent顏色,如果你希望改變這個可以通過setBackgroundTintList方法 */@CoordinatorLayout.DefaultBehavior(FloatingActionButton.Behavior.class)public class FloatingActionButton extends ImageButton {在來看一下構造方法
public FloatingActionButton(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); ...... Drawable background = a.getDrawable(R.styleable.FloatingActionButton_android_background); mBackgroundTint = a.getColorStateList(R.styleable.FloatingActionButton_backgroundTint); mBackgroundTintMode = parseTintMode(a.getInt( R.styleable.FloatingActionButton_backgroundTintMode, -1), null); mRippleColor = a.getColor(R.styleable.FloatingActionButton_rippleColor, 0); mSize = a.getInt(R.styleable.FloatingActionButton_fabSize, SIZE_NORMAL); mBorderWidth = a.getDimensionPixelSize(R.styleable.FloatingActionButton_borderWidth, 0); final float elevation = a.getDimension(R.styleable.FloatingActionButton_elevation, 0f); final float pressedTranslationZ = a.getDimension( R.styleable.FloatingActionButton_pressedTranslationZ, 0f); a.recycle(); ...... final int sdk = Build.VERSION.SDK_INT; if (sdk >= 21) { mImpl = new FloatingActionButtonLollipop(this, delegate); } else if (sdk >= 12) { mImpl = new FloatingActionButtonHoneycombMr1(this, delegate); } else { mImpl = new FloatingActionButtonEclairMr1(this, delegate); } final int maxContentSize = (int) getResources().getDimension( R.dimen.design_fab_content_size); mContentPadding = (getSizeDimension() - maxContentSize) / 2; mImpl.setBackgroundDrawable(background, mBackgroundTint, mBackgroundTintMode, mRippleColor, mBorderWidth); mImpl.setElevation(elevation); mImpl.setPressedTranslationZ(pressedTranslationZ); setClickable(true); }從代碼中不難看出,得到xml設置的屬性,讓FloatingActionButtonImpl實現隨后查看測量方法 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int preferredSize = getSizeDimension(); final int w = resolveAdjustedSize(preferredSize, widthMeasureSpec); final int h = resolveAdjustedSize(preferredSize, heightMeasureSpec); // As we want to stay circular, we set both dimensions to be the // smallest resolved dimension final int d = Math.min(w, h); // We add the shadow's padding to the measured dimension setMeasuredDimension( d + mShadowPadding.left + mShadowPadding.right, d + mShadowPadding.top + mShadowPadding.bottom); }getSizeDimension()得到不同尺寸下的大小 final int getSizeDimension() { switch (mSize) { case SIZE_MINI: return getResources().getDimensionPixelSize(R.dimen.design_fab_size_mini); case SIZE_NORMAL: default: return getResources().getDimensionPixelSize(R.dimen.design_fab_size_normal); } }resolveAdjustedSize()得到父控件測量之后的尺寸 private static int resolveAdjustedSize(int desiredSize, int measureSpec) { int result = desiredSize;//將期望的大小賦值給result int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec);//得到實際的大小 switch (specMode) { case MeasureSpec.UNSPECIFIED://無窮大 result = desiredSize;//當mode為無窮大時,將最終值設置為期望值 break; case MeasureSpec.AT_MOST://不多于實際值 result = Math.min(desiredSize, specSize);//為了保證在內部區域畫圓,得到兩者的最小值 break; case MeasureSpec.EXACTLY://準確值 // No choice. Do what we are told. result = specSize; break; } return result; }上面的方法通過判斷specMode來對result進行賦值
新聞熱點
疑難解答